更改ListView背景 – 奇怪的行为

我在更改ListView中的视图的背景有问题。

我需要的:
更改onClick()行的背景图片

究竟发生了什么:
按下例如第一个条目后,背景被改变(select)。 但是在滚动之后,第8项也被选中。 滚动到顶部,第一个不再被选中。 第二个条目现在被选中。 继续滚动,继续跳跃…

“守则”中的东西:
我有渠道,onClick()我切换通道布尔select的属性,然后我改变背景。 我只做 onClick()这就是为什么我不明白为什么它真的发生在其他条目上。 我注意到的一件事是:似乎只是“绘画”,因为被“自己”选中的项目仍然是虚假选定

我认为这似乎与自定义ListAdapters中的视图重用getView(…)

在ListActivity中onClick()的代码:

@Override protected ViewHolder createHolder(View v) { // createHolder will be called only as long, as the ListView is not // filled TextView title = (TextView) v .findViewById(R.id.tv_title_channel_list_adapter); TextView content = (TextView) v .findViewById(R.id.tv_content_channel_list_adapter); ImageView icon = (ImageView) v .findViewById(R.id.icon_channel_list_adapter); if (title == null || content == null || icon == null) { Log.e("ERROR on findViewById", "Couldn't find Title, Content or Icon"); } ViewHolder mvh = new MyViewHolder(title, content, icon); // We make the views become clickable // so, it is not necessary to use the android:clickable attribute in // XML v.setOnClickListener(new ChannelListAdapter.OnClickListener(mvh) { public void onClick(View v, ViewHolder viewHolder) { // we toggle the enabled state and also switch the the // background MyViewHolder mvh = (MyViewHolder) viewHolder; Channel ch = (Channel) mvh.data; ch.setSelected(!ch.getSelected()); // toggle if (ch.getSelected()) { v.setBackgroundResource(R.drawable.row_blue_selected); } else { v.setBackgroundResource(R.drawable.row_blue); } // TESTING Log.d("onClick() Channel", "onClick() Channel: " + ch.getTitle() + " selected: " + ch.getSelected()); } }); return mvh; } 

getView(…)的代码:

 @Override public View getView(int position, View view, ViewGroup parent) { ViewHolder holder; // When view is not null, we can reuse it directly, there is no need // to reinflate it. // We only inflate a new View when the view supplied by ListView is // null. if (view == null) { view = mInflater.inflate(mViewId, null); // call own implementation holder = createHolder(view); // TEST // we set the holder as tag view.setTag(holder); } else { // get holder back...much faster than inflate holder = (ViewHolder) view.getTag(); } // we must update the object's reference holder.data = getItem(position); // <EDIT SOLUTION> if(getItem(position).get_id() == channelList.get(position).get_id()){ if(getItem(position).getSelected()) { view.setBackgroundResource(R.drawable.row_blue_selected); } else{ view.setBackgroundResource(R.drawable.row_blue); } } // </EDIT SOLUTION> // call the own implementation bindHolder(holder); return view; } 

我真的很感激任何想法如何解决这个问题! 🙂

如果需要更多信息,请告诉我。

提前致谢!

Related of "更改ListView背景 – 奇怪的行为"

让我向您展示我用于每个ListView的代码,并正确地控制click事件以更改背景并进一步做任何事情

 public class Offices extends Activity { private ListView listView; /* selectedListItem will contain the number of items to be selected. * Your list item OnOlickListener will simply change this variable * to the position of the clicked item. The Adapter will do the rest * because you need to refresh the ListView. */ private int selectedListItem = -1; private Handler mHandler = new Handler(); private Vector<String> data; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.officeslayout); data = new Vector<String>(); // Add data as per your requirement data.add("one"); data.add("two"); data.add("three"); data.add("four"); data.add("Five"); data.add("Six"); data.add("Seven"); data.add("Eight"); data.add("Nine"); data.add("Ten"); listView = (ListView)findViewById(R.id.ListView01); listView.setDivider(null); listView.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { selectedListItem = position; ((EfficientAdapter)listView.getAdapter()).notifyDataSetChanged(); mHandler.postDelayed(new Runnable() { @Override public void run() { // call any new activity here or do any thing you want here } }, 200L); } }); listView.setAdapter(new EfficientAdapter(getApplicationContext())); } private class EfficientAdapter extends BaseAdapter { private LayoutInflater mInflater; public EfficientAdapter(Context context) { mInflater = LayoutInflater.from(context); } public int getCount() { return data.size(); } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null || convertView.getTag() == null) { convertView = mInflater.inflate(R.layout.officeslistitemlayout, null); holder = new ViewHolder(); holder.backgroundView = (ImageView) convertView .findViewById(R.id.OfficesBackground); holder.officesTitle = (TextView) convertView .findViewById(R.id.OfficesName); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } if(position == selectedListItem) { holder.backgroundView.setBackgroundResource(R.drawable.and_gray_bg_listing_selected); } else { holder.backgroundView.setBackgroundResource(R.drawable.and_gray_bg_listing); } holder.officesTitle.setText(data.get(position)); return convertView; } } static class ViewHolder { TextView officesTitle; ImageView backgroundView; } } 

officeslistitemlayout.xml文件将如下所示添加drawable并根据您的devise将以下代码放在RelativeLayout

  <ImageView android:id="@+id/OfficesBackground" android:layout_width="fill_parent" android:layout_height="45dip" android:layout_alignParentTop="true" android:background="@drawable/and_gray_bg_listing" android:scaleType="fitXY" ></ImageView> <TextView android:id="@+id/OfficesName" android:layout_width="wrap_content" android:text="Offices Name" android:textColor="#000000" android:textStyle="bold" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="5dip" ></TextView> 

希望它会帮助:)