Good day!
I'm a newbie at android/java programming and I'm trying to create, kinda like, a history function to my app. I'm using an expandableListView with a gridView (or listView; I don't really know what else to use aside from these two) inside to show said history. All the data comes from sqLite database which has 3 tables named Requests, Properties & ReqLine all linked together.
The format I'm trying to create is something like this (Sorry, cant post images yet):
HEADER: TextView ----- data from db 1st table
CHILD: TextView ----- data from 2nd GRID: 1)item from DB 3rd table 2)item
from DB 3rd table
I was able to populate the header and child portions but I'm having trouble with the child gridView repeating data on every child. I know it's with the way I'm passing the ArrayList to the GridView Adapter but I don't the correct way of doing it or how to implement it.
I tried a bunch of ways including adding another arraylist to my header class model but I don't know how I should get the childcount for it in my adapter.
I've seen lots on posts here in SO but none of them seems to have the solution to my problem. Can anyone help me with this? Thanks in advance! Suggestions on revisions are welcome as well.
Here's my code for the history fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.history_tab_layout, container, false);
openHelper = new DatabaseHelper(getActivity());
myDb = openHelper.getReadableDatabase();
TextView _number = (TextView) rootView.findViewById(R.id.lblNumber);
TextView _date = (TextView) rootView.findViewById(R.id.lblHistoryDate);
TextView _transtype = (TextView) rootView.findViewById(R.id.lblHistoryTransType);
TextView _amount = (TextView) rootView.findViewById(R.id.lblHistoryAmount);
Cursor mCursor = null;
Cursor dataCursor = null;
Cursor itemCursor = null;
String Query = "SELECT * FROM Requests";
mCursor = myDb.rawQuery(Query, null);
transHistory = new ArrayList<HistoryHeader>();
gridHistory = new ArrayList<GridItems>();
int count = 1;
if(mCursor.getCount()!=0) {
while (mCursor.moveToNext()) {
String reqDate = mCursor.getString(mCursor.getColumnIndex("RequestDate"));
String reqTransType = mCursor.getString(mCursor.getColumnIndex("TransType"));
String reqTotalAmt = mCursor.getString(mCursor.getColumnIndex("AmtTotal"));
String reqPCode = mCursor.getString(mCursor.getColumnIndex("Property"));
String BaseId = mCursor.getString(0);
HistoryHeader history = new HistoryHeader(count, reqDate, reqTransType, reqTotalAmt);
String Query2 = "SELECT * FROM Projects WHERE PrjCode = '"+ mCursor.getString(3) +"'";
dataCursor = myDb.rawQuery(Query2, null);
if (dataCursor.getCount()!=0){
while (dataCursor.moveToNext()){
String reqPName = dataCursor.getString(dataCursor.getColumnIndex("PrjName"));
history.setItemList(createItems(reqPCode, reqPName, 1));
}
}
String Query3 = "SELECT * FROM ReqLine WHERE Base_Id = "+ BaseId;
itemCursor = myDb.rawQuery(Query3, null);
if (itemCursor.getCount()!=0) {
while (itemCursor.moveToNext()) {
String reqPurpose = itemCursor.getString(itemCursor.getColumnIndex("Purpose"));
String reqAmount = itemCursor.getString(itemCursor.getColumnIndex("AmtLine"));
Integer reqNum = itemCursor.getInt(itemCursor.getColumnIndex("Linenum"));
GridItems test = new GridItems(reqNum, reqPurpose, reqAmount);
gridHistory.add(test);
}
}
transHistory.add(history);
count++;
}
}
final ExpandableListView _Content = (ExpandableListView) rootView.findViewById(R.id.historyList);
_Content.setIndicatorBounds(5,5);
HistoryAdapter exAdpt = new HistoryAdapter(getActivity(), transHistory, gridHistory);
_Content.setIndicatorBounds(0,20);
_Content.setAdapter(exAdpt);
return rootView;
}
private List<HistoryDetail> createItems(String _strPropertyCode, String _strPropertyName, int num) {
List<HistoryDetail> result = new ArrayList<HistoryDetail>();
for (int i=0; i < num; i++) {
HistoryDetail item = new HistoryDetail(i, _strPropertyCode, _strPropertyName);
result.add(item);
}
return result;
}
And the Code for my HistoryAdapter.java
public class HistoryAdapter extends BaseExpandableListAdapter {
private Context context;
private List<HistoryHeader> _listDataHeader;
private ArrayList<GridItems> _listGridItems;
public HistoryAdapter(Context context, List<HistoryHeader> _listDataHeader, ArrayList<GridItems> _listGridItems) {
this.context = context;
this._listDataHeader = _listDataHeader;
this._listGridItems = _listGridItems;
}
#Override
public int getGroupCount() {
return _listDataHeader.size();
}
#Override
public int getChildrenCount(int groupPosition) {
/*Integer size = _listDataHeader.get(groupPosition).getItemList().size();
return size;*/
return 1;
}
#Override
public Object getGroup(int groupPosition) {
return _listDataHeader.get(groupPosition);
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return _listDataHeader.get(groupPosition).getItemList().get(childPosition);
}
#Override
public long getGroupId(int groupPosition) {
return _listDataHeader.get(groupPosition).hashCode();
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return _listDataHeader.get(groupPosition).getItemList().get(childPosition).hashCode();
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup viewGroup) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.history_list_group, null);
}
TextView groupNum = (TextView) v.findViewById(R.id.historyNumber);
TextView groupDate = (TextView) v.findViewById(R.id.historyDate);
TextView groupTransType = (TextView) v.findViewById(R.id.historyTransType);
TextView groupAmount = (TextView) v.findViewById(R.id.historyTotalAmt);
HistoryHeader header = _listDataHeader.get(groupPosition);
groupNum.setText(String.valueOf(header.getId()));
groupDate.setText(header.getDate());
groupTransType.setText(header.getTransType());
groupAmount.setText(header.getTotalAmt());
return v;
}
#Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup viewGroup) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.history_list_child, null);
}
TextView itemPropCode = (TextView) v.findViewById(R.id.historyPropertyCode);
TextView itemPropName = (TextView) v.findViewById(R.id.historyPropertyName);
GridView itemGrid = (GridView) v.findViewById(R.id.historyItemList);
ItemGridAdapter adapter = new ItemGridAdapter(context,_listGridItems);
itemGrid.setAdapter(adapter);
HistoryDetail detail = _listDataHeader.get(groupPosition).getItemList().get(childPosition);
itemPropCode.setText(detail.getPropertyCode());
itemPropName.setText(detail.getPropertyName());
return v;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
Then the ItemGridAdapter.java
public class ItemGridAdapter extends BaseAdapter {
Context context;
ArrayList<GridItems> itemList;
public ItemGridAdapter(Context context, ArrayList<GridItems> itemList) {
this.context = context;
this.itemList = itemList;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return itemList.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.history_grid_layout, null);
}
TextView _rowPurpose = (TextView) convertView.findViewById(R.id.rowPurpose);
TextView _rowAmount = (TextView) convertView.findViewById(R.id.rowAmount);
GridItems gridItems = itemList.get(position);
_rowPurpose.setText(gridItems.getPurpose());
_rowAmount.setText(gridItems.getAmount());
return convertView;
}
#Override
public boolean areAllItemsEnabled() {
return false;
}
#Override
public boolean isEnabled(int position) {
// Return true for clickable, false for not
return false;
}
Model Classes
public class HistoryHeader implements Serializable {
private long id;
private String _strDate;
private String _strTransType;
private String _strTotalAmt;
private List<HistoryDetail> itemDetails = new ArrayList<HistoryDetail>();
private List<GridItems> itemGrid = new ArrayList<>();
public HistoryHeader(long id, String _strDate, String _strTransType, String _strTotalAmt) {
this.id = id;
this._strDate = _strDate;
this._strTransType = _strTransType;
this._strTotalAmt = _strTotalAmt;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getDate() {
return _strDate;
}
public void setDate(String _strDate) {
this._strDate = _strDate;
}
public String getTransType() {
return _strTransType;
}
public void setTransType(String _strTransType) {
this._strTransType = _strTransType;
}
public String getTotalAmt() {
return _strTotalAmt;
}
public void setTotalAmt(String _strTotalAmt) {
this._strTotalAmt = _strTotalAmt;
}
public List<HistoryDetail> getItemList() {
return itemDetails;
}
public void setItemList(List<HistoryDetail> itemDetails) {
this.itemDetails = itemDetails;
}
public List<GridItems> getItemGrid(){ return itemGrid; }
public void setItemGrid(List<GridItems> itemGrid) { this.itemGrid = itemGrid; }
public class GridItems {
private long id;
private String _strPurpose, _strAmount;
public GridItems(long id, String _strPurpose, String _strAmount) {
this.id = id;
this._strPurpose = _strPurpose;
this._strAmount = _strAmount;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getPurpose() {
return _strPurpose;
}
public void setPurpose(String _strPurpose) {
this._strPurpose = _strPurpose;
}
public String getAmount() {
return _strAmount;
}
public void setAmount(String _strAmount) {
this._strAmount = _strAmount;
}
Try this:
Cursor mCursor = null;
Cursor dataCursor = null;
Cursor itemCursor = null;
String Query = "SELECT * FROM Requests";
mCursor = myDb.rawQuery(Query, null);
transHistory = new ArrayList<HistoryHeader>();
//allGridHistory = new ArrayList<ArrayList<GridItems>>(); // Changed2
//gridHistory = new ArrayList<GridItems>();
int count = 1;
if(mCursor.getCount()!=0) {
while (mCursor.moveToNext()) {
String reqDate = mCursor.getString(mCursor.getColumnIndex("RequestDate"));
String reqTransType = mCursor.getString(mCursor.getColumnIndex("TransType"));
String reqTotalAmt = mCursor.getString(mCursor.getColumnIndex("AmtTotal"));
String reqPCode = mCursor.getString(mCursor.getColumnIndex("Property"));
String BaseId = mCursor.getString(0);
HistoryHeader history = new HistoryHeader(count, reqDate, reqTransType, reqTotalAmt);
String Query2 = "SELECT * FROM Projects WHERE PrjCode = '"+ mCursor.getString(3) +"'";
dataCursor = myDb.rawQuery(Query2, null);
if (dataCursor.getCount()!=0){
while (dataCursor.moveToNext()){
String reqPName = dataCursor.getString(dataCursor.getColumnIndex("PrjName"));
history.setItemList(createItems(reqPCode, reqPName, 1));
}
}
String Query3 = "SELECT * FROM ReqLine WHERE Base_Id = "+ BaseId;
itemCursor = myDb.rawQuery(Query3, null);
if (itemCursor.getCount()!=0) {
gridHistory = new ArrayList<GridItems>(); // Added
while (itemCursor.moveToNext()) {
String reqPurpose = itemCursor.getString(itemCursor.getColumnIndex("Purpose"));
String reqAmount = itemCursor.getString(itemCursor.getColumnIndex("AmtLine"));
Integer reqNum = itemCursor.getInt(itemCursor.getColumnIndex("Linenum"));
GridItems test = new GridItems(reqNum, reqPurpose, reqAmount);
gridHistory.add(test);
}
history.setItemGrid(gridHistory); // Changed2
}
transHistory.add(history);
count++;
}
}
final ExpandableListView _Content = (ExpandableListView) rootView.findViewById(R.id.historyList);
_Content.setIndicatorBounds(5,5);
HistoryAdapter exAdpt = new HistoryAdapter(getActivity(), transHistory); // Changed2
The adapter:
public class HistoryAdapter extends BaseExpandableListAdapter {
private Context context;
private List<HistoryHeader> _listDataHeader;
//private ArrayList<GridItems> _listGridItems;
public HistoryAdapter(Context context, List<HistoryHeader> _listDataHeader) {
this.context = context;
this._listDataHeader = _listDataHeader;
//this._listGridItems = _listGridItems;
}
#Override
public int getGroupCount() {
return _listDataHeader.size();
}
#Override
public int getChildrenCount(int groupPosition) {
/*Integer size = _listDataHeader.get(groupPosition).getItemList().size();
return size;*/
return 1;
}
#Override
public HistoryHeader getGroup(int groupPosition) {
return _listDataHeader.get(groupPosition);
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return _listDataHeader.get(groupPosition).getItemList().get(childPosition);
}
#Override
public long getGroupId(int groupPosition) {
return _listDataHeader.get(groupPosition).hashCode();
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return _listDataHeader.get(groupPosition).getItemList().get(childPosition).hashCode();
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup viewGroup) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.history_list_group, null);
}
TextView groupNum = (TextView) v.findViewById(R.id.historyNumber);
TextView groupDate = (TextView) v.findViewById(R.id.historyDate);
TextView groupTransType = (TextView) v.findViewById(R.id.historyTransType);
TextView groupAmount = (TextView) v.findViewById(R.id.historyTotalAmt);
HistoryHeader header = _listDataHeader.get(groupPosition);
groupNum.setText(String.valueOf(header.getId()));
groupDate.setText(header.getDate());
groupTransType.setText(header.getTransType());
groupAmount.setText(header.getTotalAmt());
return v;
}
#Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup viewGroup) {
View v = convertView;
// As for using grid view, there is only one child, no suitable view for reuse/recycle.
//if (v == null) {
LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.history_list_child, null);
//}
TextView itemPropCode = (TextView) v.findViewById(R.id.historyPropertyCode);
TextView itemPropName = (TextView) v.findViewById(R.id.historyPropertyName);
GridView itemGrid = (GridView) v.findViewById(R.id.historyItemList);
// Get the child list of this group/header.
List<GridItems> history_list_child = getGroup(groupPosition).getItemGrid();
// As for using grid view, onChildClickListener cannot be used. You may need to pass the group/header object
// to grid view adapter and do onClick inside getView. First try your original way to display data correctly.
ItemGridAdapter adapter = new ItemGridAdapter(context, history_list_child);
itemGrid.setAdapter(adapter);
HistoryDetail detail = _listDataHeader.get(groupPosition).getItemList().get(childPosition);
itemPropCode.setText(detail.getPropertyCode());
itemPropName.setText(detail.getPropertyName());
return v;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
Hope that helps!
Related
I have Expandable List View in my app with is hardcoded. After getting to know Firebase database i want to add inside child item information from my database. I copyed code and node from here android expandable listview retrieve data from firebase and it worked perfectly fine. Here is the result:
My main Firebase node look like this:
How can i display data from my node? All information stored inside "campus", building and faculties are should be parent item. Building1 and Building2, same goes to faculty item, should be child items. How can i achieve my goal? Here is my Java code:
public class campus extends AppCompatActivity {
CampusAdapter campusAdapter;
List<String> listDataHeader;
HashMap<String, List<String>> listDataChild;
FirebaseDatabase database;
DatabaseReference myRef;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_campus);
database = FirebaseDatabase.getInstance();
myRef = database.getReference("campus");
expandableListView = findViewById(R.id.campusExpandableListView);
SetStandardGroups();
campusAdapter = new CampusAdapter(this, listDataHeader, listDataChild);
expandableListView.setAdapter(campusAdapter);
}
public void SetStandardGroups() {
listDataHeader = new ArrayList<>();
listDataChild = new HashMap<>();
myRef.addChildEventListener(new ChildEventListener() {
int counter = 0;
List<String> childItem;
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
listDataHeader.add(dataSnapshot.getKey());
Log.e("TAG", listDataHeader.get(counter));
childItem = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String childNames = (String) ds.getValue();
Log.e("TAG", "childNames :" + childNames);
childItem.add(childNames);
}
listDataChild.put(listDataHeader.get(counter), childItem);
counter++;
Log.e("TAG", "counter :" + counter);
campusAdapter.notifyDataSetChanged();
}
});
}
Here is my Adapter java file:
public class CampusAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> headerItem;
private HashMap<String, List<String>> childItem;
public CampusAdapter(Context context, List<String> headerItem, HashMap<String, List<String>> childItem) {
this.context = context;
this.headerItem = headerItem;
this.childItem = childItem;
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return childItem.get(headerItem.get(groupPosition)).get(childPosition);
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
String childText = (String) getChild(groupPosition, childPosition);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.child_item, null);
}
TextView tv = convertView.findViewById(R.id.campusName);
tv.setText(childText);
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
return childItem.get(headerItem.get(groupPosition)).size();
}
#Override
public Object getGroup(int groupPosition) {
return headerItem.get(groupPosition);
}
#Override
public int getGroupCount() {
return headerItem.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 inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.group_item, null);
}
TextView tv = convertView.findViewById(R.id.groupName);
tv.setText(headerTitle);
return convertView;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
p.s i use Glide to display images
This goes in your onCreate() of the main class (the one with the listView)
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("(campus/building");
reference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot ds:snapshot.getChildren()){
String title = ds.child("title").getValue(String.class);
String image = ds.child("image").getValue(String.class);
//TODO: add it to the expandable view with the link above who explains it
ExpandableListView myExpList= (ExpandableListView) this.view.findViewById(R.id.yourExpListView);
ExpandableListAdapter adapter =
(ExpandableListAdapter) myExpList.getExpandableListAdapter();
( (ExpandableListParentClass)adapter.getMParent().get(0) ).getParentChildren().add(title);
( (ExpandableListParentClass)adapter.getMParent().get(0) ).getParentChildren().add(image);
//(change to get(0) which you parent want to get )
adapter.notifyDataSetChanged();
adapter.notifyDataSetInvalidated();
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
})
Then create a new java class called "ExpandableListAdapter" with following code:
public class ExpandableListAdapter extends BaseExpandableListAdapter implements Filterable{
private LayoutInflater inflater;
private ArrayList<ExpandableListParentClass<Object>> mParent;
private View view;
public ArrayList<Object> getMParent() {
return mParent;
}
public ExpandableListAdapter(Context context,
ArrayList<ExpandableListParentClass<Object>> parentList ) {
this.mParent = parentList;
this.inflater = LayoutInflater.from(context);
}
// counts the number of group/parent items so the list knows how many
// times calls getGroupView() method
public int getGroupCount() {
return mParent.size();
}
// counts the number of children items so the list knows how many times
// calls getChildView() method
public int getChildrenCount(int parentPosition) {
int size =0;
if(mParent.get(parentPosition).getParentChildren() != null){
size = mParent.get(parentPosition).getParentChildren().size();
}
return size;
}
// gets the title of each parent/group
public Object getGroup(int i) {
return mParent.get(i).getParent();
}
// gets the name of each item
public Object getChild(int parentPosition, int childPosition) {
return mParent.get(parentPosition).getParentChildren().get(childPosition);
}
public long getGroupId(int parentPosition) {
return parentPosition;
}
public long getChildId(int i, int childPosition) {
return childPosition;
}
public boolean hasStableIds() {
return true;
}
// in this method you must set the text to see the parent/group on the list
public View getGroupView(int parentPosition, boolean b, View view, ViewGroup viewGroup) {
if (view == null) {
view = inflater.inflate(R.layout.layout_listview, viewGroup, false);
}
return view;
}
// in this method you must set the text to see the children on the list
public View getChildView(int parentPosition, int childPosition, boolean b, View view, ViewGroup viewGroup) {
if (view == null) {
view = inflater.inflate(R.layout.layout_listview, viewGroup, false);
}
// return the entire view
return view;
}
public boolean isChildSelectable(int i, int i1) {
return true;
}
}
List<ExpandableListParentClass> arrayParents = new ArrayList<ExpandableListParentClass>();
ExpandableListParentClass item = new ExpandableListParentClass();
item.setParent(yourParentItem);
item.setParentChildren( yourChildList);
Then create a new java class called "ExpandableListParentClass" with the following code:
public class ExpandableListParentClass{
private Object parent;
private ArrayList<Object> parentChildren;
public ExpandableListParentClass() {
}
public ExpandableListParentClass(Object parent, ArrayList<Object> parentChildren) {
this.parent = parent;
this.parentChildren = parentChildren;
}
public Object getParent() {
return parent;
}
public void setParent(Object parent) {
this.parent = parent;
}
public ArrayList<Object> getParentChildren() {
return parentChildren;
}
public void setParentChildren(ArrayList<Object> parentChildren) {
this.parentChildren = parentChildren;
}
}
On each row i have two EditTexts.when i change the first one , i want the other to be changed as well(if needed ,for now just setting there '25' for testing).I am using a viewholder pattern,and setting on each of the first edittexts a TextChangedListener,expecting the second to be changed as well .problem is , whenever i change ANY of the first edittexts on ANY of the rows ,only the edittext on the last row is changed. here is the code of the adapter(listener is in getgroupview):
public class CustomExpandableListAdapterNewWorkout extends BaseExpandableListAdapter {
private Context context;
private List<String> expandableListTitle;
private HashMap<String, List<String>> expandableListDetail;
private ChildViewHolder childViewHolder;
private GroupViewHolder groupViewHolder;
public CustomExpandableListAdapterNewWorkout(Context context, List<String> expandableListTitle,
HashMap<String, List<String>> expandableListDetail) {
this.context = context;
this.expandableListTitle = expandableListTitle;
this.expandableListDetail = expandableListDetail;
}
#Override
public Object getChild(int listPosition, int expandedListPosition) {
return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
.get(expandedListPosition);
}
#Override
public long getChildId(int listPosition, int expandedListPosition) {
return expandedListPosition;
}
#Override
public View getChildView(int listPosition, final int expandedListPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final String expandedListText = (String) getChild(listPosition, expandedListPosition);
String categoryName= (String)getGroup(listPosition);
if (convertView == null)
{
LayoutInflater layoutInflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list_item_exercises_exercise, null);
childViewHolder = new ChildViewHolder();
childViewHolder.mChildTitle = (TextView) convertView.findViewById(R.id.expandedListItem);
childViewHolder.mChildImage = (ImageView) convertView.findViewById(R.id.ImgExercisePic);
convertView.setTag(childViewHolder);
}
else
{
childViewHolder = (ChildViewHolder) convertView.getTag();
}
childViewHolder.mChildTitle.setText(expandedListText);
childViewHolder.mChildTitle.setTextAppearance(context,R.style.TitleStyle);
return convertView;
}
#Override
public int getChildrenCount(int listPosition) {
return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
.size();
}
#Override
public Object getGroup(int listPosition) {
return this.expandableListTitle.get(listPosition);
}
#Override
public int getGroupCount() {
return this.expandableListTitle.size();
}
#Override
public long getGroupId(int listPosition) {
return listPosition;
}
#Override
public View getGroupView(int listPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String listTitle = (String) getGroup(listPosition);
if (convertView == null)
{
LayoutInflater layoutInflater = (LayoutInflater) this.context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list_group_new_workout_exercise, null);
groupViewHolder = new GroupViewHolder();
groupViewHolder.mGroupTitle = (TextView) convertView.findViewById(R.id.exerciseName);
groupViewHolder.mMinSets = (EditText) convertView.findViewById(R.id.edtMinimumSets);
groupViewHolder.mMaxSets = (EditText) convertView.findViewById(R.id.edtMaxSets);
groupViewHolder.mMinSets.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) {
groupViewHolder.mMaxSets.setText("25");
}
});
convertView.setTag(groupViewHolder);
}
else
{
groupViewHolder = (GroupViewHolder) convertView.getTag();
}
groupViewHolder.mGroupTitle.setText(listTitle);
return convertView;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isChildSelectable(int listPosition, int expandedListPosition) {
return true;
}
public final class GroupViewHolder {
TextView mGroupTitle;
EditText mMinSets;
EditText mMaxSets;
}
public final class ChildViewHolder {
TextView mChildTitle;
ImageView mChildImage;
}
}
probably there is something basic i don't understand about adapters and viewholders, and i would like to know the correct method to address it.
ok my bad.
should have declared "GroupViewHolder groupViewHolder" inside the getGroupView method,this way a new one with a new listener is created each time and affects his corresponding row
I want to show the count and all the data when clicked. But so far in testing using click on the Parent item
I tried increment checkedCount when check. But it show only checked count in in one group child elemements.
My Adapter:
public class RubExpandAdapter extends BaseExpandableListAdapter {
private Context context;
private List<RubricsModel> rubrics;
private List<VacancyModel> listForRubricListView;
private List<VacancyModel> listForSubRubricListView;
private HashMap<Integer, boolean[]> mChildCheckStates;
public static int rubricPage = 1;
public static int rubricId;
public static int subRubricPage = 1;
public static int subRubricId;
int checkedCount;
FragmentManager fm;
public RubExpandAdapter(Context context, ArrayList<RubricsModel> rubrics, FragmentManager fragmentManager) {
this.context = context;
this.rubrics = rubrics;
fm = fragmentManager;
listForRubricListView = new ArrayList<>();
mChildCheckStates = new HashMap<>();
}
#Override
public Object getChild(int groupPosition, int childPosition) {
ArrayList<SubRubricsModel> chList = rubrics.get(groupPosition)
.getItems();
return chList.get(childPosition);
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final int mGroupPosition = groupPosition;
final int mChildPosition = childPosition;
SubRubricsModel subRubricsModel = (SubRubricsModel) getChild(groupPosition,
childPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) context
.getSystemService(context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.rubrics_child_row_layout, null);
}
final CheckBox checkBox = (CheckBox) convertView.findViewById(R.id.checkBox);
TextView tv = (TextView) convertView.findViewById(R.id.tvsubrubricsfr);
tv.setText(subRubricsModel.getSubRubricName());
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkBox.setChecked(!checkBox.isChecked());
}
});
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
boolean getChecked[] = mChildCheckStates.get(mGroupPosition);
getChecked[mChildPosition] = isChecked;
mChildCheckStates.put(mGroupPosition, getChecked);
} else {
boolean getChecked[] = mChildCheckStates.get(mGroupPosition);
getChecked[mChildPosition] = isChecked;
mChildCheckStates.put(mGroupPosition, getChecked);
}
for (int i = 0; i < mChildCheckStates.size(); i++){
if (mChildCheckStates.containsValue(true)){
checkedCount ++;
}
}
}
});
if (mChildCheckStates.containsKey(mGroupPosition)) {
boolean getChecked[] = mChildCheckStates.get(mGroupPosition);
checkBox.setChecked(getChecked[mChildPosition]);
} else {
boolean getChecked[] = new boolean[getChildrenCount(mGroupPosition)];
mChildCheckStates.put(mGroupPosition, getChecked);
checkBox.setChecked(false);
}
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
ArrayList<SubRubricsModel> chList = rubrics.get(groupPosition)
.getItems();
return chList.size();
}
#Override
public Object getGroup(int groupPosition) {
return rubrics.get(groupPosition);
}
#Override
public int getGroupCount() {
return rubrics.size();
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
final RubricsModel rubricsModel = (RubricsModel) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater inf = (LayoutInflater) context
.getSystemService(context.LAYOUT_INFLATER_SERVICE);
convertView = inf.inflate(R.layout.rubrics_group_row_layout, null);
}
TextView tv = (TextView) convertView.findViewById(R.id.tvrubricsfr);
tv.setText(rubricsModel.getRubricName());
ImageView indicator = (ImageView) convertView.findViewById(R.id.ivGroupIndicator);
if (isExpanded) {
indicator.setImageResource(R.drawable.arrow_down);
} else {
indicator.setImageResource(R.drawable.arrow_right);
}
tv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// RubFragment.searchByRubrics = true;
// rubricId = rubricsModel.getRubricID();
// searchByRubric(String.valueOf(rubricId));
Toast.makeText(context, String.valueOf(mChildCheckStates.size()), Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
}
how to do, tell me, pls?
I am trying to create an android application using a database from Parse.com. I am using a custom adapter to create a listview. I don't find any errors with the code and yet the listeview is not showing up. Nothing there in the logcat as well. Just the listview does not show up.
lv = (ListView)findViewById(R.id.listView);
mProgress = (ProgressBar)findViewById(R.id.check_progress);
mProgress.setVisibility(View.VISIBLE);
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("Sellers");
query.orderByAscending("Name");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> parseObjects, ParseException e) {
if (e == null) {
studentsList = new ArrayList<Sellers>();
for (ParseObject ob : parseObjects) {
s = new Sellers();
s.setName(ob.getString("Name").toString());
s.setAddress1(ob.getString("Address1").toString());
s.setAddress2(ob.getString("Address2").toString());
s.setShopName(ob.getString("ShopName").toString());
s.setEmail(ob.getString("Email").toString());
s.setPhone(ob.getString("Phone").toString());
s.setZipcode(ob.getString("Zipcode").toString());
studentsList.add(s);
}
adapter = new ListviewAdapter(CheckStatus.this, studentsList);
lv.setAdapter(adapter);
mProgress.setVisibility(View.GONE);
} else {
mProgress.setVisibility(View.GONE);
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
This is the activity where I am invoking the listview.
public class ListviewAdapter extends BaseAdapter{
private final static String TAG = ListviewAdapter.class.getSimpleName();
private Context activity;
private LayoutInflater inflater = null;
private List<Sellers> sellers;
int layout;
public ListviewAdapter(Context activity, List<Sellers> sellers) {
this.activity = activity;
this.sellers = sellers;
inflater = LayoutInflater.from(activity);
}
#Override
public int getCount() {
return 0;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
public class ViewHolder {
TextView name ;
TextView shop ;
TextView address1 ;
TextView address2;
TextView phone;
TextView email;
RelativeLayout rl;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
View v =view;
ViewHolder holder = new ViewHolder();
if (view == null) {
LayoutInflater li = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = li.inflate(R.layout.list_item_layout,null);
holder.name = (TextView)v.findViewById(R.id.seller_name);
holder.shop = (TextView)v.findViewById(R.id.shop_name);
holder.address1 = (TextView)v.findViewById(R.id.address1);
holder.address2 = (TextView)v.findViewById(R.id.address2);
holder.phone = (TextView)v.findViewById(R.id.phone);
holder.email = (TextView)v.findViewById(R.id.emailID);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
Sellers s = sellers.get(position);
// String a = s.Name;
// Log.d(TAG, a);
holder.name.setText(s.getName());
holder.shop.setText(s.getShopName());
holder.address1.setText(s.getAddress1());
holder.address2.setText(s.getAddress2());
holder.phone.setText(s.getPhone());
holder.email.setText(s.getEmail());
Log.d("CustomAdapter.class", "CustomAdapter");
// imageView.setImageDrawable(s.getPic());
return v;
}
}
And this is the custom adapter. There are no null pointer exceptions showing up in the logcat. I can't determine why the listview is not getting populated.
Try this;
#Override
public int getCount() {
return sellers.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position:
}
You have to implement your code on getCount() by return number of item listview will be created.
When end items in a ListView, i upload new, and after update adapter:
ListView lvMain = (ListView) findViewById(R.id.list);
boxAdapter = null;
boxAdapter = new BoxAdapter(this, products);
lvMain.setAdapter(boxAdapter);
But after this, elements are loaded but the scroll position the top. Ie the position of ListView is lost, and look again at the beginning of all
How fix it?
BoxAdapter code:
public class BoxAdapter extends BaseAdapter {
private final Context ctx;
private final LayoutInflater lInflater;
private final ArrayList<ItemInfo> objects;
private final int loadCount = 10;
private int count = 10;
private String name, desc;
BoxAdapter(Context context, ArrayList<ItemInfo> products) {
this.ctx = context;
this.objects = products;
this.lInflater = (LayoutInflater) ctx
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
// кол-во элементов
#Override
public int getCount() {
//return objects.size();
return this.count;
}
// элемент по позиции
#Override
public ItemInfo getItem(int position) {
return objects.get(position);
}
// id по позиции
#Override
public long getItemId(int position) {
return position;
}
public void loadAdditionalItems() {
this.count += this.loadCount;
if (this.count > this.objects.size()) {
this.count = this.objects.size();
}
notifyDataSetChanged();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
view = lInflater.inflate(R.layout.item, parent, false);
ItemInfo p = getItem(position);
TextView desc_id = (TextView) view.findViewById(R.id.desc);
if (p.username.contains("null"))
{
name = "Автор: Неизвестен";
}
else
{
name = "Автор: " + p.username;
}
if(!p.description.contains("null"))
{
desc = p.description.replaceAll("<br />", "");
desc = desc.replaceAll(""", "");
}
else
{
desc = "";
desc_id.setVisibility(View.GONE);
}
((TextView) view.findViewById(R.id.name)).setText(name);
((TextView) view.findViewById(R.id.desc)).setText(desc);
return view;
}
}
P.S setOnScrollListener code:
lvMain.setOnScrollListener(new OnScrollListener()
{
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
ListView lvMain = (ListView) findViewById(R.id.list);
if(firstVisibleItem + visibleItemCount >= totalItemCount) {
boxAdapter.loadAdditionalItems();
loading = false;
}
if (!loading && (lvMain.getLastVisiblePosition() + 10) >= (60))
{
new LoadLastestPost().execute();
loading = true;
}
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
}
});
The best solution would be to create a setProducts method in your boxAdapter and then just call boxAdapter.notifyDataSetChanged(). For example:
boxAdapter.setProducts(products);
boxAdapter.notifyDataSetChanged();
If you implement this method, there is no need to call lvMain.setAdapter(boxAdapter) more than once.
To add the setProducts() method to your adapter:
public BoxAdapter extends BaseAdapter {
Context mContext;
ArrayList<ItemInfo> objects;
public BoxAdapter(Context context, ArrayList<ItemInfo> products) {
mContext = context;
objects = products;
}
public View getView(int position, View convertView, ViewGroup parent) {
// inflate and adjust view
}
public int getCount() {
return objects.size();
}
public Object getItem(int position) {
return objects.get(position);
}
public void setProducts(ArrayList<ItemInfo> newData) {
objects = newData;
}
}
Also, I wouldn't use a count variable. I would just use the size method in the ArrayList. I would remove count altogether.