остановить автоматический вызов getView()

Я реализую Expandable ListView. Каждый дочерний элемент имеет текстовое представление и EditText.

Проблема в том, что в группе 10 элементов/строк. Я ввел данные в строки 1 и 2. Когда я прокручиваю вниз до строк 6 и 7, у них уже есть текст (в строке 6 есть данные строки 1, а в строке 7 - данные строки 2).

Я понимаю, почему это происходит. Это связано с тем, что когда я печатаю в строке 1, я могу в настоящее время видеть строку с 1 по строку 5. Когда я прокручиваю вниз, чтобы просмотреть оставшиеся строки. getChildView() вызывается автоматически, чтобы показать мне оставшиеся строки и их данные, поскольку все тексты редактирования имеют одинаковый идентификатор. Таким образом, в следующем представлении отображаются те же данные, что и в предыдущем представлении. Аналогичная проблема здесь: Метод ArrayAdapter getView() вызывается автоматически при загрузке и при прокрутке списка я пробовал:

  1. его решение, оно не работает.
  2. установка getChildCount() вручную: нет успеха

Вот мой ExpandableListAdapter.java:

package com.syapaa;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import static android.content.Context.MODE_PRIVATE;

public class ExpandableListAdapter extends BaseExpandableListAdapter {



    int j=1;
    int neww=0;
    EditText edt;
    private Context _context;
    private List<String> _listDataHeader; // header titles
    // child data in format of header title, child title
    private HashMap<String, List<String>> _listDataChild;






    public ExpandableListAdapter(Context context, List<String> listDataHeader,
                                 HashMap<String, List<String>> 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(int groupPosition, final int childPosition,
                             boolean isLastChild, View convertView, ViewGroup parent) {



        //Don't change://///////////////////////////////-/////////////////////
        final String childText = (String) getChild(groupPosition, childPosition);

        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this._context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.list_item, null);
        }
        TextView txtListChild = (TextView) convertView.findViewById(R.id.lblListItem);
        //////////////------------------------------------------------------------/////

        //For Sharing my ID(I am Group PG):
        SharedPreferences prefb = convertView.getContext().getSharedPreferences("my_prefb", MODE_PRIVATE);
        SharedPreferences.Editor editb = prefb.edit();
        editb.putInt("GR", groupPosition );
        editb.commit();




        if(childPosition==0){
            //Receiving 1857 of OnClick
            SharedPreferences phobjc = convertView.getContext().getSharedPreferences("my_prefd", 0);
            neww = phobjc.getInt("BRNDM", 0);
            phobjc.edit().clear().commit();
        }


        if(neww==1857){
            edt=convertView.findViewById(R.id.marks);
            String abc=edt.getText().toString();


            j=childPosition+1;
            //For Sharing data entered in list:
            SharedPreferences prefa = convertView.getContext().getSharedPreferences("my_prefa", MODE_PRIVATE);
            SharedPreferences.Editor edita = prefa.edit();
            edita.putString("PH"+j, abc );
            edita.commit();
            Toast.makeText(convertView.getContext(),"Sharing "+ abc+"with "+"PH"+j,Toast.LENGTH_SHORT).show();

            if(isLastChild==true){
                int tellmaxitems=childPosition+1;

                //Sharing No of Items in Group
                SharedPreferences prefd = convertView.getContext().getSharedPreferences("noofitems", MODE_PRIVATE);
                SharedPreferences.Editor editd = prefd.edit();
                editd.putInt("NoItems", tellmaxitems );
                editd.commit();
            }
        }

        txtListChild.setText(childText);
        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 lblListHeader = (TextView) convertView
                .findViewById(R.id.lblListHeader);
        lblListHeader.setText(headerTitle);

        return convertView;
    }

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

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

}

Вот Tab1.Java, где я добавляю элементы в списки/строки:

package com.syapaa;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.CountDownTimer;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.telephony.SmsManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import android.widget.ExpandableListView;


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import static android.content.Context.MODE_PRIVATE;


