У меня проблемы с оптимизацией моего RecyclerView. Когда я запускаю приложение в холодном режиме, первая прокрутка всегда дергается.
Я следил за этим , но это не помогло, так как я не уверен, что вызывает отставание.
Вот содержимое моего RecyclerView (list_item.xml):
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="86dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp">
<android.support.constraint.ConstraintLayout
android:id="@+id/list_item_constraint_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/selectableItemBackground">
<TextView
android:id="@+id/list_item_akcija_ime"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:ellipsize="marquee"
android:fontFamily="sans-serif"
android:singleLine="true"
android:text="@string/ime_akcije"
android:textColor="@color/common_google_signin_btn_text_dark_focused"
android:textSize="18sp"
app:layout_constraintEnd_toStartOf="@+id/list_item_eye"
app:layout_constraintStart_toEndOf="@+id/list_item_slika"
app:layout_constraintTop_toTopOf="@+id/list_item_slika" />
<TextView
android:id="@+id/list_item_akcija_datum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:text="@string/_1_7_2019"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="@+id/list_item_akcija_ime"
app:layout_constraintTop_toBottomOf="@+id/list_item_akcija_ime" />
<ImageView
android:id="@+id/list_item_slika"
android:layout_width="110dp"
android:layout_height="70dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:adjustViewBounds="true"
android:contentDescription="@string/slika_akcije"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/list_item_starosti_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="@+id/list_item_slika"
app:layout_constraintStart_toStartOf="@+id/list_item_akcija_ime" />
<ImageView
android:id="@+id/list_item_fire"
android:layout_width="21dp"
android:layout_height="22dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:contentDescription="@string/fire"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/list_item_fires"
app:layout_constraintTop_toBottomOf="@+id/list_item_eye"
app:srcCompat="@drawable/campfire" />
<ImageView
android:id="@+id/list_item_eye"
android:layout_width="21dp"
android:layout_height="22dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:contentDescription="@string/eye"
app:layout_constraintBottom_toTopOf="@+id/list_item_fire"
app:layout_constraintEnd_toStartOf="@+id/list_item_clicks"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
app:srcCompat="@drawable/eye" />
<TextView
android:id="@+id/list_item_clicks"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/list_item_eye"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/list_item_eye"
tools:text="159" />
<TextView
android:id="@+id/list_item_fires"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="60"
android:textColor="@color/colorAccent"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/list_item_fire"
app:layout_constraintStart_toStartOf="@+id/list_item_clicks"
app:layout_constraintTop_toBottomOf="@+id/list_item_eye" />
</android.support.constraint.ConstraintLayout>
Это то, что я делаю в onBindViewHolder
@Override
public void onBindViewHolder(@NonNull AkcijaViewHolder akcija, int i) {
akcija.bindData(akcije.get(i), mOnItemClickListener, context);
}
Мой метод bindData довольно дорогой, но если я прав, это не должно повлиять на производительность?
public void bindData(final Akcija akcija, final AkcijaAdapter.OnItemClickListener onItemClickListener, Context context) {
/* Set Akcija's ime to the TextView */
imeTextView.setText(akcija.getIme());
imeTextView.setSelected(true);
/* Set date and show it */
Date date = new Date(akcija.getDatum() * 1000);
DateFormat dateFormat = new SimpleDateFormat("d. M. yyyy", Locale.getDefault()); // Format for 13. 4. 2019
String strDate = dateFormat.format(date);
datumTextView.setText(strDate);
/* Set clicks */
klikTextView.setText(String.valueOf(akcija.getClicks()));
/* Draw starosti circle_mc images */
String starosti = akcija.getStarost(); // get starosti...
String[] starostiArr = starosti.split(" "); // and split them into strings
linearLayout.removeAllViews();
for (String starost : starostiArr) { // loop through all starosti. For each starost draw it by calling drawStarostSlika and pass in the drawable of circle
switch (starost) {
case "M":
drawStarostSlika(R.drawable.circle_mu);
break;
case "MČ":
drawStarostSlika(R.drawable.circle_mc);
break;
case "GG":
drawStarostSlika(R.drawable.circle_gg);
break;
case "PP":
drawStarostSlika(R.drawable.circle_pp);
break;
case "RR":
drawStarostSlika(R.drawable.circle_rr);
break;
case "G":
drawStarostSlika(R.drawable.circle_gr);
break;
default:
break;
}
}
/* Load image into slikaImageView from Firebase Storage */
GlideApp.with(context)
.load(storageReference.child(akcija.getIme() + ".jpg"))
.thumbnail(0.5f)
.transition(DrawableTransitionOptions.withCrossFade())
.diskCacheStrategy(DiskCacheStrategy.DATA)
.into(slikaImageView);
/* Make each item clickable. On click, run the method passed in to adapter from anywhere. */
listItemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onItemClickListener.onItemClick(akcija, v);
}
});
}
Так я заполняю RecyclerView
private DatabaseReference mDatabaseReference = FirebaseDatabase.getInstance().getReference().child("akcije");
private StorageReference storageReference = FirebaseStorage.getInstance().getReference();
List<Akcija> akcije = new ArrayList<>();
AkcijaAdapter adapter;
RecyclerView recyclerView;
Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = MainActivity.this;
mDatabaseReference.addValueEventListener(valueEventListener); // set listener for the method defined below
adapter = new AkcijaAdapter(context, akcije, onItemClickListener); // for now, add empty akcija's so the list is not skipped
recyclerView = findViewById(R.id.list);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
}
/* When Firebase's databases changes update the recycler view */
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
akcije.add(new Akcija(
ds.getKey(), // the key is the same as Akcija's name
ds.child("datum").getValue(Long.class), // milliseconds since 1970
ds.child("starost").getValue().toString(),
ds.child("link").getValue().toString(),
ds.child("klik").getValue(Integer.class)
));
}
/* Sort akcija's by date */
Collections.sort(akcije, new Comparator<Akcija>() {
@Override
public int compare(Akcija o1, Akcija o2) {
return o2.getDatum().compareTo(o1.getDatum());
}
});
adapter = new AkcijaAdapter(context, akcije, onItemClickListener); // update the list and
recyclerView.setAdapter(adapter); // set the adapter
mDatabaseReference.removeEventListener(this); // only update the app when it's ran
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
};
AkcijaAdapter.OnItemClickListener onItemClickListener = new AkcijaAdapter.OnItemClickListener() {
@Override
public void onItemClick(Akcija akcija, View listItemView) {
// do stuff here
}
};
}
Я также думал, что использование ConstraintLayout было оптимальным, но я не знаю, слишком ли дорог мой list_item?