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:
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.
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:
(Step 3 and Further are Optional)
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("");
}
}
});