public class Tab1 extends Fragment {
    int grtoShow=0;
    int prGroup=-1;

    String last="ls.txt";
    SwipeRefreshLayout rfrsh;
    ExpandableListAdapter listAdapter;
    ExpandableListView expListView;
    List<String> listDataHeader;
    HashMap<String, List<String>> listDataChild;
    Button btn;


    @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
         final View v = inflater.inflate(R.layout.tab1, container, false);


        // get the listview
        expListView =  v.findViewById(R.id.lvExp);


        //Pull Down to Refresh ListView///////////////////////////////////////////////////////
        rfrsh=v.findViewById(R.id.refresh);
        rfrsh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                Intent intent = getActivity().getIntent();
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_NO_ANIMATION);
                getActivity().overridePendingTransition(0, 0);
                getActivity().finish();
                getActivity().overridePendingTransition(0, 0);
                startActivity(intent);
                rfrsh.setRefreshing(false);
            }
        });
        ////-------Refresh Logic Ends here----------------------------------------/////////////



        ////////Expand Only One Group at a Time (collapse previously Expanded Gruop)///////////////
        expListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
            @Override
            public void onGroupExpand(int i) {
                new CountDownTimer(120, 1) {
                    public void onFinish() {
                        // When timer is finished
                        // Execute your code here
                        //Taking Group ID (which group was expanded last)
                        SharedPreferences phobjb = getContext().getSharedPreferences("my_prefb", 0);
                        final int i= phobjb.getInt("GR", 0);
                    }
                    public void onTick(long millisUntilFinished) {}
                }.start();
                if ((prGroup != -1) && (i != prGroup)) {
                    expListView.collapseGroup(prGroup);
                    InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
                    try{imm.hideSoftInputFromWindow(v.getWindowToken(), 0);}
                    catch (Exception e){}
                }
                prGroup = i;
            }
        });
        /////////////-----------Only One Expand at a time Ends here-------------------------/////////////////////

        // preparing list data
        prepareListData();

        listAdapter = new ExpandableListAdapter(getContext(), listDataHeader, listDataChild);
        // setting list adapter
        expListView.setAdapter(listAdapter);


        //Send Button OnClick Starts /////////////////////////////////////////////////////////////////
        btn=v.findViewById(R.id.button);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //Sharing Rndom to OnChildView
                SharedPreferences prefd = getContext().getSharedPreferences("my_prefd", MODE_PRIVATE);
                SharedPreferences.Editor editd = prefd.edit();
                editd.putInt("BRNDM", 1857 );
                editd.commit();

                //Taking Group ID (which group was expanded last)
                SharedPreferences phobjb = getContext().getSharedPreferences("my_prefb", 0);
                int grID = phobjb.getInt("GR", 0);

                expListView.collapseGroup(grID);
                expListView.expandGroup(grID);


                new CountDownTimer(1000, 1000) {
                    public void onFinish() {
                        // When timer is finished
                        // Execute your code here
                        //Receiving 1857 of OnClick
                        SharedPreferences phobjc = getContext().getSharedPreferences("noofitems", 0);
                        int j = phobjc.getInt("NoItems", 0);
                        phobjc.edit().clear().commit();

                        for(int i=1;i<=j;i++){
                            //Taking data entered in  ETs
                            SharedPreferences phobja = getContext().getSharedPreferences("my_prefa", 0);
                            String data = phobja.getString("PH"+i, "");
                            Toast.makeText(getContext(),"Recving "+data+"from PH"+i,Toast.LENGTH_SHORT).show();
                        }
                    }

                    public void onTick(long millisUntilFinished) {
                        // millisUntilFinished    The amount of time until finished.
                    }
                }.start();



            }
        });
        //-------On Click of button ends here----------------------////////////
        return v;
    }
    //////----------------OnCreate ends here-----------------------------////////////////





    private void prepareListData() {
        listDataHeader = new ArrayList<String>();
        listDataChild = new HashMap<String, List<String>>();


        if(readFile("filePG1.txt").equals(null)||readFile("filePG1.txt").equals("")){
            //pg.add("No Contacts Present");
        }
        else {
            listDataHeader.add("PG");
            List<String> pg = new ArrayList<String>();

            int j=1;
            int i = Integer.parseInt(readFile(last));

            //Start reading from 1 to "How many files are saved"/////////////////
            while (j <= i) {
                try {
                    FileInputStream fis = getContext().openFileInput("filePG"+ j + ".txt");

                    pg.add(readFile("filePG"+ j + ".txt"));
                    //Add items to listView by reading all saved files/Contacts/////////////

                    int size = fis.available();
                    byte[] buffer = new byte[size];
                    fis.read(buffer);
                    fis.close();
                } catch (Exception e) {
                    //If limit is reached , Break the Loop///////////////////////////
                    break;
                }
                j++;

            }

            listDataChild.put(listDataHeader.get(grtoShow), pg); // Header, Child data
            grtoShow++;


        }


        if(readFile("fileNur1.txt").equals(null)||readFile("fileNur1.txt").equals("")){
            //nur.add("No Contacts Present");
        }
        else {
            listDataHeader.add("Nursery");
            List<String> nur = new ArrayList<String>();

            int j=1;
            int i = Integer.parseInt(readFile(last));

            //Start reading from 1 to "How many files are saved"/////////////////
            while (j <= i) {
                try {
                    FileInputStream fis = getContext().openFileInput("fileNur"+ j + ".txt");
                    nur.add(readFile("fileNur"+ j + ".txt"));
                    //Add items to listView by reading all saved files/Contacts/////////////

                    int size = fis.available();
                    byte[] buffer = new byte[size];
                    fis.read(buffer);
                    fis.close();
                } catch (Exception e) {
                    //If limit is reached , Break the Loop///////////////////////////
                    break;
                }
                j++;

            }
            listDataChild.put(listDataHeader.get(grtoShow), nur);
            grtoShow++;






        }




        if(readFile("filePrep1.txt").equals(null)||readFile("filePrep1.txt").equals("")){
            //prep.add("No Contacts Present");
        }
        else {
            listDataHeader.add("Prep");
            List<String> prep = new ArrayList<String>();
            int j=1;
            int i = Integer.parseInt(readFile(last));

            //Start reading from 1 to "How many files are saved"/////////////////
            while (j <= i) {
                try {
                    FileInputStream fis = getContext().openFileInput("filePrep"+ j + ".txt");
                    prep.add(readFile("filePrep"+ j + ".txt"));
                    //Add items to listView by reading all saved files/Contacts/////////////

                    int size = fis.available();
                    byte[] buffer = new byte[size];
                    fis.read(buffer);
                    fis.close();
                } catch (Exception e) {
                    //If limit is reached , Break the Loop///////////////////////////
                    break;
                }
                j++;

            }
            listDataChild.put(listDataHeader.get(grtoShow), prep);
            grtoShow++;


        }


        if(readFile("fileOne1.txt").equals(null)||readFile("fileOne1.txt").equals("")){
            //one.add("No Contacts Present");
        }
        else {
            listDataHeader.add("One");
            List<String> one = new ArrayList<String>();


            int j=1;
            int i = Integer.parseInt(readFile(last));

            //Start reading from 1 to "How many files are saved"/////////////////
            while (j <= i) {
                try {
                    FileInputStream fis = getContext().openFileInput("fileOne"+ j + ".txt");
                    one.add(readFile("fileOne"+ j + ".txt"));
                    //Add items to listView by reading all saved files/Contacts/////////////

                    int size = fis.available();
                    byte[] buffer = new byte[size];
                    fis.read(buffer);
                    fis.close();
                } catch (Exception e) {
                    //If limit is reached , Break the Loop///////////////////////////
                    break;
                }
                j++;
            }

            listDataChild.put(listDataHeader.get(grtoShow), one);
            grtoShow++;

        }
        if(readFile("fileTwo1.txt").equals(null)||readFile("fileTwo1.txt").equals("")){
            //two.add("No Contacts Present");
        }
        else {
            listDataHeader.add("Two");
            List<String> two = new ArrayList<String>();

            int j=1;
            int i = Integer.parseInt(readFile(last));

            //Start reading from 1 to "How many files are saved"/////////////////
            while (j <= i) {
                try {
                    FileInputStream fis = getContext().openFileInput("fileTwo"+ j + ".txt");
                    two.add(readFile("fileTwo"+ j + ".txt"));
                    //Add items to listView by reading all saved files/Contacts/////////////

                    int size = fis.available();
                    byte[] buffer = new byte[size];
                    fis.read(buffer);
                    fis.close();
                } catch (Exception e) {
                    //If limit is reached , Break the Loop///////////////////////////
                    break;
                }
                j++;
            }
            listDataChild.put(listDataHeader.get(grtoShow), two);
            grtoShow++;

        }
        if(readFile("fileThree1.txt").equals(null)||readFile("fileThree1.txt").equals("")){
            //three.add("No Contacts Present");
        }
        else {

            listDataHeader.add("Three");
            List<String> three = new ArrayList<String>();

            int j=1;
            int i = Integer.parseInt(readFile(last));

            //Start reading from 1 to "How many files are saved"/////////////////
            while (j <= i) {
                try {
                    FileInputStream fis = getContext().openFileInput("fileThree"+ j + ".txt");
                    three.add(readFile("fileThree"+ j + ".txt"));
                    //Add items to listView by reading all saved files/Contacts/////////////

                    int size = fis.available();
                    byte[] buffer = new byte[size];
                    fis.read(buffer);
                    fis.close();
                } catch (Exception e) {
                    //If limit is reached , Break the Loop///////////////////////////
                    break;
                }
                j++;
            }
            listDataChild.put(listDataHeader.get(grtoShow), three);
            grtoShow++;

        }


    }



    public String readFile(String file){
        String text="";
        try {
            FileInputStream fis=getContext().openFileInput(file);
            int size=fis.available();
            byte[] buffer=new byte[size];
            fis.read(buffer);
            fis.close();
            text=new String(buffer);
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return text;
    }

}

