无条件布局膨胀:应使用View Holder模式

时间:2018-02-03 19:00:18

标签: java android android-studio

我是新手,我试图给项目行充气,但在滚动时会减慢应用程序的速度。在下面的代码中,它说我需要使用View Holder。

        row = inflater.inflate(mLayoutResourceId, parent, false);

我该如何解决这个问题?

package com.example.android.ontrack.adapters;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import com.example.android.ontrack.R;
import com.example.android.ontrack.models.Order;

public class OrdersList extends ArrayAdapter<Order> {

    Context mContext;
    int mLayoutResourceId;
    Order mData[] = null;

    public OrdersList(Context context, int resource, Order[] data) {
        super(context, resource, data);
        this.mContext = context;
        this.mLayoutResourceId = resource;
        this.mData = data;
    }


    @Override
    public Order getItem(int position) {
        return super.getItem(position);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row;

        LayoutInflater inflater = LayoutInflater.from(mContext);
        row = inflater.inflate(mLayoutResourceId, parent, false);

            TextView nameOfSchool = row.findViewById(R.id.school_name_orders);
        TextView nameOfAgent = row.findViewById(R.id.agent_name);
        TextView orderId = row.findViewById(R.id.order_id);
        TextView netRevenue = row.findViewById(R.id.net_revenue);
        TextView orderQuantity = row.findViewById(R.id.total_quantity);
        TextView date = row.findViewById(R.id.date);

        Order orders = mData[position];

        nameOfSchool.setText(orders.nameOfSchool);
        nameOfAgent.setText(String.valueOf(orders.nameOfAgent));
        orderId.setText(String.valueOf(orders.orderId));
        netRevenue.setText(String.valueOf(orders.netRevenue));
        orderQuantity.setText(String.valueOf(orders.totalQuantity));
        date.setText(String.valueOf(orders.date));

        return row;
    }
}

2 个答案:

答案 0 :(得分:4)

你的问题出现在这段代码中:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row;

    LayoutInflater inflater = LayoutInflater.from(mContext);
    row = inflater.inflate(mLayoutResourceId, parent, false);

    ...
    return row;
}

警告信息表明,无论系统将哪些内容传递给getView(),您都始终致电inflater.inflate()以生成row

要理解的第一件事是传递给convertView的{​​{1}}参数有时是空的,有时不是。 当它不为空时,它是一个&#34; old&#34; (&#34;再循环&#34;)以前从getView()返回的视图。换句话说,它与您自己充气的视图完全相同的类型,它只包含旧数据。

因此,您可以通过将上述代码更改为此来解决此问题:

getView()

要理解的第二件事是@Override public View getView(int position, View convertView, ViewGroup parent) { View row; if (convertView == null) { LayoutInflater inflater = LayoutInflater.from(mContext); row = inflater.inflate(mLayoutResourceId, parent, false); } else { row = convertView; } ... return row; } 很慢。不像多秒慢,但足够慢,如果你必须运行数百次,它将导致你的UI滞后。所以&#34;视图持有者模式&#34;是一种避免每次都查看这些视图的方法。

您要做的第一件事是创建一个类,其中包含行中每个视图的字段。鉴于你发布的内容,看起来像这样:

findViewById()

现在您必须将其插入private static class ViewHolder { private final TextView nameOfSchool; private final TextView nameOfAgent; private final TextView orderId; private final TextView netRevenue; private final TextView orderQuantity; private final TextView date; private ViewHolder(View row) { nameOfSchool = row.findViewById(R.id.school_name_orders); nameOfAgent = row.findViewById(R.id.agent_name); orderId = row.findViewById(R.id.order_id); netRevenue = row.findViewById(R.id.net_revenue); orderQuantity = row.findViewById(R.id.total_quantity); date = row.findViewById(R.id.date); } } 代码。每次展开视图时(例如getView()为空时),您都需要创建新的ViewHolder,否则您将要重新使用现有的convertView。我们使用视图标记。

总之,它看起来像这样:

ViewHolder

答案 1 :(得分:1)

由于层次结构计算和其他一些事情,布局通胀可能非常耗时,这就是为什么android引入了 RECYCLING 视图的平台。

您可以创建一次视图,当它不再使用时,它可以被回收。所以它只需要将数据绑定到视图。

视图持有者是视图的包装器,它是持有ref的视图。要重新使用的视图。您可以在RecyclerView上查看这些单页教程,这是ListView

的更灵活高效的版本

https://developer.android.com/training/material/lists-cards.html