Listview中的TextView onclick冲突

时间:2013-12-03 21:59:50

标签: java android listview

我已经使用list_row_layout.xml填充了Listview(其中填充了json可序列化类),我有可点击的textview和onclick将文本从“Accept”更改为“Accepted”。但是当我在第一个listview项目上单击它时,下面的另一个textview listview项目正在发生变化。这里有一些照片要说明你的意思。

before 单击第一行中的接受后  after clicking the accept in first row  在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;
}
}

1 个答案:

答案 0 :(得分:3)

您的实际解决方案未正确实施。我认为问题是你的行没有被核心回收 - 确切的问题是我认为:

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解决方案更新

更新

问题略大,因为

  • 收藏知道您更改了行的文字。当 getView()时 方法被称为您正在使用来自集合的数据填充适配器 但我怎么提到收集不知道运行时更改“你”做了如果 你不会更新集合

我尝试使用 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
}

#Solution with position list(伪代码):

...
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);
   }
}

希望它能帮助你解决你的问题。