Android Multiple EditText fields in ListAdapter

I have a screen (see the figure) that is populated by the GridView using the custom BaseAdapter extension.

When a user enters any text in the EditText fields, the text they entered may disappear completely or completely. I suppose this is due to recycling views, but my listadapters are poorly understood.

Fields behave fine due to the Manifest entry in android: windowSoftInputMode = "adjustPan", but they move if you scroll randomly.

All I want to do is get some String data from the user. Strings are stored in the global array String "string []". The string array is updated by MyTextWatcher, which is just an extension of TextWatcher.

Code (attempts) so that TextWatchers always know the position of their EditText field in the grid. Therefore, TextWatchers should always update the [] lines with the correct index.

shows an example of the carnage

I have every reason to believe that the problem arises from my getView () method:

public void initList() { ArrayAdapter<String> listAdapter = new ArrayAdapter<String>(this, R.layout.shape, strings) { @Override public View getView(final int position, View convertView, ViewGroup parent) { final ViewHolder holder; if (convertView == null || convertView.getTag() == null) { convertView = LayoutInflater.from(getContext()).inflate(R.layout.shape, null); holder = new ViewHolder(); holder.text = (TextView) convertView.findViewById(R.id.shape_text); holder.image = (ImageView) convertView.findViewById(R.id.shape_image); holder.editText = (EditText) convertView.findViewById(R.id.shape_edittext); holder.editText.addTextChangedListener(new TextWatcher() { public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2){} public void onTextChanged(CharSequence s, int start, int before, int count) { if (gameType == SHAPES_ABSTRACT && before == 0 && count == 1) { InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); mgr.hideSoftInputFromWindow(holder.editText.getWindowToken(), 0); } } public void afterTextChanged(Editable s) { strings[holder.ref]= s.toString(); } }); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.ref = position; holder.editText.setText(strings[position]); holder.image.setBackgroundResource(images[position]); if (gameType == SHAPES_ABSTRACT) holder.text.setText("Seq:"); else holder.text.setVisibility(View.GONE); return convertView; } }; grid.setAdapter(listAdapter); } 
0
source share
1 answer

I would prefer this, as in the other answer, to say that I will not implement it that way. You do scary things. By posting a lot of links. However, I think this should help:

 Map<EditText, MyTextWatcher> watchers = new HashMap<EditText, MyTextWatcher>(); public View getView(int position, View convertView, ViewGroup parent) { View MyView = convertView; if (MyView == null) { LayoutInflater li = getLayoutInflater(); MyView = li.inflate(R.layout.shape, null); } EditText textbox = (EditText) MyView.findViewById(R.id.shape_edittext); textbox.setText(strings[position]); MyTextWatcher myTextWatcher = watchers.get(textbox); if(myTextWatcher == null) { myTextWatcher = new MyTextWatcher(position, textbox); watchers.put(textbox, myTextWatcher); } myTextWatcher.setIndex(position); ImageView image = (ImageView) MyView.findViewById(R.id.shape_image); image.setBackgroundResource(images[position]); TextView text = (TextView) MyView.findViewById(R.id.shape_text); text.setText("Seq:"); return MyView; } 

The problem is that you created a TextWatcher, added it to EditText, but then saved the link to it in the list by position, so the links between EditText and TextWatcher were broken.

This solution assumes that the 'equals' for the EditText will compare object instances, not value comparisons. If this is not the case, you need to keep a link to all instances of EditText and match "==" with each and find a match.

I think there are safer ways to do this, but give it a chance.

+2
source

Source: https://habr.com/ru/post/901405/


All Articles