androidlistviewexpandablelistviewexpandablelistadaptergetview

stop getView() from getting called automatically


I'm implementing Expandable ListView. Each child item has a Text View and an EditText.

The problem is, Suppose a Group has 10 items/rows. I entered a data in row 1 and 2. When I scroll down to row 6 and 7. They already have a text (Row 6 has data of row 1 and Row 7 has data of Row 2).

I understand why this is happeneing. This is because, When I'm typing in row 1, I can currenlty see row 1 to row 5. When I scroll down to view the remaining rows. getChildView() is called automatically to show me remaining rows and thier data, As all editTexts have same id. So, Next View has same data as in previous view. Similar problem here: ArrayAdapter's getView() method getting called automatically on load and while scrolling listview I tried:

  1. his solution, It doesn't work.
  2. setting the getChildCount() manually: No Success

Here is my 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;
    }

}

Here is Tab1.Java where I'm adding items in 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;
    }

}

So, How Do I restrict onChildView() to be called only when a group is expanded, Not when View is scrolled/changed.


Solution

  • The getView() is Android's Own Method, You cannot Override it. The Only way what you are trying to acheive is:

    The Thing you are Trying to do is Certainly Possible, But Complex:

    1. Add A Button in Every Child Item
    2. When User types in Child 0, He Must Press that Child's Button (on Button Click, Save the value in array on index[childPosition]). In this Way, Array[0] will have text of Child 1, Similar for Next Children.

    (Step 3 and Further are Optional)

    1. If You Don't like this Design (as User needs to press button every time he enters a value, Refer to Step 4)
    2. Set the Visibility of the Button(which was added in Step 1) to INVISIBLE
    3. Add a TextWatcher (TextChangedListener) for EditText in ChildItem (It will getText entered > Save it in Array[] > Click the Button itself as Soon as User leaves the Current EditText). As:

      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();
                  }
              }
          });
      }
      }});
      

      Now the Button Click will be like:

      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("");
              }
          }
      });