停止自动调用 getView()

stop getView() from getting called automatically

我正在实施 Expandable ListView。每个子项都有一个 Text View 和一个 EditText。

问题是,假设一个群组有 10 个 items/rows。我在第 1 行和第 2 行输入了一个数据。当我向下滚动到第 6 行和第 7 行时。它们已经有一个文本(第 6 行有第 1 行的数据,第 7 行有第 2 行的数据)。

我明白为什么会这样。 这是因为,当我在第 1 行输入时,我当前可以看到第 1 行到第 5 行。当我向下滚动以查看剩余的行时。 getChildView() 被自动调用 来显示剩余的行和它们的数据,因为所有的 editTexts 都有相同的 id。因此,下一个视图与上一个视图具有相同的数据。 这里有类似问题ArrayAdapter's getView() method getting called automatically on load and while scrolling listview 我试过了:

  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 我要在 Lists/Rows 中添加项目的地方:

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() 仅在组展开时调用,而不是在视图为 scrolled/changed.

时调用

问题是您的视图正在被回收,这意味着 Android 使用滚动到屏幕外的相同视图,然后 re-uses 绘制您滚动到的下一个视图,因为这个你写了一些文字,使用相同的视图将有相同的文字。

解决方法很简单。

您应该让您的模型反映用户在视图中输入的数据。在任何时候你都应该知道每个 child 有什么文本,也许使用 TextWatcher.

对于每个 child,您只需执行以下操作。

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 您检查是否为空的模型。

如果还不清楚,请告诉我

getView() 是 Android 自己的方法,您不能覆盖它。 您想要实现的唯一方法是:

您尝试做的事情当然是可能的,但是很复杂:

  1. 在每个 Child 项中添加一个按钮
  2. 当用户输入 Child 0 时,他必须按下 Child 的按钮(单击按钮时,将值保存在索引 [childPosition] 的数组中)。在 这样,Array[0] 将具有 Child 1 的文本,与 Next 类似 Child仁。

(第 3 步和其他步骤是可选的)

  1. 如果您不喜欢这种设计(因为用户每次输入值时都需要按下按钮,请参阅第 4 步)
  2. 将按钮(在步骤 1 中添加)的可见性设置为 INVISIBLE
  3. 为 ChildItem 中的 EditText 添加一个 TextWatcher (TextChangedListener)(它将获取输入的文本 > 将其保存在 Array[] 中 > 在用户离开当前 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("");
            }
        }
    });