ListView子对象可点击的confilct

在问了一个问题并花了15天解决这个问题之后,我又在这里寻找帮助和解决方法。 在MainActivity中,我创build了Json Downloading Task,它从http下载数据,并使用CustomListAdapter.class填充listview。 一切正常。 现在,在列表视图中,我有两个textview的,我想点击,其中之一是“接受”,textview只是在XML它没有填充适配器或JSON。 “接受”应该像这样工作“改变文本接受和改变颜色”,其工作就像一切。 但是当我点击第一个“接受”(位置0)在列表视图它改变其他列表视图项目(位置4,9)。 这就像我点击位置4,9的文字。 第一个图像是在点击“接受”之前,第二个是点击。

在点击之前 /// 点击后

public class MainActivity extends Activity { protected static final String TAG = null; public ArrayList<FeedItem> feedList; public ListView feedListView; private ProgressBar progressbar; private CustomListAdapter adap; private LayoutInflater mInflater; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); feedListView= (ListView) findViewById(R.id.custom_list); mInflater = (LayoutInflater) getSystemService(Activity.LAYOUT_INFLATER_SERVICE); String url = "..."; new DownloadFilesTask().execute(url); getActionBar().setIcon(R.drawable.angel); progressbar = (ProgressBar)findViewById(R.id.progressBar); public void updateList() { adap = new CustomListAdapter(this, feedList); feedListView.setAdapter(adap); } public class DownloadFilesTask extends AsyncTask<String, Integer, Void> { ///.... 

CustomListAdapter.class

  public class CustomListAdapter extends BaseAdapter { private ArrayList<FeedItem> listData; private LayoutInflater layoutInflater; private Context mContext; private ArrayList<String> data; protected ListView feedListView; ArrayList<HashMap<String,String>> list; public CustomListAdapter(Context context, ArrayList<FeedItem> listData) { this.listData = listData; layoutInflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); mContext = context; data = new ArrayList<String>(); for (int i = 0; i < 10; i++) { data.add("Sample Text " + String.valueOf(i)); } } @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; View row=convertView; if ((row == null) || (row.getTag()==null)) { convertView = layoutInflater.inflate(R.layout.list_row_layout, null); holder = new ViewHolder(); holder.headlineView = (TextView)convertView.findViewById(R.id.name); holder.reportedDateView = (TextView) convertView.findViewById(R.id.confid); holder.accept= (TextView) convertView.findViewById(R.id.acceptTV); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } final FeedItem newsItem = (FeedItem) listData.get(position); holder.accept.setFocusable(true); holder.accept.setClickable(true); holder.headlineView.setText(Html.fromHtml(newsItem.getTitle())); holder.reportedDateView.setText(Html.fromHtml(newsItem.getContent())); holder.accept.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { holder.accept.setText(Html.fromHtml(newsItem.getContent())); } }); return convertView; } static class ViewHolder { TextView accept; TextView headlineView; TextView reportedDateView; ImageView imageView; FeedItem newsItem; } 

您需要了解如何使用listview回收机制

ListView的回收机制如何工作

使用模型类。 假设你已经有了下面的内容

 public class FeedItem { String title,content; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } } 

getView

 holder.accept.setText(listData.get(position).getContent()); holder.accept.setTag(position); holder.accept.setOnClickListener(mClickListener); 

然后

 private OnClickListener mClickListener = new OnClickListener() { public void onClick(View v) { int pos = (Integer) v.getTag(); FeedItem newsItem = (FeedItem) listData.get(pos); newsItem.setContent("Accepted"); CustomListadapter.this.notifyDataSetChanged(); } }; 

Exaplanation:

你使用一个有getter和setter的模型类。

您将setTag设置为位置的button。 在onClick你得到的标签即位置,并相应地改变内容。 通过调用适配器上的notifyDataSetChanged来刷新listview。

为了他人的利益,这里是一个例子

 public class MainActivity extends Activity { ArrayList<Holder> list = new ArrayList<Holder>(); ListView lv; CustomListAdapter cus; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv = (ListView) findViewById(R.id.listView1); for(int i=0;i<10;i++) { Holder h = new Holder(); h.setTitle("Title"+i); h.setContent("Content"+i); h.setColor(Color.BLACK); list.add(h); } cus = new CustomListAdapter(this,list); lv.setAdapter(cus); } } 

模型类持有人

 public class Holder { String title,content; int color; public int getColor() { return color; public void setColor(int color) { this.color = color; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } } 

CustomListAdapter

 public class CustomListAdapter extends BaseAdapter{ LayoutInflater inflater; ArrayList<Holder> list; public CustomListAdapter(MainActivity mainActivity, ArrayList<Holder> list) { inflater = LayoutInflater.from(mainActivity); this.list =list; } @Override public int getCount() { // TODO Auto-generated method stub return list.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return position; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = inflater.inflate(R.layout.list_item, parent, false); holder = new ViewHolder(); holder.tv = (TextView) convertView.findViewById(R.id.textView1); holder.b = (Button) convertView.findViewById(R.id.button1); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } Holder h = list.get(position); holder.tv.setText(h.getTitle()); holder.b.setText(h.getContent()); holder.b.setTextColor(h.getColor()); holder.b.setOnClickListener(mClickListener); holder.b.setTag(position); return convertView; } private OnClickListener mClickListener = new OnClickListener() { public void onClick(View v) { int pos = (Integer) v.getTag(); Holder h = (Holder) list.get(pos); h.setContent("Accepted"); h.setColor(Color.BLUE); CustomListAdapter.this.notifyDataSetChanged(); } }; static class ViewHolder { TextView tv; Button b; } } 

list_item.xml

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginRight="40dp" android:text="Button" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/button1" android:layout_alignParentLeft="true" android:layout_marginLeft="22dp" android:text="TextView" /> </RelativeLayout> 

activity_main.xml中

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView> </RelativeLayout> 

快照

点击第1行和第5行的button,将其更改为已接受并且为蓝色。

在这里输入图像描述

 getView(...){ if ((row == null) || (row.getTag()==null)) { // some code }else{ // some code } holder.accept.setTag(position); // some more code if(newsItem.isSelected()){ holder.accept.setText("accepted"); }else{ holder.accept.setText("accept"); } //handling click holder.accept.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { int position = (Integer)arg0.getTag(); // change backing dataset here instead. FeedItem m = listData.get(position); // declare a boolean 'selected' in FeedItem // toggle the previous selection m.setSelected(! m.isSelected()); // call notifydatasetChanged CustomListAdapter.this.notifyDataSetChanged(); } }); // some more code } class FeedItem{ // some data member boolean selected = false; public boolean isSelected(){ return selected; } public void setSelected(boolean status){ selected = status; } } 

你的问题肯定是因为你不重置视图的状态,当他们被重用。 ListView重用视图更好的内存pipe理。 所以调整你的getView()来根据select的项目状态调整文本和颜色。 我没有看到你的代码在哪里,所以我不能给你一个工作的例子。

就像是

  if (newsItem.selected) holder.accept.setText("accepted"); else holder.accept.setText("accept");