Содержимое EditText внутри ExpandableListView исчезает при нажатии следующего заголовка ExpandableListView

У меня есть edittext внутри дочернего элемента expandablelistview. Затем я ввел текст внутри этого edittext, но всякий раз, когда я нажимаю другой заголовок expandablelistview, текст, который я вводил, исчезает.

Я уже использовал android:windowSoftInputMode="adjustPan" внутри моего Manifest.xml и многих других возможных исправлений, но не работал.

это мой адаптер:

public class ExpendableAdapter extends BaseExpandableListAdapter {
    private Context _context;
    private List<String> _listDataHeader;
    private HashMap<String, List<ExpandItemModel>> _listDataChild;

public ExpendableAdapter(Context context, List<String> listDataHeader,
                             HashMap<String, List<ExpandItemModel>> listChildData) {
    this._context = context;
    this._listDataHeader = listDataHeader;
    this._listDataChild = listChildData;
}

@Override
public Object getChild(int groupPosition, int childPosititon) {
    return this._listDataChild.get(this._listDataHeader.get(groupPosition))
            .get(childPosititon);
}

@Override
public long getChildId(int groupPosition, int childPosition) {
    return childPosition;
}

@Override
public View getChildView(final int groupPosition, final int childPosition,
                         boolean isLastChild, View convertView, ViewGroup parent) {

    final ExpandItemModel childText = (ExpandItemModel) getChild(groupPosition, childPosition);

    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) this._context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.list_item, null);
    }

    final EditText etTotal = (EditText)convertView
            .findViewById(R.id.et_total);

    etTotal.setText(childText.getTotal);

    return convertView;
}

@Override
public int getChildrenCount(int groupPosition) {
    return this._listDataChild.get(this._listDataHeader.get(groupPosition))
            .size();
}

@Override
public Object getGroup(int groupPosition) {
    return this._listDataHeader.get(groupPosition);
}

@Override
public int getGroupCount() {
    return this._listDataHeader.size();
}

@Override
public long getGroupId(int groupPosition) {
    return groupPosition;
}

@Override
public View getGroupView(int groupPosition, boolean isExpanded,
                         View convertView, ViewGroup parent) {
    String headerTitle = (String) getGroup(groupPosition);
    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) this._context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.list_group, null);
    }



    TextView tvHeader = (TextView) convertView
            .findViewById(R.id.tv_header);
    tvHeader.setTypeface(null, Typeface.BOLD);
    tvHeader.setText(headerTitle);

    return convertView;
}

@Override
public boolean hasStableIds() {
    return true;
}


@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
    return true;
}
}

И это макет:

<RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/rl_expen_but"
        android:layout_below="@+id/rl_ats_draft2"
        android:layout_above="@+id/selanjutnya"
        >



        <ExpandableListView
            android:background="@color/cardview_light_background"
            android:id="@+id/lvExp"
            android:descendantFocusability="beforeDescendants"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:animateLayoutChanges="true"/>

        <View
            android:layout_below="@+id/lvExp"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#bebebe"/>

    </RelativeLayout>

Есть ли что-то неправильное, что я сделал с вышеуказанными кодами? Спасибо.

EDIT:

Вот как выглядит мой код после того, как я его отредактировал, как было предложено chandil03. Расширяемое listview больше не обновляется при расширении заголовков. Но странно, когда я вводил значения в edittext в groupposition 0 и child position 0, то в некоторых других edittext в разных goupposition и childposition появляются те же точные значения, которые я набрал в предыдущем edittext. Или даже незнакомец, значения в предыдущем редакторе иногда исчезали.

static class ViewHolder {
    protected View et;

    public void addView(View et){
        this.et = et;
    }
}

       @Override
       public View getChildView(final int groupPosition, final int childPosition,
                     boolean isLastChild, View convertView, ViewGroup parent) {

       final ExpandItemModel childText = (ExpandItemModel) getChild(groupPosition, childPosition);

       ViewHolder viewHolder;

       if (convertView == null) {
           LayoutInflater infalInflater = (LayoutInflater) this._context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
           convertView = infalInflater.inflate(R.layout.list_item, null);
           viewHolder = new ViewHolder();
           viewHolder.addView(convertView
                .findViewById(R.id.et_total));
           convertView.setTag(viewHolder);
       }else{
           viewHolder = (ViewHolder)convertView.getTag();
       }

       final EditText etTotal = (EditText)convertView
        .findViewById(R.id.et_total);

       etTotal.setText(childText.getTotal);

       return convertView;
  }

Ответ 1

Наконец, я смог обработать это, используя эту библиотеку:

http://bignerdranch.github.io/expandable-recycler-view/

Затем, используя AddTextChangedListener, я вставил значение я типа. После этого проверьте вставленные значения в ViewHolderChild. Например:

