添加新视图时,RecyclerView会断断续续

时间:2016-08-23 10:00:45

标签: android android-recyclerview

我有一个回收站视图,它是从API动态填充的。回收者视图项包含一个图像视图,文本层叠在其顶部,图像视图的图像来自API,并使用毕加索加载。滚动recyclerview时,我发现当底部添加一个新视图时,滚动中会有轻微的卡顿。我还发现滚动越多,滚动越慢,反应越慢。我已经尝试使用它与毕加索代码注释掉并得到相同的结果。

这是我对recyclerview的适配器:

public class EventListAdapter extends RecyclerView.Adapter<EventListAdapter.ViewHolder> {

Context context;
public ArrayList<EventObject> eventList;
private LayoutInflater mInflater;
private String category;

public static class ViewHolder extends RecyclerView.ViewHolder {
    private ImageView img_main;
    private RelativeLayout layoutItem;
    private TextView txt_event_name;
    private TextView txt_event_details;
    private TextView txt_going_to;

    public ViewHolder(View itemView) {
        super(itemView);
        img_main = (ImageView) itemView.findViewById(R.id.img_main);
        txt_event_details = (TextView) itemView.findViewById(R.id.txt_event_details);
        txt_event_name = (TextView) itemView.findViewById(R.id.txt_event_name);
        txt_going_to = (TextView) itemView.findViewById(R.id.txt_going_to);
        gradient_view = itemView.findViewById(R.id.gradient_view);
        layoutItem = (RelativeLayout) itemView.findViewById(R.id.rl_event_item);
    }

    public void bindView(final Context context, final EventObject eventObject, String category) throws JSONException, ParseException {
        txt_event_name.setTypeface(FontClass.getOpenSansRegular(context));
        txt_event_details.setTypeface(FontClass.getOpenSansLight(context));
        txt_going_to.setTypeface(FontClass.getOpenSansLight(context));

        txt_event_name.setText(eventObject.getEventName());

        if (eventObject.getVenueName().contains(eventObject.getTown())) {
            txt_event_details.setText(eventObject.getVenueName() + ", " + getFormattedDate(eventObject.getEventDate()));
        } else {
            txt_event_details.setText(eventObject.getVenueName() + ", " + eventObject.getTown() + ", " + getFormattedDate(eventObject.getEventDate()));
        }

        if(eventObject.getFeeFreeStatus() == 1){
            if(category.equalsIgnoreCase("no fees")) {
                txt_going_to.setVisibility(View.GONE);
            } else {
                txt_going_to.setVisibility(View.VISIBLE);
                txt_going_to.setText("Fee free tickets available");
            }

        } else if (Integer.parseInt(eventObject.getGoingToCount()) >= 200) {
            txt_going_to.setVisibility(View.VISIBLE);
            txt_going_to.setText("Popular event: " + eventObject.getGoingToCount() + " going");
        } else {
            txt_going_to.setVisibility(View.GONE);
        }


        layoutItem.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ((HomeActivity) context).setEventProfileFrag(eventObject.getFullJsonObject(), null);
            }
        });

        Picasso.with(context)
                .load(eventObject.getImageUrl())
                .placeholder(R.drawable.holder_image)
                .into(img_main);

    }

    private String getFormattedDate(String dateString) throws ParseException {

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.UK);
        Date newDate = format.parse(dateString);

        format = new SimpleDateFormat("EEEE dd MMMM", Locale.UK);
        String date = format.format(newDate);

        return date;
    }

}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_event_list_item, parent, false);
    return new ViewHolder(itemView);
}

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {

    try {
        holder.bindView(context, eventList.get(position), this.category);
    } catch (JSONException e) {
        e.printStackTrace();
    } catch (ParseException e) {
        e.printStackTrace();
    }
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public int getItemCount() {
    return eventList.size();
}


public EventListAdapter(Context context, ArrayList<EventObject> eventList, String category) {
    this.context = context;
    this.eventList = eventList;
    this.category = category;
    mInflater = LayoutInflater.from(context);
    setHasStableIds(true);
}

public void addItems(ArrayList<EventObject> eventList) {
    this.eventList.addAll(eventList);
    notifyDataSetChanged();
}
}

1 个答案:

答案 0 :(得分:2)

您可能会遇到口吃的原因:

  1. 您(可能)反序列化适配器内的数据。你不应该,反序列化可能是昂贵的过程。摆脱onBindViewHolder中的去除,发送反序列化的模型对象。
  2. 
    try {
            holder.bindView(context, eventList.get(position), this.category);
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } 
    1. 请勿强制RecyclerView.Adapter在不需要时尝试重绘所有项目。改进此并使用notifyItemXXXX()notifyItemRangeXXX()方法:
    2. 
      public void addItems(ArrayList eventList) {
          this.eventList.addAll(eventList);
          notifyDataSetChanged();
      }
      
      1. 在您对数据进行消毒时(但不在onBindViewHolder()内部进行消毒),解析日期和基元

      2. 尝试以不同方式设置字体,例如在xml中提供字体。缓存字体。

      3. .contains()对于长字符串来说可能会很慢