Итак, Как ограничить вызов onChildView() только при расширении группы, а не при прокрутке/изменении вида.


person Zubair Younas    schedule 30.11.2017    source источник
comment
I understand why this is happeneing. . Извиняюсь. Не думай так. Я не вижу, чтобы вы упоминали «переработку».   -  person greenapps    schedule 30.11.2017
comment
Что такое переработка, сэр?   -  person Zubair Younas    schedule 30.11.2017
comment
Google для переработки элементов списка.   -  person greenapps    schedule 30.11.2017


Ответы (2)


Проблема в том, что ваш вид перерабатывается, это означает, что Android использует тот же вид, который прокручивается за пределы экрана, и повторно использует его для рисования следующего, к которому вы прокручиваете, поскольку в этот вы написали некоторый текст, используя тот же вид будет иметь тот же текст.

Решение очень простое.

Ваши модели должны отражать данные, которые пользователь вводит в представление. И в любой момент вы должны знать, какой текст есть у каждого ребенка, возможно, используйте TextWatcher.

И для каждого ребенка вы просто делаете следующее.

String text = getTextForThisChild();
if (!TextUtils.isEmpty(text) {
    yourEditText.setText(text); // Sets correct text for view
} else {
    yourEditText.setText(null); // Clears text of recycled view
}

Вам нужно отслеживать изменения текста

edt.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(final CharSequence charSequence, final int i, final int i1, final int i2) {}

        @Override
        public void onTextChanged(final CharSequence charSequence, final int i, final int i1, final int i2) {
          yourModelList.get(childPosition).setText(charSequence);  // This is dummy, you should get the correct model for this child
        }

        @Override
        public void afterTextChanged(final Editable editable) {}
    });