public void bind(final MyModel model) {
            tvName.setText(model.getName());
            tvPrice.setText(model.getPrice());
            tvNote.setText(model.getNote());

            for(int i=0;i<listProduct.size();i++){
                if(listProduct.get(i).getIdProduct().equals(model.getIdProduct())){
                    et.setText(listProduct.get(i).getQuantity());
                    break;
                }
            }

            et.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) {
                    if(m!=null){
                        listProduct.remove(m);
                    }

                    if (!s.toString().equals("")) {

                        m = new MyModel();
                        m.setName(model.getName());
                        m.setNote(model.getNote());
                        m.setIdProduct(model.getIdProduct());
                        m.setPrice(model.getPrice());
                        m.setQuantity(s.toString());
                        m.setSubtotal(Long.parseLong(s.toString()) * Long.parseLong(model.getPrice()) + "");
                        m.setStock(model.getStock());
                        listProduct.add(m);
                    }
                }
            });
        }

Ответ 2

Всякий раз, когда вы расширяете другой список групп, обновляется, и вы получаете другой экземпляр EditText, который не имеет текста. Текст EditText, в который вы ввели текст, стал бы потомком другого groupView.

Поэтому я бы рекомендовал вам создать класс ViewHolder и сохранить в нем свое представление и установить его как тег, а в getView() проверить, имеет ли значение convertView значение null, которое вы уже сделали. Просто добавьте еще часть и getTag из convertView и соответственно установите значения.

Например:

@Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent)
    {
        View v = convertView;
        if (v == null)
        {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(R.layout.my_layout, parent, false);
            ViewHolder holder = new ViewHolder(); // View holder to save views.
            holder.addView(v.findViewById(R.id.myView));
            v.setTag(holder);
        }
        else{
        ViewHolder holder = (ViewHolder) v.getTag();  // get tag and set values
        // Do whatever you need to with the group view
        }
        return v;
    }

РЕДАКТИРОВАТЬ 1

Я изменил ваш код. Также ознакомьтесь с комментариями.

@Override
    public View getChildView(final int groupPosition, final int childPosition,
                             boolean isLastChild, View convertView, ViewGroup parent) {

        final ExpandItemModel childText = (ExpandItemModel) getChild(groupPosition, childPosition);
        ViewHolder holder;
        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this._context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.list_item, null);
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        }else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.editText.setText(childText.getTotal); // Here whatever you will type in edittext will be overwritten by the value of 'childText.getTotal'. So after you are done writing in edit text make sore you change that in "_listDataChild" list. 

        return convertView;
    }

    /**This is a class that holds view, Here i m not talking about support.v7.widget.RecyclerView.ViewHolder class. Though concept is more or less same.*/
    class ViewHolder{
        EditText editText;

        public ViewHolder(View v)
        {
            editText = (EditText) v.findViewById(R.id.et_total);
        }
    }

РЕДАКТИРОВАТЬ 2

Добавьте следующий код в метод getChildView().

holder.editText.setOnFocusChangeListener(new View.OnFocusChangeListener()
    {
        @Override
        public void onFocusChange(View v, boolean hasFocus)
        {
            if(!hasFocus)
                childText.getTotal = holder.editText.getText().toString(); 
// In java variable contains reference of Object so when you change childText object, it will be reflected in same HashMap you are getting data from.

        }
    });

Ответ 3

EditText перерабатывается при каждом прокрутке вниз или нажатии на другой заголовок в ExpandableListView.

Лучше всего сохранить текст, который пользователь вводит в вашу модель например:

etTotal.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        public void onFocusChange(View v, boolean hasFocus) {
            if (!hasFocus) {
                childText.setTotal(etTotal.getText().toString().trim());
            }
        }
    });

Ответ 4

Сначала создайте класс фиктивной модели для хранения ваших данных из edittext следующим образом:

public class DummyModel {
    String edt_field;
    //
    //And any other data you might want to store
    //
    public DummyModel(String field)
    {
        this.edt_field=field;
    }
}

Затем создайте статический arraylist для хранения ваших данных:

public class DummyStatic  {
public static ArrayList<DummyModel> arl_static=new ArrayList();
}

Затем в вашем классе адаптера измените метод getChildView() следующим образом:

    @Override
public View getChildView(final int groupPosition, final int childPosition,
                         boolean isLastChild, View convertView, ViewGroup parent) {

    final ExpandItemModel childText = (ExpandItemModel) getChild(groupPosition, childPosition);

    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) this._context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.list_item, null);
    }

    final EditText etTotal = (EditText)convertView
            .findViewById(R.id.et_total);
    etTotal.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
             DummyStatic.arl_static.add(childPosition,new DummyModel(charSequence.toString()));
        }

        @Override
        public void afterTextChanged(Editable editable) {

        }
    });

    etTotal.setText(childText.getTotal);

    return convertView;
}

Что этот код будет делать, так это то, что при вводе символов в edittext они будут храниться в объекте DummyModel внутри arraylist.

Вы можете получить эти данные:

String value = DummyStatic.arl_static.get(position).edt_field;