The content of EditText contained into a Android ListView isn't saved

前端 未结 1 1692
我寻月下人不归
我寻月下人不归 2020-12-20 02:34

On my project I have to show to the user a ListView which is contained basically of EditText.

It is like a questionnaire, when he answer to the question he can go do

相关标签:
1条回答
  • 2020-12-20 03:24

    To speed up things in most mobile apps (Android iOS ...) cells of lists are usually recycled. This spares memory especially for long lists. Therefore you have to get the data of a new displayed cell. When the cell goes outside the screen, its layout/view is destroyed. In your case you have to save the text of the edit text somewhere. That's what you are trying to do with the hashmap.

    I don't see any particular mistake in your code.

    If the question is about the "workaround" of using the hashmap, I confirm that for me it is up to you to save the states of the edit text. Using a hashmap is one way of doing it.

    By the way getItem(position).id can be replaced by getItemId(position) which is here for that purpose.

    Not sure if all this answers your question.

    EDIT

    Now that I understood your question correctly I can provide some code. I must say that I am not fully happy with the solution found but at least it is working.

    The problem with the TextWatcher is that you have no access to the context and of the corresponding view.

    Using setOnFocusChangeListener solved the problem. So here is the code I finally got working.

    public final class PointVerificationAdapter extends BaseAdapter {
        List<BasicNameValuePair> mObjects;
        Context mContext;
        LayoutInflater mInflater;
        HashMap<Integer, String> mReponsesActuel;
        ArrayList<String> myItems = new ArrayList<String>();
    
        public PointVerificationAdapter(
                Context context,
                List<BasicNameValuePair> listObjets
                ) {
    
            this.mInflater = LayoutInflater.from(context);
            this.mContext = context;
            this.mObjects = listObjets;
    
            for (int i = 0; i < 30; i++) {
                myItems.add(Integer.toString(i));
            }
        }
    
        @Override
        public int getCount() {
            return mObjects.size();
        }
    
        @Override
        public BasicNameValuePair getItem(int position) {
            return mObjects.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        static class ViewHolder {
            EditText yourEditText;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
    
            ViewHolder holder = null;
    
            if (convertView == null)
            {
                holder = new ViewHolder();
                convertView = mInflater.inflate(R.layout.intervention_reponses_controle_nombre, parent, false);
                convertView.setId(position);
                holder.yourEditText = (EditText) convertView.findViewById(R.id.edValeur);
    
                convertView.setTag(holder);
            }
            else
            {
                holder = (ViewHolder) convertView.getTag();
            }
    
            ((TextView) convertView.findViewById(R.id.tvNom)).setText(Integer.toString(position));
    
            holder.yourEditText.setText(myItems.get(position));
            holder.yourEditText.setId(position);
            holder.yourEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
                public void onFocusChange(View view, boolean hasFocus) {
                    if (!hasFocus){
                        final int position = view.getId();
                        final EditText editText = (EditText) view;
                        myItems.set(position, editText.getText().toString());
                    }
                }
            });
    
            return convertView;
        }
    
    }
    

    FINAL EDIT

    The previous code is working but I wasn't happy with it because you asked for addTextChangedListenerand not for onFocusChange.

    So here is the solution :

    public final class PointVerificationAdapter extends BaseAdapter {
        List<BasicNameValuePair> mObjects;
        Context mContext;
        LayoutInflater mInflater;
        HashMap<Integer, String> mReponsesActuel;
        ArrayList<String> myItems = new ArrayList<String>();
    
        public PointVerificationAdapter(
                Context context,
                List<BasicNameValuePair> listObjets
                ) {
    
            this.mInflater = LayoutInflater.from(context);
            this.mContext = context;
            this.mObjects = listObjets;
    
            for (int i = 0; i < 30; i++) {
                myItems.add(Integer.toString(i));
            }
        }
    
        @Override
        public int getCount() {
            return mObjects.size();
        }
    
        @Override
        public BasicNameValuePair getItem(int position) {
            return mObjects.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        static class ViewHolder {
            EditText yourEditText;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
    
            ViewHolder holder = null;
    
            if (convertView == null)
            {
                holder = new ViewHolder();
                convertView = mInflater.inflate(R.layout.intervention_reponses_controle_nombre, parent, false);
                convertView.setId(position);
                holder.yourEditText = (EditText) convertView.findViewById(R.id.edValeur);
                holder.yourEditText.setId(position);
                holder.yourEditText.addTextChangedListener(new GenericTextWatcher(holder.yourEditText));
                convertView.setTag(holder);
            }
            else
            {
                holder = (ViewHolder) convertView.getTag();
                holder.yourEditText.setId(position);
            }
    
            ((TextView) convertView.findViewById(R.id.tvNom)).setText(Integer.toString(position));
    
            holder.yourEditText.setText(myItems.get(position));
    
            return convertView;
        }
    
        private class GenericTextWatcher implements TextWatcher{
    
            private View view;
            private GenericTextWatcher(View view) {
                this.view = view;
            }
    
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
    
            public void afterTextChanged(Editable editable) {
                final int position = view.getId();
                final EditText editText = (EditText) view;
                myItems.set(position, editText.getText().toString());
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题