Лагает при скролле RecyclerView

350
12 мая 2017, 14:56

Вообщем проблема такая, есть TabLayout и ViewPager, всего вкладок у меня 5, на первых двух вкладках идет RecyclerView с данными, а на 3 избранные, по началу там пустой адаптер.

Так вот, заполняю RecyclerView на первых двух фрагментах, и при скролле видно что лагает, просто я сравниваю с другим RecyclerView который не в фрагменте, а в AppCompatActivity там все идеально крутится, хотя там элементов больше и в адаптере условий больше, туда пользователь попадает нажав в первой или во второй вкладке на любой item. В первой вкладке у меня элементов где-то 100-150, во второй 30.

Из за чего может лагать скролл в RecyclerView, перепробывал все методы, даже ставил вместо RecyclerView, ListView, такая же байда. Думаю это связано с TabLayout и ViewPager ибо не в фрагменте так не лагает, сталкивались ли вы с такой проблемой? Подскажите в чем проблема?

public class myAdapter extends RecyclerView.Adapter<myAdapter.ViewHolder> implements Filterable {
private Context ctx;
private List<myItem> objects = new ArrayList<>();
private List<myItem> originalObjects = new ArrayList<>();
private List<myItem> tempObjects = new ArrayList<>();
private SharedPreferences sp;
private SharedPreferences.Editor editor;
private String from;
public myAdapter(Context ctx, List<myItem> objects, String from){
    this.ctx = ctx;
    this.objects = objects;
    this.originalObjects = objects;
    this.from = from;
    sp = PreferenceManager.getDefaultSharedPreferences(ctx);
    editor = sp.edit();
}
static class ViewHolder extends RecyclerView.ViewHolder {
    TextView tvNumber1;
    TextView tvText1;
    TextView tvText2;
    TextView tvText3;
    TextView tvNumber2;
    TextView tvPlace;
    CheckBox cbFav;
    ViewHolder(View v) {
        super(v);
        tvNumber1 = (TextView) v.findViewById(R.id.tvNumber1);
        tvText1 = (TextView) v.findViewById(R.id.tvText1);
        tvText2 = (TextView) v.findViewById(R.id.tvText2);
        tvText3 = (TextView) v.findViewById(R.id.tvText3);
        tvNumber2 = (TextView) v.findViewById(R.id.tvNumber2);
        tvPlace = (TextView) v.findViewById(R.id.tvPlace);
        cbFav = (CheckBox) v.findViewById(R.id.cbFav);
    }
}
@Override
public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler_view, parent, false);
    v.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            myItem item = (myItem) v.getTag();
            Intent intent = new Intent(parent.getContext(), two_activity.class);
            intent.putExtra("id", item.getId());
            parent.getContext().startActivity(intent);
        }
    });
    return new ViewHolder(v);
}
public myItem getItem(int position){
    return objects.get(position);
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
    holder.tvNumber1.setText(String.valueOf(objects.get(position).getId()));
    holder.tvPlace.setText(objects.get(position).getPlace());
    holder.tvNumber2.setText(String.valueOf(objects.get(position).getNumber2()));
    holder.tvNumber1.setTypeface(Typeface.createFromAsset(ctx.getAssets(), sp.getString(Config.SP_FONT_NUMBER_1, Config.FONT_GOTHICB)));
    holder.tvNumber1.setTextColor(sp.getInt(Config.SP_COLOR_NUMBER_1, 0xffff0000));
    holder.tvNumber1.setTextSize(sp.getInt(Config.SP_SIZE_NUMBER_1, 22));
    holder.tvPlace.setTypeface(Typeface.createFromAsset(ctx.getAssets(), Config.FONT_GOTHIC));
    holder.tvNumber2.setTypeface(Typeface.createFromAsset(ctx.getAssets(), Config.FONT_GOTHIC));
    if (sp.getBoolean(Config.SP_SHOW_TEXT_1, true)){
        holder.tvText1.setVisibility(View.VISIBLE);
        holder.tvText1.setText(objects.get(position).getText1());
        holder.tvText1.setTextSize(sp.getInt(Config.SP_SIZE_TEXT_1, 22));
        holder.tvText1.setTypeface(Typeface.createFromAsset(ctx.getAssets(), sp.getString(Config.SP_FONT_TEXT_1, Config.FONT_1)));
        holder.tvText1.setTextColor(sp.getInt(Config.SP_COLOR_TEXT_1, 0xff000000));
    } else {
        holder.tvText1.setVisibility(View.GONE);
    }
    if (sp.getBoolean(Config.SP_SHOW_TEXT_2, true)){
        holder.tvText2.setVisibility(View.VISIBLE);
        holder.tvText2.setText(objects.get(position).getText2());
        holder.tvText2.setTextSize(sp.getInt(Config.SP_SIZE_TEXT_2, 18));
        holder.tvText2.setTypeface(Typeface.createFromAsset(ctx.getAssets(), sp.getString(Config.SP_FONT_TEXT_2, Config.FONT_GOTHICB)));
        holder.tvText2.setTextColor(sp.getInt(Config.SP_COLOR_TEXT_2, 0xff000000));
    } else {
        holder.tvText2.setVisibility(View.GONE);
    }
    if (sp.getBoolean(Config.SP_SHOW_TEXT_3, true)){
        holder.tvText3.setVisibility(View.VISIBLE);
        holder.tvText3.setText(objects.get(position).getText3());
        holder.tvText3.setTextSize(sp.getInt(Config.SP_SIZE_TEXT_3, 18));
        holder.tvText3.setTypeface(Typeface.createFromAsset(ctx.getAssets(), sp.getString(Config.SP_FONT_TEXT_3, Config.FONT_GOTHIC)));
        holder.tvText3.setTextColor(sp.getInt(Config.SP_COLOR_TEXT_3, 0xff000000));
    } else {
        holder.tvText3.setVisibility(View.GONE);
    }
    holder.cbFav.setChecked(isFav(objects.get(position)));
    holder.cbFav.setTag(objects.get(position));
    holder.cbFav.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            myItem item = (myItem) view.getTag();
            setFav(ctx, item);
            if(from.equals("FAV")){
                objects.remove(item);
                notifyDataSetChanged();
            }
        }
    });
    holder.itemView.setTag(objects.get(position));
}
private boolean isFav(myItem item){
    boolean isFav = false;
    Gson gson = new Gson();
    String json = sp.getString(Config.SP_FAV, null);
    Type type = new TypeToken<ArrayList<myItem>>() {}.getType();
    ArrayList<myItem> arrayList;
    if (json == null) {
        arrayList = new ArrayList<>();
    } else {
        arrayList = gson.fromJson(json, type);
    }
    if (arrayList.size() != 0) {
        for (int i = 0; i < arrayList.size(); i++) {
            if (arrayList.get(i).getId() == item.getId()) {
                isFav = true;
            }
        }
    }
    return isFav;
}
private void setFav(Context ctx, myItem item){
    boolean isFav = false;
    Gson gson = new Gson();
    String json = sp.getString(Config.SP_FAV, null);
    Type type = new TypeToken<ArrayList<myItem>>() {}.getType();
    ArrayList<myItem> arrayList;
    if (json == null) {
        arrayList = new ArrayList<>();
    } else {
        arrayList = gson.fromJson(json, type);
    }
    if (arrayList.size() != 0) {
        for (int i = 0; i < arrayList.size(); i++) {
            if (arrayList.get(i).getId() == item.getId()) {
                isFav = true;
                arrayList.remove(i);
            }
        }
    }
    if (!isFav){
        arrayList.add(item);
        Toast.makeText(ctx, R.string.added_to_favorites, Toast.LENGTH_SHORT).show();
    } else {
        Toast.makeText(ctx, R.string.removed_from_favorites, Toast.LENGTH_SHORT).show();
    }
    String toJson = gson.toJson(arrayList);
    editor.putString(Config.SP_FAV, toJson).apply();
}
@Override
public int getItemCount() {
    return objects.size();
}
@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            tempObjects = new ArrayList<>();
            if(constraint == null || constraint.length() == 0 ){
                tempObjects = new ArrayList<>(originalObjects);
            } else {
                constraint = constraint.toString().toLowerCase();
                for (int i=0; i < originalObjects.size(); i++){
                    String text1 = originalObjects.get(i).getText1.toLowerCase();
                    String text2 = originalObjects.get(i).getText2.toLowerCase();
                    String text3 = originalObjects.get(i).getText3.toLowerCase();
                    if(text1.contains(constraint)){
                        tempObjects.add(originalObjects.get(i));
                    } else if (text2.contains(constraint)) {
                        tempObjects.add(originalObjects.get(i));
                    } else if (text3.contains(constraint)){
                        tempObjects.add(originalObjects.get(i));
                    }
                }
            }
            objects = new ArrayList<>(tempObjects);
            return null;
        }
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            notifyDataSetChanged();
        }
    };
}

}

Answer 1

Проблема в некэшированном шрифте. Каждый раз, для каждого элемента шрифт подгружается из Assets заново.

Попробуйте класс для кэша шрифта:

public class TypeFaces {
//---Кэширование шрифта---
private static final Hashtable<String, Typeface> cache = new Hashtable<String, Typeface>();
public static Typeface get(Context c, String name) {
    synchronized (cache) {
        if (!cache.containsKey(name)) {
            String path =  name;
            try {
                Typeface t = Typeface.createFromAsset(c.getAssets(), path);
                cache.put(name, t);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return cache.get(name);
    }
}
}

Использование: textview.setTypeface(Typefaces.get(Контекст, имя шрифта)) можно имя по умолчанию задать в самом классе.

READ ALSO
GMP4J на андроиде с помощью ndk

GMP4J на андроиде с помощью ndk

Нашел проект который создает подобие javamath

200
Будильник Android

Будильник Android

Делаю что-то вроде будильника, как можно указать сразу два будильника? Просто если использовать этот же код и изменять время, то будильник...

279