Оптимизация RecyclerView с обложками из альбомов
Есть RecyclerView с информацией об альбомах. При прокрутке есть фризы, из-за подгрузки обложек, которые берутся из mp3. Каким образом я могу оптимизировать его ?
Параметры RecyclerView
myRecyclerView.setItemViewCacheSize(300);
myRecyclerView.setDrawingCacheEnabled(true);
myRecyclerView.setHasFixedSize(true);
onBindViewHolder
@Override
public void onBindViewHolder(@NonNull AlbumViewHolder holder, int position) {
holder.tv_album_title.setText(mAlbumList.get(position).getAlbum());
uri = Uri.parse(mAlbumList.get(position).getData());
retriever.setDataSource(uri.toString());
art = retriever.getEmbeddedPicture();
if (art != null) {
Glide.with(mContext)
.asBitmap()
.load(art)
.format(DecodeFormat.PREFER_RGB_565)
.override(100, 100)
.placeholder(R.drawable.default_cover)
.into(holder.album_cover_albumFragment);
} else {
Glide.with(mContext)
.asBitmap()
.load(R.drawable.default_cover)
.override(100, 100)
.into(holder.album_cover_albumFragment);
}
}
album_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="4dp">
<ImageView
android:id="@+id/album_cover_albumFragment"
android:layout_width="45dp"
android:layout_height="45dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/album_title_albumFragment"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
android:textColor="@color/white"
android:textSize="16sp" />
</LinearLayout>
Ответы (1 шт):
Нашел на ютубе решение https://youtu.be/J55pR7EvVUQ. Всё хорошо работает, но пришлось доработать, так как у меня при нажатии открывается другая activity.
Перестал работать interface, который отвечал за слушателя в RecyclerView, переделал таким образом:
Класс слушателя
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
public void onLongItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && mListener != null) {
mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child));
}
}
});
}
@Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
return true;
}
return false;
}
@Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }
@Override
public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
}
Объявляем слушателя
myRecyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(getActivity(), myRecyclerView, new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
//Do what you need after click
}
@Override
public void onLongItemClick(View view, int position) {
//Do what you need after long click
}
})
);
При возврате к RecyclerView приложение вылетало, фиксил так https://stackoverflow.com/a/33822747/17839298 :
public class WrapContentLinearLayoutManager extends LinearLayoutManager {
public WrapContentLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
try {
super.onLayoutChildren(recycler, state);
} catch (IndexOutOfBoundsException e) {
}
}
}
Потом применяем к RecyclerView
myRecyclerView.setLayoutManager(new WrapContentLinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
Дальше заметил, что моргает первый элемент RecyclerView, на секунду подгружалась другая обложка, помог данный код:
myRecyclerView.swapAdapter(albumsAdapter, false);