Customized ListView when scrolling changes randomly button text or edittext

夙愿已清 提交于 2019-12-23 12:03:04

问题


I have searched for this one but to no avail I haven't get the exact answer to the issue.

I have a button inside a ListView, when that button is clicked it shows an alert dialog to choose a date and after choosing date, the selected date will be the text of the button. The code works fine but when i scroll down and up the date will be randomly change here is my code for the getView() method of my adapter.This also happens to the EditText when i type to any of the EditText works fine but when i start scrolling the values also change.

Here is my get view method

public View getView(int position, View convertView, ViewGroup parent) {
    final ViewHolder viewHolder;
    if(convertView == null){
        convertView = layoutInflater.inflate(R.layout.repeat_entry_listview,null);

        viewHolder = new ViewHolder();
        viewHolder.btnDate = (Button) convertView.findViewById(R.id.rpbtnDate);
        viewHolder.txtNotes  = (EditText) convertView.findViewById(R.id.rpNotes);
        convertView.setTag(viewHolder);
    }else{
        viewHolder = (ViewHolder) convertView.getTag();
    }


    RepeatEntryList repeatEntryList = listData.get(position);
    viewHolder.btnDate.setText(repeatEntryList.getDate());
    viewHolder.btnDate.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          //EVEN IF I REMOVE THE CODE FOR SETTING THE BUTTON TEXT TO JUST LIKE THE BELOW CODE. SCROLLING ISSUES STILL PERSIST

          viewHolder.btnDate.setText("just sample date text");

            //**NOTE UPDATED**
            //MY EDITTEXT ALSO HAVE THE SAME BEHAVIOR
        }
    });
    viewHolder.txtNotes.setHint(contx.getResources().getString(R.string.placeholder_txt));
    return convertView;
}

Note Let's say i have 20 buttons and 20 EditText inside the ListView. When i type something to all of the EditText and change the text of the button by clicking it ,then scroll down and up the ListView ,the text or values of EditText and button will change or interchange and sometimes gone.

With regards to my problem can someone explain to me why ListView is behaving like this and how to avoid this certain behavior.


回答1:


make changes in your code remove if(convertView == null){ }else{} condition and directly use as follow

convertView = layoutInflater.inflate(R.layout.repeat_entry_listview,null);
Button btnDate = (Button) convertView.findViewById(R.id.rpbtnDate);
TextView txtNotes  = (EditText) convertView.findViewById(R.id.rpNotes);



回答2:


Just add below line, repeatEntryList.setDate("Selected Date")

datePickerTo.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {

                                String strdate = (pickerTo.getMonth() + 1) + "-" + pickerTo.getDayOfMonth() + "-" + pickerTo.getYear();

                                viewHolder.btnDate.setText(mainActivity.pickerStringTodate(strdate));

//Here is your new line
repeatEntryList.setDate(mainActivity.pickerStringTodate(strdate))


                                try {
                                    Date date1 = mainActivity.dateFormat.parse(viewHolder.btnDate.getText().toString());
                                    Date date2 = mainActivity.dateFormat.parse(mainActivity.dateFormat.format(new Date()));
                                    if (date1.before(date2)) {
                                        Toast.makeText(contx, "You cannot select past date", Toast.LENGTH_LONG).show();
                                        viewHolder.btnDate.setText(mainActivity.dateFormat.format(new Date()));
                                    }
                                } catch (ParseException e) {
                                    e.printStackTrace();
                                }
                            }
                        }).setNegativeButton("Cancel", null);
                        datePickerTo.show();



回答3:


Make your position variable final in getView

final int position

And also make your modal class as Final.

final RepeatEntryList repeatEntryList = listData.get(position);



回答4:


You are using an if condition:

if (date1.before(date2)) { 
    Toast.makeText(contx, "You cannot select past date", Toast.LENGTH_LONG).show();
    viewHolder.btnDate.setText(mainActivity.dateFormat.format(new Date()));
}else{viewHolder.btnDate.setVisibility(View.GONE);}

But there is no else case. The else case should be handled too.




回答5:


This is what i have done to solve my problem is incase someone might have the same problem:
1. First i create i variable inside my custom Adapter class which is RepeatEntryListAdapter and called it listData

public ArrayList<RepeatEntryList> listData;

2. i reference listData variable to be the array list of RepeatEntryList class which is my getter and setter class like this.

public RepeatEntryListAdapter(Context context,ArrayList<RepeatEntryList> listdata){
          this.listData = listdata;
            this.contx = context;
            mainActivity = (MainActivity) context;
            layoutInflater= LayoutInflater.from(context);
       }

3. Inside getview method i created click event for the button .Inside the click event I instantiated my getter class then use the instantiated variable of my getter class and use settext,for setting the text of the button and also set the date for the lisData variable.and the important part is use the listData variable in which i use the position variable to set the value of a certain position of the listData varaible like this.

 RepeatEntryList re = rListData;
 viewHolder.btnDate.setText('07-06-2015')//say the date selected is the string inside setText                          re.setDate(viewHolder.btnDate.getText().toString());//set Date is a setter method inside my RepeatEntryList class
 listData.set(position, re);//position variable should be final

4. This is the most trickiest part which is part in solving the scrolling problem of my custom list view which is caused by the edittext watcher which fires when scrolling . what i did is.

a. i Created a class that implements TextWatcher like this

class EditTextWatcher implements TextWatcher{

        private int mPosition;
        private boolean mActive;

        void setPosition(int position){
            mPosition = position;
        }
        void setActive(boolean active){
            mActive = active;
        }
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            if(mActive){
                //rNotes.set(mPosition,s.toString());
                RepeatEntryList re = listData.get(mPosition);
                re.setNotes(s.toString());
                listData.set(mPosition,re);
            }
        }
    }

b. i also created a variable for EditeTextWatcher inside my static class ViewHolder

 static class ViewHolder{
   public Button btnDate;
   public EditText txtNotes;
   public EditTextWatcher mWatcher;
}

c. inside my getview method ,i created a new instance of EditTextWatcher() which also create a new textwatcher and not use the last event because i create a new instance of the textwatcher

public View getView(final int position, View convertView, ViewGroup parent) {

        final ViewHolder viewHolder;

        final RepeatEntryList rListData = listData.get(position);

        if(convertView == null){
            convertView = layoutInflater.inflate(R.layout.repeat_entry_listview,null);

            viewHolder = new ViewHolder();
            viewHolder.btnDate = (Button) convertView.findViewById(R.id.rpbtnDate);
            viewHolder.mWatcher = new EditTextWatcher();
            viewHolder.txtNotes  = (EditText) convertView.findViewById(R.id.rpNotes);
            viewHolder.txtNotes.addTextChangedListener(viewHolder.mWatcher);

            convertView.setTag(viewHolder);
        }else{
            viewHolder = (ViewHolder) convertView.getTag();


        }

        viewHolder.btnDate.setText(rListData.getDate());

        viewHolder.mWatcher.setActive(false);
        viewHolder.txtNotes.setText(rListData.getNotes());
        viewHolder.mWatcher.setPosition(position);
        viewHolder.mWatcher.setActive(true);


      //here is the part of button click event i mention above (no 3.)
return convertView;
}


来源:https://stackoverflow.com/questions/31309654/customized-listview-when-scrolling-changes-randomly-button-text-or-edittext

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!