【问题标题】:Recycle View scrolls slow . How to fix it?Recyclerview 滚动缓慢。如何解决?
【发布时间】:2017-08-21 06:52:24
【问题描述】:

我刚刚在回收视图中实现了可扩展布局。ExpandableLayout library

问题:第一次回收视图滚动很慢。展开/折叠效果很好,但列表滚动很慢

注意: 它在4 GB RAM 设备上运行顺畅,但在2 GB RAM 设备上滚动缓慢。我用 Moto g3 (2 GB RAM) 和 Moto 进行了测试 g5 Plus(4 GB RAM)

来自网络服务并通过适配器传递数组列表的数据。

嵌套线性布局中的布局行文件 (XML)。(可能是它的视图组加载,但我也尝试使用约束布局。仍然循环视图加载滞后)

我在展开和折叠项目视图期间替换视图(我已经评论了该代码。但我的回收视图仍然很慢) 在 itemview 中没有使用任何图像存储。 已经尝试过setHasFixedSizenotifyDataChangedsetCacheadapter.setHasStableIds(true);

但仍仅在第一次时 recycleview 加载滞后。

帮我解决这个问题。我还在找问题! 您可以查看我的适配器代码!

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

public LayoutInflater mInflater;
public HashSet<Integer> mExpandedPositionSet = new HashSet<>();
Context context;
ArrayList<CustomerDetails> list;
CustomerDetails details;


public PendingOrdersAdapter(Context context, ArrayList<CustomerDetails> list) {
this.context = context;
this.list = list;
this.mInflater = LayoutInflater.from(context);
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View item = mInflater.inflate(R.layout.pending_order_item, parent, false);
return new ViewHolder(item);
}


@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
 details = list.get(position);

holder.updateItem(position, holder);
holder.tvOrderNo.setText("" + details.getOrderID());
holder.tvCustomerName.setText("" + details.getCustomerName());
holder.tvTotalPrice.setText("" + details.getTotalPrice());
holder.tvCustomerContactNo.setText("" + details.getPrimaryContactNo());
holder.tvProductWeight.setText("" + details.getProductWeight());
holder.tvCustomerStatus.setText("" + details.getCustomerStatus());
holder.tvDeliveryManStatus.setText("" + details.getDeliveryManStatus());
holder.tvAddress.setText("" + details.getAddress());
holder.tvDeliveryMan.setText("" + details.getCustomerName() + " ( " + details.getPrimaryContactNo() + " ) ");
holder.tvTime.setText("" + details.getTime());
holder.tvPickUpDate.setText("" + details.getPickupDate());

holder.tvDeliveryCharge.setText("" + details.getDeliveryCharge());


//Opening DialogFragment on Click Listner

  holder.tvDeliveryMan.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        AppCompatActivity activity = (AppCompatActivity) (context);

        android.app.FragmentTransaction ft = activity.getFragmentManager().beginTransaction();
        android.app.Fragment prev = activity.getFragmentManager().findFragmentByTag("dvdialog");

        if (prev != null) {
            ft.remove(prev);
        }
        ft.addToBackStack(null);

        DeliveryManDetailsDialog newFragment = new DeliveryManDetailsDialog();
        newFragment.show(ft, "dvdialog");

    }
});

holder.tvAddress.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {

        final int DRAWABLE_RIGHT = 2;


        //Address icon click listner right side

        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (event.getRawX() >= (holder.tvAddress.getRight() - holder.tvAddress.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {

                // your action here
                Intent intent = new Intent(context, RouteActivity.class);
                intent.putExtra("custLat", details.getCustLatitude());
                intent.putExtra("custLong", details.getCustLongitude());
                intent.putExtra("boLat", details.getBoLatitude());
                intent.putExtra("boLong", details.getBosLongitude());

                context.startActivity(intent);


            }


            return true;

        }
        return true;
    }
});


}

@Override
public int getItemViewType(int position) {
return position;
}

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

public void registerExpand(int position, ViewHolder holder) {

if (mExpandedPositionSet.contains(position)) {

    //Replacing views at runtime and arrow animation

    ViewGroupUtils.replaceView(holder.timeLayout, holder.statusLayout);


holder.orderbox.setBackgroundResource(R.drawable.box_fill_drawable);
    holder.ivArrow.animate().rotation(360).start();
    removeExpand(position);




} else {
    ViewGroupUtils.replaceView(holder.statusLayout, holder.timeLayout);

    holder.orderbox.setBackgroundResource(R.drawable.box_fill_drawable_top);
    holder.ivArrow.animate().rotation(180).start();
    addExpand(position);


}
}

public void removeExpand(int position) {


mExpandedPositionSet.remove(position);


}

public void addExpand(int position) {


mExpandedPositionSet.add(position);

}

