background
Recently, we are developing the answer App, which involves the possibility of multiple blank filling questions. For this kind of demand, I will adopt the new style of the traditional ListVIew+Adapter. (Ps: single choice, multiple choice, filling in blank and judging common question types are mixed in the answer, which is just for convenience.) It mainly talks about the pit that Adapter encountered when embedding EditText, and gives you a rendering.
This is the interface of multiple blank filling questions, and the problem encountered is that when multiple input boxes input content, it can be seen through debugging that when the keyboard is closed, getView will be executed again, so as to save data for us again, which obviously does not conform to our logic. First paste the code as follows, and adjust the details by yourself.
Class Adapter
class OptionsListAdapter extends BaseAdapter {
private boolean flag=true; private Context mContext;
private HashMap<Integer, String> contentMap = new HashMap<Integer, String>();// Save the data of edittext to avoid the influence of pop-up and hide of soft keyboard on the data
ListView lv; int index; public List<QuestionOptionBean> options; private int selectItem = -1; private TextView ctv; public OptionsListAdapter(Context context, List<QuestionOptionBean> options, ListView lv, int index) { this.mContext = context; this.options = options; this.lv = lv; } public int getCount() { return options.size(); } @Override public boolean areAllItemsEnabled() { return false; } @Override public boolean isEnabled(int position) { return true; } @Override public boolean hasStableIds() { return true; } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public View getView(final int position, View convertView, ViewGroup parent) { View view = null; final ViewHolder viewHolder; if (questionBean.getQuestion_type() == 4) {//Multiple choice filling questions if (view == null) { view = LayoutInflater.from(mContext).inflate( R.layout.item_edittext, null); viewHolder = new ViewHolder(view); view.setTag(viewHolder); } else { viewHolder = (ViewHolder) view.getTag(); } if (viewHolder.editText.getTag() instanceof TextWatcher) { viewHolder.editText.removeTextChangedListener((TextWatcher) viewHolder.editText.getTag()); } if(flag) { if (!options.get(position).getName().isEmpty()) {//The answer submitted last time will be displayed now. viewHolder.editText.setText(options.get(position).getDescription()); contentMap.put(position, viewHolder.editText.getText().toString());// Store the changed data } } //Determine EditText editing location viewHolder.editText.setOnTouchListener(new View.OnTouchListener() {//Determine EditText touch location @Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction()==MotionEvent.ACTION_UP) { index = position; flag=false;//If the cursor position is determined, it means that the data has changed, which is set to false. } return false; } }); viewHolder.editText.addTextChangedListener(new TextWatcher() { @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) { int tag = (int) viewHolder.editText.getTag();//Determine EditText editing location contentMap.put(tag, s.toString());// Store the changed data } }); // if (contentMap.get(position) != null) { // viewHolder.editText.setText(contentMap.get(position)); // } else { // viewHolder.editText.setText(""); // } // //Set the focus and edittext to set the cursor position. Remember, first set the text. Then set the focus and cursor position. // if (index != -1 && index == position) { // viewHolder.editText.requestFocus(); // viewHolder.editText.setSelection(viewHolder.editText.getText().toString().length()); // } } else { //Choice question view = LayoutInflater.from(mContext).inflate( R.layout.list_item_option, null); ctv = (TextView) view.findViewById(R.id.ctv_name); TextView option = (TextView) view.findViewById(R.id.tv_option); ctv.setText(options.get(position).getName()); option.setText(options.get(position).getDescription()); updateBackground(position, ctv); } // if (position == selectItem) { // ctv.setBackgroundResource(R.drawable.option_btn_single_checked); // notifyDataSetChanged(); // } // else { // ctv.setBackgroundResource(R.drawable.option_btn_single_normal); // notifyDataSetChanged(); // } return view; } public void updateBackground(int position, TextView view) { int backgroundId; selectItem = -1; if (lv.isItemChecked(position)) { backgroundId = R.drawable.shape_red_point; view.setTextColor(getResources().getColor(R.color.white)); } else { backgroundId = R.drawable.shape_red_unpoint; view.setTextColor(getResources().getColor(R.color.back)); } Drawable background = mContext.getResources().getDrawable(backgroundId); view.setBackgroundDrawable(background); notifyDataSetChanged(); } public void setSelectItem(int selectItem) { this.selectItem = selectItem; } }
end
I don't need to set the width of ListView as it is said on the Internet. After all, this is not a good experience. I haven't tried this method either. I change the state or it will perform getView () refresh. Problems encountered in the work, for reference, thank you.