Тормозит RecyclerView при прокрутке (скроллинге)

484
30 января 2017, 16:56

Я не могу разобраться в чем причина тормозов при прокрутке моего списка. Прокрутка вызывается методом mRecyclerView.smoothScrollToPosition(position); При прокрутке список дергается (время отрисовки фрейма >16ms)

AlphaAdapter.java

public class AlphaAdapter extends RecyclerView.Adapter<AlphaAdapter.ViewHolder> {
    private static final String TAG = "AlphaAdapter";
    private Context mContext;
    private List<PrimaryWeapon> mGunList;
    private boolean isAnimate;
    private final int VIEW_TYPE_NULL        = 0;
    private final int VIEW_TYPE_ITEM        = 1;

    public AlphaAdapter(Context mContext, List<PrimaryWeapon> mGunList) {
        this.mContext = mContext;
        this.mGunList = mGunList;
    }
    public AlphaAdapter(Context mContext, List<PrimaryWeapon> mGunList, boolean a) {
        this.mContext = mContext;
        this.mGunList = mGunList;
        this.isAnimate = a;
    }
    @Override
    public int getItemViewType(int position) {
        try {
            if (mGunList.get(position).getNameWeapon().equals(""))
                return VIEW_TYPE_NULL;
            else return VIEW_TYPE_ITEM;
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("AlphaAdapter", String.valueOf(position));
            return VIEW_TYPE_NULL;
        }
    }
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = null;
        if (viewType == VIEW_TYPE_ITEM)
            view = LayoutInflater.from(mContext).inflate(R.layout.item_game, parent, false);
        else
            view = LayoutInflater.from(mContext).inflate(R.layout.item_null, parent, false);
        return new ViewHolder(view);
    }
    @Override
    public void onViewDetachedFromWindow(ViewHolder holder) {
        super.onViewDetachedFromWindow(holder);
        holder.itemView.clearAnimation();
    }
    @Override
    public boolean onFailedToRecycleView(ViewHolder holder) {
        return true;
    }
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        try {
            long startTime = System.currentTimeMillis();
            if (!getWeapon(position).getNameWeapon().equals("")) {
                if (isAnimate) {
                    if (mLastAnimPosition < position) {
                        mLastAnimPosition = position;
                        Animation a = AnimationUtils.loadAnimation(mContext, R.anim.item_game_anim);
                        holder.itemView.startAnimation(a);
                        a.setAnimationListener(new Animation.AnimationListener() {
                            @Override
                            public void onAnimationStart(Animation animation) {
                            }
                            @Override
                            public void onAnimationEnd(Animation animation) {
                            }
                            @Override
                            public void onAnimationRepeat(Animation animation) {
                            }
                        });
                    }
                }
               Picasso.with(mContext)
                        .load("file:///android_asset/" + getWeapon(position).getImagePath())
                        .placeholder(R.drawable.loading)
                        .error(R.drawable.load_fail)
                        .into(holder.image);
                holder.main.setText(getWeapon(position).getNameWeapon());
                holder.desc.setText(getWeapon(position).getNameSkin());
            }
            Log.i(TAG, String.valueOf(System.currentTimeMillis() - startTime) + "ms onBind (" + String.valueOf(position) + ");");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public long getItemId(int position) {
        return position;
    }
    private PrimaryWeapon getWeapon(int position) {
        return mGunList.get(position);
    }
    @Override
    public int getItemCount() {
        return mGunList.size();
    }
    class ViewHolder extends RecyclerView.ViewHolder {
        TextView main, desc;
        ImageView image;
        ViewHolder(View itemView) {
            super(itemView);
            main = (TextView) itemView.findViewById(R.id.item_textMain);
            desc = (TextView) itemView.findViewById(R.id.item_textDescription);
            image = (ImageView) itemView.findViewById(R.id.item_image);
        }
    }
}

Layout элемента, который участвует в адаптере состоит из LinearLayout, ImageView и двух TextView.

Сначала думал, что проблема в загрузке изображений, пробовал загружать их в AsyncTask, загружать bitmap через Picasso и без, но после вовсе убрал их из разметки, и список все равно лагает.

Сделал дамп ОЗУ после скрола, показывает, что в памяти существует 71 экзепляр ViewHolder, после добавления

@Override
    public boolean onFailedToRecycleView(ViewHolder holder) {
        return true;
    }

это значение уменьшилось до 15-16, хотя норма для RecyclerView - 5 экземпляров, а при прокрутке он должен их переопределять, но не создавать новые.

READ ALSO
Вызов FragmentDialog в RecyclerViewAdapter

Вызов FragmentDialog в RecyclerViewAdapter

Добрый день! Имеется такая ситуация: использую RecyclerView+CardViewНужно при нажатии на карточку открывать DialogFragment

324
Конкатенация это плохой способ?

Конкатенация это плохой способ?

В книге вычитал, что приведение int в String с использованием конкатенации, например, где а это int

310
Панель открытых окон

Панель открытых окон

Скажите пожалуйста, как на java server face реализовать панель открытых окон? Строим учетную программу, нужно открыть несколько окон одновременно...

333
Аутентификация в Spring Security

Аутентификация в Spring Security

Разбираюсь с Spring Security(и параллельно пишу веб приложение)Всё работает, но есть пара вопросов

501