【问题标题】:set onClickListener in getview() with ViewHolder class在 getview() 中使用 ViewHolder 类设置 onClickListener
【发布时间】:2018-04-22 18:05:51
【问题描述】:

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

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);”得到错误并说持有人应该是最终的......

我该如何解决?

【问题讨论】:

    标签: android listview onclicklistener


    【解决方案1】:

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

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

    您在onClick 方法中传递View v 参数。然后,您的方法附加到您的情况下的视图: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;
    }
    

    就是这样!

    【讨论】:

    • holder.tvName 怎么样?!
    • onclick 方法中的 holder.tvname 对我不起作用,它得到的是持有者的最后一个实例,它是视图组的最后一项。
    【解决方案2】:

    基于本文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();
             } }
    

    【讨论】:

      猜你喜欢
      • 2021-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多