public class ViewHolder extends RecyclerView.ViewHolder {
public ExpandableLayout expandableLayout;
public LinearLayout orderbox, orderbox_bottom;
public ImageView ivArrow;
public TextView tvAddress, tvOrderNo, tvCustomerName, tvTotalPrice, tvCustomerContactNo;
public TextView tvProductWeight, tvCustomerStatus, tvDeliveryManStatus;
public TextView tvDeliveryCharge, tvDeliveryMan, tvTime;
public TextView tvPickUpDate;
public LinearLayout statusLayout, statusParentLayout, timeLayout, timeParentLayout, addressLayout;


public ViewHolder(final View itemView) {
    super(itemView);
    expandableLayout = (ExpandableLayout) 
itemView.findViewById(R.id.expandable_layout);
    orderbox = (LinearLayout) itemView.findViewById(R.id.orderbox);

    orderbox_bottom = (LinearLayout) 
itemView.findViewById(R.id.orderbox_bottom);
    ivArrow = (ImageView) itemView.findViewById(R.id.ivArrow);

    tvOrderNo = (TextView) itemView.findViewById(R.id.tvOrderNo);
    tvCustomerName = (TextView) 
itemView.findViewById(R.id.tvCustomerName);
    tvTotalPrice = (TextView) 
itemView.findViewById(R.id.tvTotalPrice);
    tvCustomerContactNo = (TextView) 
itemView.findViewById(R.id.tvCustomerContactNo);
    tvProductWeight = (TextView) 
itemView.findViewById(R.id.tvProductWeight);
    tvCustomerStatus = (TextView) 
itemView.findViewById(R.id.tvCustomerStatus);
    tvDeliveryManStatus = (TextView) 
itemView.findViewById(R.id.tvDeliveryManStatus);
    tvDeliveryCharge = (TextView) 
itemView.findViewById(R.id.tvDeliveryCharge);
    tvAddress = (TextView) itemView.findViewById(R.id.tvAddress);
    tvDeliveryMan = (TextView) 
itemView.findViewById(R.id.tvDeliveryMan);
    tvTime = (TextView) itemView.findViewById(R.id.tvTime);
    tvPickUpDate = (TextView) 
itemView.findViewById(R.id.tvPickUpDate);

    statusParentLayout = (LinearLayout) 
itemView.findViewById(R.id.statusParentLayout);
    statusLayout = (LinearLayout) 
itemView.findViewById(R.id.statusLayout);
    timeParentLayout = (LinearLayout) 
itemView.findViewById(R.id.timeParentLayout);
    timeLayout = (LinearLayout) 
itemView.findViewById(R.id.timeDateLayout);
    addressLayout = (LinearLayout) 
itemView.findViewById(R.id.addressLayout);
}

public void updateItem(final int position, final ViewHolder holder) {
    holder.orderbox.setBackgroundResource(R.drawable.box_fill_drawable_top);
    holder.expandableLayout.setOnExpandListener(new ExpandableLayout.OnExpandListener() {
        @Override
        public void onExpand(boolean expanded) {

            registerExpand(position, holder);

        }
    });

    expandableLayout.setExpand(mExpandedPositionSet.contains(position));

}
}

从片段调用适配器

**  PendingOrdersAdapter adapter = new PendingOrdersAdapter(getActivity(), detailsArrayList);

    recyclerview.setLayoutManager(new LinearLayoutManager(getActivity()));
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.setHasFixedSize(true);
    recyclerView.setItemViewCacheSize(20);
    recyclerView.setDrawingCacheEnabled(true);

recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
    recyclerview.setAdapter(adapter);
    adapter.notifyDataSetChanged();**

【问题讨论】:

  • 您从 Web 服务中获得了多少条记录?
  • 18 个 JSON 对象(可以更多)。每个对象有 43 个值

标签: android android-recyclerview


【解决方案1】:

创建一个类,例如Util,并将该方法添加到该类中并使用它。

 public static void setDivider(Context context, RecyclerView recyclerView, RecyclerView.LayoutManager layoutManager) {
            recyclerView.setLayoutManager(layoutManager);
            recyclerView.setItemAnimator(new DefaultItemAnimator());
            recyclerView.setHasFixedSize(true);
            recyclerView.setItemViewCacheSize(20);
            recyclerView.setDrawingCacheEnabled(true);
            recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
            DividerItemDecoration horizontalDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
            Drawable horizontalDivider = ContextCompat.getDrawable(context, R.drawable.horizontal_divider);
            horizontalDecoration.setDrawable(horizontalDivider);
            recyclerView.addItemDecoration(horizontalDecoration);
        }

这里第一个参数是context,第二个传递你的recyclerview,第三个传递布局管理器。 如果你有更多的东西然后改变CacheSize

【讨论】:

  • 它们有分隔物品装饰的效果吗?
  • DividerItemDecoration 用于在 recyclerview 的每个单元格之后给出简单的行
  • 上述解决方案仅在您参考回收站视图的所有最佳实践时才有效,例如 CustomerDetails cd = list.get(position);然后在用户 cd.getOrderId() 之后
  • 更多信息可以参考这个链接guides.codepath.com/android/using-the-recyclerview
  • @HarshBhavsar 上面的答案是有效的,因为您的缓存临时基础是为滚动效率而存储的。
【解决方案2】:

使用这个 recyclerView.setNestedScrollingEnabled(false);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多