Solution to the Problem of incorrect item button listening in ListView in Android

Source: Internet
Author: User
Tags call back

Solution to the Problem of incorrect item button listening in ListView in Android
This problem is often encountered during development. A list is created to add button listening events to each item in the list, however, when there is a lot of data in the list, the click error may often occur. We may all have our own solutions to this problem in the program, but you may be confused when you discover this problem for the first time. Now we can analyze the root cause of this problem. First, let's look at the next wrong BaseAdapter.

Package com. example. listdelectdemo; import java. util. arrayList; import android. content. context; import android. view. layoutInflater; import android. view. view; import android. view. view. onClickListener; import android. view. viewGroup; import android. widget. baseAdapter; import android. widget. button; import android. widget. textView; import android. widget. toast; public class MyDataAdapter extends BaseAdapter {private Context mContext; private ArrayList <String> mStrings; private LayoutInflater mInflater; private String mStrData; public MyDataAdapter (Context c, ArrayList <String> s) {mContext = c; mStrings = s; mInflater = LayoutInflater. from (c) ;}@ Override public int getCount () {return mStrings. size () ;}@ Override public Object getItem (int position) {return mStrings. get (position) ;}@ Override public long getItemId (int position) {return position ;}@ Override public View getView (int position, View convertView, ViewGroup parent) {MyViewHolder viewHolder = null; if (convertView = null) {convertView = mInflater. inflate (R. layout. item, null); viewHolder = new MyViewHolder (); viewHolder. item_button_test = (Button) convertView. findViewById (R. id. item_button_test); viewHolder. item_textView_content = (TextView) convertView. findViewById (R. id. item_textView_content); convertView. setTag (viewHolder);} else {viewHolder = (MyViewHolder) convertView. getTag () ;}// the current mStrData = mStrings in the dataset. get (position); viewHolder. item_textView_content.setText (mStrData); viewHolder. item_button_test.setText ("click"); // The click listener event viewHolder is set for the button of the item. item_button_test.setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {// here, the mStrData output from toast is not the Toast item clicked. makeText (mContext, "you clicked-" + mStrData, Toast. LENGTH_LONG ). show () ;}}); return convertView;} class MyViewHolder {TextView item_textView_content; Button item_button_test ;}}

 

Then, let's analyze the cause. I believe that all the old programmers can see the problem: mStrData = mStrings. get (position); when the getView method is called for the first time, the current item data in the set is taken out and paid to the member variable mStrData. The program continues to execute:
ViewHolder. item_button_test.setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {// here, the mStrData output from toast is not the Toast item clicked. makeText (mContext, "you clicked-" + mStrData, Toast. LENGTH_LONG ). show ();}});

 

Here, a listener event is added to the item button, but note that the program does not call back
@ Overridepublic void onClick (View v) {// The mStrData from toast is not the Toast. makeText (mContext, "you clicked-" + mStrData, Toast. LENGTH_LONG ). show ();}

 

Instead, the getView method will be called back. When the list is about to be loaded, that is, when the getView method is called back for the last time, the member variable mStrData is assigned a value for the last time, the getView method calls back each time, the mStrData value is assigned again. Then, when we click the button, The onClick method of the listener will be called back. At this time, toast: 1Toast will be executed. makeText (mContext, "you clicked-" + mStrData, Toast. LENGTH_LONG ). show (); at this time, mStrData is only the value assigned for the last time, and errors are inevitable. So let's take a look at my solution:
Package com. example. listdelectdemo; import java. util. arrayList; import android. content. context; import android. view. layoutInflater; import android. view. view; import android. view. view. onClickListener; import android. view. viewGroup; import android. widget. baseAdapter; import android. widget. button; import android. widget. textView; import android. widget. toast; public class MyDataAdapter extends BaseAdapter {private Context mContext; private ArrayList <String> mStrings; private LayoutInflater mInflater; private String mStrData; public MyDataAdapter (Context c, ArrayList <String> s) {mContext = c; mStrings = s; mInflater = LayoutInflater. from (c) ;}@ Override public int getCount () {return mStrings. size () ;}@ Override public Object getItem (int position) {return mStrings. get (position) ;}@ Override public long getItemId (int position) {return position ;}@ Override public View getView (int position, View convertView, ViewGroup parent) {MyViewHolder viewHolder = null; if (convertView = null) {convertView = mInflater. inflate (R. layout. item, null); viewHolder = new MyViewHolder (); viewHolder. item_button_test = (Button) convertView. findViewById (R. id. item_button_test); viewHolder. item_textView_content = (TextView) convertView. findViewById (R. id. item_textView_content); convertView. setTag (viewHolder);} else {viewHolder = (MyViewHolder) convertView. getTag ();} mStrData = mStrings. get (position); viewHolder. item_textView_content.setText (mStrData); viewHolder. item_button_test.setText ("click"); // click the item button to set a listener, create an implementation class for the listener, and input the current position viewHolder. listener (new MyAdapterListener (position); return convertView;} class MyViewHolder {TextView item_textView_content; Button listener;} class MyAdapterListener implements OnClickListener {private int position; public MyAdapterListener (int pos) {position = pos ;}@ Override public void onClick (View v) {Toast. makeText (mContext, "you clicked-" + mStrings. get (position), Toast. LENGTH_LONG ). show ();}}}

 

At this time, no problem will occur. The difference is that a new MyAdapterListener object is created each time a click event is added to the button of an item to implement this listener. When the new MyAdapterListener object is used, a position is passed into it as a tag, so that each item will have its own listening class, we can perform some logic processing in this listener class, so there will be no confusion. This solution can only be used as a reference solution. One drawback is that many new objects will be created while there are too many data in the list, which occupies the memory. So we can share with you any better solutions.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.