我已经使用list_row_layout.xml填充了Listview(其中填充了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;
}
}
答案 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解决方案更新
问题略大,因为
我尝试使用 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);
}
}
希望它能帮助你解决你的问题。