【问题标题】:Android: Only the last row of my ListView is reacting to an OnClickListenerAndroid:只有我的 ListView 的最后一行对 OnClickListener 做出反应
【发布时间】:2016-03-20 19:42:30
【问题描述】:

我有一个带有 View Holder 的 ListView。当我在ListView 的某一行中按下一个按钮时,它应该在该位置展开该行并在我再次按下它时折叠。我在布局上使用显示/隐藏来做到这一点。但是,单击并未扩展正确的行。

示例:

I was clicked
I am a row that was not clicked
I am a row that was not clicked
I am a row that was not clicked // yet my layout was shown and hidden

每当我滚动时都会发生这种情况,只有在我的ListView 中可见的最后一行才会对我按下的任何行做出反应。

代码

public class PetAdapter extends BaseAdapter {
...
...

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

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public int getItemViewType(int position) {
        if (mPetList.get(position).getPetType().equals(ConstantValues.CAT)) {
            return 0;
        } else {
            return 1;
        }
    }

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

    @Override
    public long getItemId(int position) {
        return Integer.parseInt(mPetList.get(position).getId());
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Pet pet;
        View view = convertView;

        switch (getItemViewType(position)) {
            case 0:
                pet = mPetList.get(position);
                mRowType = ConstantValues.CAT;
                view = createCatRow(pet, convertView, parent);
                break;
            case 1:
                pet = mPetList.get(position);
                mRowType = ConstantValues.DOG;
                view = createDogRow(pet, convertView, parent);
                break;
        }

        return view;
    }

膨胀行

    public View createCatRow(Pet pet, View convertView, ViewGroup parent) {
        if (convertView != null) {
            mCatHolder = (CatViewHolder) convertView.getTag();
        } else {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.cat_row, parent, false);
            mCatHolder= new CatViewHolder(convertView);
            convertView.setTag(mCatHolder);
        }

        setCatText(pet);
        setCatListeners(pet);

        return convertView;
    }

设置文字

    public void setCatText(Pet pet) {
        mCatHolder.catName.setText(pet.getName());         
    }

设置监听器

public void setCatListeners(Pet pet) {      
    mCatHolder.catName.setOnClickListener(getCatNameListener(pet));
}

public View.OnClickListener getCatNameListener(final Pet pet) {
     return new View.OnClickListener() {
         @Override
         public void onClick(View v) {
             expandCard(pet);
         }
     };
}

设置可见性

public void expandCard(Pet pet) {
    if (mCatHolder.expanded.getVisibility() == View.GONE) {
        mCatHolder.collapsed.setVisibility(View.GONE);
        mCatHolder.expanded.setVisibility(View.VISIBLE);
    } else {
        mCatHolder.collapsed.setVisibility(View.VISIBLE);
        mCatHolder.expanded.setVisibility(View.GONE);
    }
}

查看持有人

public static class CatViewHolder {            
    @Bind(R.id.expanded) RelativeLayout expanded;
    @Bind(R.id.collapsed ) RelativeLayout collapsed;
    @Bind(R.id.cat_name) TextView catName;

    public CatViewHolder(View view) {
        ButterKnife.bind(this, view);
    }
}

请帮助我理解为什么会发生这种行为。为什么最后一行对第一行的 OnClick 事件做出反应。谢谢

【问题讨论】:

  • 我会试试这个。不过,它确实采用了一些类似的方法。由于我有两个布局,这意味着我必须使用条件语句过滤每个方法,或者我必须为每种类型创建两个方法,即使它们做同样的事情
  • 你在你的适配器类中持有对持有者的引用吗?这通常不能很好地工作。与其将 viewholder 作为参考,为什么不将它传递给您的函数呢?您知道每个列表视图只有一个适配器类实例吗?
  • @Bhargav 是的,我只是认为通过每个函数传递它会更容易。现在重构试试
  • @Rah ty 你是对的
  • @Bhargav 它的工作原理是将其本地化并每次都通过它

标签: android listview android-listview onclicklistener


【解决方案1】:

RecyclerView 中,视图被回收。所以第一行的视图被重新用于后面的行,它仍然是OnClickListener。您必须在 every onBindViewHolder() 中设置监听器。

【讨论】:

  • 我相信我正在这样做。如果不是,请告诉我我是如何打破视图持有者模式的。
【解决方案2】:

您在适配器类中持有对您的查看器的引用,然后将 onClicklistener 应用于视图。这意味着 viewholder 变量将引用最后呈现的视图,同时将 onclicklistener 设置为最后呈现的视图。

您需要在 getview 方法中让 viewholder 引用一个局部变量,并将其传递给所有需要 view holder 的函数。

【讨论】:

    猜你喜欢
    • 2016-07-30
    • 1970-01-01
    • 2021-07-27
    • 2015-09-04
    • 1970-01-01
    • 2021-08-11
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    相关资源
    最近更新 更多