Change ListView List Background - Strange Behavior

I have a problem with changing the background of the view in a ListView.

What I need:
Change the background image of the onClick () line

What is actually going on:
The background changes (is selected) after clicking, for example. First recording. But after scrolling, the eighth record is also selected. Scrolling up to the first is not selected. Now the second entry will be selected. Keep scrolling and keep jumping ...

What am I dong in code:
I have channels, and onClick () I switch the channel attribute boolean selected and then I change the background. I only do this onClick (), so I don’t understand why this is happening on other posts. One thing I notice: this seems to be just “drawing” - the part, because the element that is selected “by itself” has the selected value set to false

I think this has something to do with reusing views in custom ListAdapters getView (...)

OnClick () code in ListActivity:

@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; } 

Code 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 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; } 

I would really appreciate any idea how to solve this! :)

If you need more information, please tell me.

Thanks in advance!

+7
source share
1 answer

Let me show you the code that I use for each ListView , and properly control the click event to change the background and do something else

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

The officelistitemlayout.xml file will look like this: add drawable and design it according to your code in 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> 

Hope this helps :)

+10
source

All Articles