使用ViewHolder类在getview()中设置onClickListener

时间:2014-04-08 19:08:49

标签: android listview onclicklistener

我有一个扩展BaseAdapter的自定义列表适配器。 我创建了一个holder类来标记我的视图,以避免夸大已经存在的视图。

static class ViewHolder{
    TextView tvName;
    TextView tvDescription;
    Button   btAdd;
}

在我的getView中我有这样的事情:

public View getView(int position, View convertView, ViewGroup parent) {
    View vi = convertView;
    ViewHolder holder = null;

    if(vi == null){
        vi = inflater.inflate(R.layout.list_row, null);
        holder = new ViewHolder();
        holder.tvName = (TextView)vi.findViewvById(R.id.name);
        holder.tvDescription = (TextView)vi.findViewvById(R.id.desc);
        holder.btAdd = (Button)vi.findViewvById(R.id.btnadd);
    }else{
        holder = (ViewHolder) vi.getTag();
    }

    holder.btnAdd.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            holder.btnAdd.startAnimation(scale);
        holder.tvName.setVisibility(View.GONE);
        }
    });
    return vi;
}

但eclipse从" holder.btnAdd.startAnimation(scale)获得错误;"并说持有人应该是最后的......

我该如何解决?

2 个答案:

答案 0 :(得分:6)

您应该使用view方法获取onClick,如下所示:

holder.btnAdd.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        v.startAnimation(scale);
    }
});  

您在View v方法中传递了onClick参数。然后,您的方法会附加到您的案例中的视图:holder.btnAdd,因此v == holder.btnAdd

<强>更新
我做了什么来解决这个问题有点愚蠢。这真的很简单,实际上您将viewHolder初始化为null,但您不应该这样做。这就是为什么你无法将viewHolder设为final

public View getView(int position, View convertView, ViewGroup parent) {
    View vi = convertView;
    final ViewHolder holder; // without initialized

    if(vi == null){
        vi = inflater.inflate(R.layout.list_row, null);
        holder = new ViewHolder();
        holder.tvName = (TextView)vi.findViewvById(R.id.name);
        holder.tvDescription = (TextView)vi.findViewvById(R.id.desc);
        holder.btAdd = (Button)vi.findViewvById(R.id.btnadd);
    }else{
        holder = (ViewHolder) vi.getTag();
    }
    holder.btnAdd.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            v.startAnimation(scale);
            holder.tvName.setVisibility(View.GONE);
        }
    });
    return vi;
}

就是这样!

答案 1 :(得分:0)

基于这篇文章https://scottweber.com/2013/04/30/adding-click-listeners-to-views-in-adapters/ 每次拨打 getView

时,您都不应该成为听众

而是只使用一次

    @Override public View getView(int position, View convertView, ViewGroup parent) 
    {
    ViewHolder holder;
         if (convertView == null) {
             convertView = 
     LayoutInflater.from(getContext()).inflate(R.layout.row_simple, parent,
     false);
             holder = new ViewHolder();
             holder.text = (TextView) convertView.findViewById(R.id.text);
             holder.button = (Button) convertView.findViewById(R.id.button);
             holder.button.setOnClickListener(mMyButtonClickListener);
             convertView.setTag(holder);
         }
         else {
             holder = (ViewHolder) convertView.getTag();
         }

         holder.button.setTag(position);

         return convertView; }   

private View.OnClickListener mMyButtonClickListener = new View.OnClickListener() {
    @Override
         public void onClick(View v) {
             int position = (Integer) v.getTag();
             Toast.makeText(getContext(), "Row " + position + " was clicked!", Toast.LENGTH_SHORT).show();
         } }