【问题标题】:TextView in Listview onclick conflictListview中的TextView onclick冲突
【发布时间】:2013-12-03 21:59:50
【问题描述】:

我制作了一个 Listview 填充了 list_row_layout.xml(填充了 json 可序列化类),我有可点击的 textview 和 onclick 将文本从“Accept”更改为“Accepted”。但是当我在第一个 listview 项目上单击它时,下面的另一个 textview listview 项目正在发生变化。这里有一些照片来描述你最好的。

单击第一行中的接受后 在Activity类中

      feedListView.setAdapter(new CustomListAdapter(this, feedList));

ListAdapter 类

    public class CustomListAdapter extends BaseAdapter
   {
 private ArrayList<FeedItem> listData;
 private LayoutInflater layoutInflater;
 private Context mContext;

public CustomListAdapter(Context context, ArrayList<FeedItem> listData)
{
this.listData = listData;
layoutInflater = LayoutInflater.from(context);
mContext = context;
 }

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

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

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


public View getView(int position, View convertView, ViewGroup parent)
{
final ViewHolder holder;
if (convertView == null)
{
    convertView = layoutInflater.inflate(R.layout.list_row_layout, null);

    holder = new ViewHolder();

    holder.headlineView = (TextView)convertView.findViewById(R.id.title);
    holder.reportedDateView = (TextView) convertView.findViewById(R.id.confid);
    holder.approve = (TextView) convertView.findViewById(R.id.approveTV);

    holder.approve.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View argView)
            {
                holder.approve.setText("accepted");
            }
        }
    );

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

FeedItem newsItem = listData.get(position);

holder.headlineView.setText(Html.fromHtml(newsItem.getTitle()));
holder.reportedDateView.setText(Html.fromHtml(newsItem.getContent()));

holder.approve.setTag(newsItem);



return convertView;
}

static class ViewHolder
{
TextView approve;
TextView headlineView;
TextView reportedDateView;
ImageView imageView;
}
}

【问题讨论】:

    标签: java android listview


    【解决方案1】:

    您的实际解决方案未正确实施。我认为这个问题是你的行没有被正确回收——我认为这正是问题所在:

    holder.approve.setText("accepted");
    

    尝试将其更改为:

    ((TextView) argView).setText("accepted");
    

    这应该有效。 但我建议你改变你的应用程序逻辑。查看您当前的解决方案。您正在为每一行分配 OnClickListener。例如,如果您有 1000+ 行,它不会高效,不是吗?出于这个原因以及为了更好的性能,我建议您只创建一个 OnClickListener(让适配器类实现 View.OnClickListener),然后为每一行分配该侦听器:

    holder.approve.setOnClickListener(this);
    

    onClick() 方法同上:

    @Override
    public void onClick(View v) {
       ((TextView) v).setText("accepted");
    }
    

    现在一切正常@Geralt 解决方案更新如下

    更新:

    问题稍微大一点,因为

    • Collection 对您更改了行的文本一无所知。当 getView() 方法被称为你正在用来自集合的数据填充适配器 但我如何提到集合不知道运行时更改“你”做了 if 你不会更新收藏

    我尝试使用 OnClickListener 保留您的原始解决方案,但现在我认为这不是正确的解决方案。所以让我们制定可行的解决方案:

    解决方案:

    首先你需要使用OnItemClickListener 而不是当前的监听器——它是直接为AdapterView 子类指定的。包含方便的信息,例如整行及其内容,在适配器中的位置只是您需要的信息。

    然后您需要创建机制,让您的收藏项目“不会忘记被点击”。可以这样做:

    • Item 中表示行的下一个属性,例如 布尔变量 isClicked(当您点击行时,只需在点击位置找到集合中的项目并将其属性更改为 true)1

      李>
    • 创建被点击的位置列表(当你点击行时, 将其位置保存到该列表中)2

    那么您应该能够实现正确的行为。现在您需要做的就是在创建行的 getView() 方法中正确使用这些信息。做这样的事情:

    #Solution with property(伪代码):

    ...
    final Item i = collection.get(position);
    if (i.isClicked()) {
       // set text accepted
    }
    else {
       // set text normal
    }
    

    #带有位置列表的解决方案(伪代码):

    ...
    final Item i = collection.get(position);
    if (positions.indexOf(position) > 0) {
       // set text accepted
    }
    else {
       // set text normal
    }
    

    最后是 onItemClick() 方法的示例:

    @Override
    public void onItemClick(AdapterView<?> a, View row, int position, long id) { 
       // solution with list of positions:
       myAdapterClass.addPosition(position);
    
      // solution with property
      myAdapteClass.setItemClicked(position);
    
      // update immediate after click row
      ((TextView) row.findViewById(R.id.yourTextViewId)).setText("Accepted");
    }
    

    以及Adapter类中的方法:

    public void addPosition(position) {
       // if position is not in list
       if (positions.indexOf(position) < 0) {
          positions.add(position);
       }
    }
    
    public void setItemClicked(position) {
       // finds clicked item
       if (collection.get(position) != null) {
          collection.get(position).setIsClicked(true);
       }
    }
    

    希望它能帮助你男人/女孩并解决你的问题。

    【讨论】:

    • View类型中的setOnClickListener(View.OnClickListener)方法不适用于参数(CustomListAdapter)
    • @SandraMladenovic 您是否仔细阅读了我的回答?实现您的适配器类 View.OnClickListener?
    • 我确实实现了它并复制了你的代码,但没有帮助我,也点击了其他文本视图,就像我在这个问题中的图片一样
    • 在 list_row_layout 我有 4 个线性布局和一个相对的父级,这可能是问题吗?以及我在活动类 feedListView.setAdapter(new CustomListAdapter(this, feedList)) 中邀请适配器对象的方式; ?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-28
    • 2011-06-23
    相关资源
    最近更新 更多