如何实现ListView项的OnClickListener以获得良好的性能(避免慢速滚动)

时间:2014-02-19 10:54:42

标签: android-listview

我一直在阅读ViewHolder Pattern及其对ListView滚动效果的影响。

为了实现平滑滚动,快速ListView应该避免在 adapter OnClickListener方法中使用 getView()注册,例如:< / p>

@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
    ViewHolder holder;
    if (convertView == null) 
    {
        holder = new ViewHolder();

        LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = vi.inflate(mResourceId, null);

        holder.btn1 = (TextView) convertView.findViewById(R.id.btn1);
        holder.img1 = (TextView) convertView.findViewById(R.id.img1);

        convertView.setTag(holder);
    } else { holder = (ViewHolder) convertView.getTag(); }

    final Items item = getItem(position);

    holder.btn1.setText(item.btnText);
    holder.img1.setBackgroundResource(item.imgSource);

    holder.img1.setOnClickListener(new OnClickListener() {          
        @Override 
        public void onClick(View v) { /* .. my code block USING POSITION ARG .. */ }
    }

    holder.btn1.setOnClickListener(new OnClickListener() {          
        @Override 
        public void onClick(View v) { /* .. My Code Block USING POSITION ARG .. */ }
    }

    return convertView;
}

如果是,请注册OnItemClickListenerListView个实例,因为以下示例做了一个很好的做法:

myListView.setOnItemClickListener(new OnItemClickListener() 
{
    @Override 
    public void onItemClick(AdapterView<?> arg0, View view, int position, long id) {
        if (view.getId() == R.id.btn1)
        {
            // my code block USING POSITION ARG     
        }
        else if (view.getId() == R.id.img1)
        {
            // my code block USING POSITION ARG                         
        }                   
    }           
});

1 个答案:

答案 0 :(得分:2)

最好使用 Wrapper 访问View并更早地定义OnClickListener(以及在适配器外以获得更好的效果)可用性)。

以下示例显示了如何在View的一个项目上处理2 可点击 ListView且效果良好:

public class ItemAdapter extends BaseAdapter {

    private List<Item> items;
    private ItemWrapper wrapper = null;
    private OnClickListener onMyItemClickListener1;
    private OnClickListener onMyItemClickListener2;

    public ItemAdapter(Context context, List<Item> items, OnClickListener onMyItemClickListener1, OnClickListener onMyItemClickListener2) {
        this.inflater = LayoutInflater.from(context);
        this.items = items;
        this.onMyItemClickListener1 = onMyItemClickListener1;
        this.onMyItemClickListener2 = onMyItemClickListener2;
    }        

    @Override
    public int getCount() {
        return items.size();
    }

    @Override
    public Object getItem(int position) {
        return items.get(position);
    }

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

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

        if (row == null) {
            row = inflater.inflate( R.layout.item, null);
            wrapper = new ItemWrapper(row);
            row.setTag(wrapper);
        } else {
            wrapper = (ItemWrapper)row.getTag();
        }

        Item item = getItem(position);
        wrapper.getClickView1().setOnClickListener(onMyItemClickListener1);
        wrapper.getClickView2().setOnClickListener(onMyItemClickListener2);
        return(row);
    }        
}

public class ItemWrapper {
    private View baseView;
    private View clickView1;
    private View clickView2;

    public ItemWrapper(View baseView) {
        this.baseView = baseView;
    } 

    public View getClickView1() {
        if ( clickView1 == null) {
            clickView1 = (View)baseView.findViewById(R.id.clickView1);
        }

        return(clickView1);
    }  

    public View getClickView2() {
        if ( clickView2 == null) {
            clickView2 = (View)baseView.findViewById(R.id.clickView2);
        }

        return(clickView2);
    }
}