Затем в той же модели, полученной yourModelList.get(childPosition), вы получаете text ту, которую вы проверяете, пуста она или нет.

Пожалуйста, дайте мне знать, если это все еще не ясно

person elmorabea    schedule 30.11.2017
comment
Попробуйте добавить свой код в мой метод getChildView(). Почему, потому что он знает, что является текущим дочерним элементом и какой текст он содержит. Таким образом, это приводит к сбою приложения при вызове getChildView(). Где я могу реализовать это для правильного функционирования? - person Zubair Younas; 30.11.2017
comment
Как вы реализуете getTextForThisChild в своем примере? - person elmorabea; 30.11.2017
comment
@Override public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { edt=convertView.findViewById(R.id.marks); String text = edt.getText().toString(); if (!TextUtils.isEmpty(text)) { edt.setText(text); // Sets correct text for view } else { edt.setText(null); // Clears text of recycled view } } getView уже знает, что такое EditText для этого дочернего элемента. Так что я просто устанавливаю текст в этом методе. - person Zubair Younas; 30.11.2017
comment
text = edt.getText() неверно, вам нужно сохранить значения, введенные в ваших представлениях. см. отредактированный ответ - person elmorabea; 30.11.2017
comment
Уважаемый, я не вижу ответа отредактировано. + Что может быть не так с: text = edt.getText()? - person Zubair Younas; 30.11.2017
comment
Вы говорили о сохранении значений, введенных в настоящее время. Но я не вижу никакого алгоритма сохранения в TextChangedListener. + This is dummy, you should get the correct model for this child Извините, объясните пожалуйста. Что это значит? - person Zubair Younas; 30.11.2017
comment
Пожалуйста, покажите код структуры данных, поддерживающей этот адаптер, какой у вас список/массив, который вы используете для заполнения списка, и я могу помочь вам заполнить его. - person elmorabea; 30.11.2017
comment
Проверьте обновленный вопрос. Пожалуйста, и спасибо за помощь :) - person Zubair Younas; 30.11.2017
comment
Давайте продолжим обсуждение в чате. - person Zubair Younas; 30.11.2017

getView() — это собственный метод Android, его нельзя переопределить. Единственный способ, которым вы пытаетесь достичь, это:

То, что вы пытаетесь сделать, безусловно, возможно, но сложно:

  1. Добавьте кнопку в каждый дочерний элемент
  2. Когда пользователь вводит Child 0, он должен нажать кнопку этого ребенка (при нажатии кнопки сохранить значение в массиве на index[childPosition]). Таким образом, массив [0] будет иметь текст дочернего элемента 1, аналогичный для следующих дочерних элементов.

(Шаг 3 и последующие являются необязательными)

  1. Если вам не нравится этот дизайн (поскольку пользователю нужно нажимать кнопку каждый раз, когда он вводит значение, см. Шаг 4)
  2. Установите для параметра «Видимость» кнопки (добавленной на шаге 1) значение INVISIBLE.
  3. Добавьте TextWatcher (TextChangedListener) для EditText в ChildItem (он получит текст, введенный> Сохранить его в массиве []> Нажмите саму кнопку, как только пользователь покинет текущий EditText). Так как:

    edt.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) {}
    @Override
    public void afterTextChanged(Editable editable) {
    
    if(edt.getText().toString()==""&&edt.getText().toString().equals(null)){
    }
    else {
        edt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus)//Perform Click when edt loses Focus {
                    btn.callOnClick();
                }
            }
        });
    }
    }});
    

    Теперь нажатие кнопки будет выглядеть так:

    btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
            if(edt.getText().toString().equals("")){
    
            }
            else {
            Toast.makeText(view.getContext(),"Entered: "+edt.getText().toString(),Toast.LENGTH_SHORT).show();
            myStringArray[childPosition]=edt.getText().toString();
            edt.setText("");
            }
        }
    });
    
person Zubair Younas    schedule 24.12.2017