Been stucked at here more than a week but still unable to solve! I have an expandable listView where the data were retrieved from SQLite and set to expListAdapter. Once the arrow clicked, it will display two child items.
AddMonthlyExpenses
public class AddMonthlyExpenses extends AppCompatActivity {
ArrayList<ListObj> groupList= new ArrayList<ListObj>();;
List<String> childList;
Map<ListObj, List<String>> laptopCollection;
ExpandableListView listview;
ExpandableListAdapter expListAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_monthly_expenses);
laptopCollection = new LinkedHashMap<ListObj, List<String>>();
listview = (ExpandableListView) findViewById(R.id.exlistView);
expListAdapter = new ExpandableListAdapter(getApplication(), groupList, laptopCollection);
listview.setAdapter(expListAdapter);
retrieveList(name);
}
public void retrieveList(String name) {
database = mdb.getReadableDatabase();
Cursor cursor = database.rawQuery("SELECT * FROM " + MyDatabaseHelper.TABLE__TASK + " WHERE Name = ? ", new String[]{name}, null);
if (cursor != null && cursor.getCount() > 0) {
while (cursor.moveToNext()) {
groupList = new ArrayList<ListObj>();
int iD = cursor.getInt(cursor.getColumnIndex("ID"));
String month = cursor.getString(cursor.getColumnIndex("Month"));
double budget = cursor.getDouble(cursor.getColumnIndex("Budget"));
groupList.add(new ListObj(iD,month,budget));
if (expListAdapter != null) {
expListAdapter.add(iD, month, budget);
createCollection(); // for child items
listview.setAdapter(expListAdapter);
}
}
}
}
private void createCollection() {
String[] options = {"Edit","Delete"};
for (ListObj laptop : groupList) {
loadChild(options);
laptopCollection.put(laptop, childList);
}
}
private void loadChild(String[] laptopModels) {
childList = new ArrayList<String>();
for (String model : laptopModels)
childList.add(model);
}
}
ExpandableListAdapter
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context context;
Map<ListObj, List<String>> laptopCollections;
private ArrayList<ListObj> laptops;
double used = 0;
private LayoutInflater mInflater;
public ExpandableListAdapter(Context context, ArrayList<ListObj> laptops, Map<ListObj, List<String>> laptopCollections) {
this.context = context;
this.laptopCollections = laptopCollections;
this.laptops = laptops;
mInflater = LayoutInflater.from(context);
}
public Object getChild(int groupPosition, int childPosition) { // error line
if (laptopCollections.get(laptops.get(groupPosition)).get(childPosition) != null && !laptopCollections.get(laptops.get(groupPosition)).get(childPosition).isEmpty()) {
return laptopCollections.get(laptops.get(groupPosition)).get(childPosition);
}
return 1;
}
public void add(int id, String month, double budget) {
String[] splited = month.split("\\s+");
ListObj obj = new ListObj(id, month, budget);
obj.setYear(splited[1]);
obj.setMonth(splited[0]);
obj.setBudget(budget);
obj.setID(id);
laptops.add(obj);
this.notifyDataSetChanged();
}
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
public int getCount() {
return laptops.size();
}
public ListObj getItem(int position) {
return laptops.get(position);
}
public View getChildView(final int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final String laptop = (String) getChild(groupPosition, childPosition); // here the error line
if (convertView == null) {
convertView = inflater.inflate(R.layout.child_item, null);
}
TextView edit = (TextView) convertView.findViewById(R.id.textEdit);
edit.setText(laptop);
return convertView;
}
public int getChildrenCount(int groupPosition) {
if (laptopCollections.get(laptops.get(groupPosition)) != null && ! laptopCollections.get(laptops.get(groupPosition)).isEmpty()) {
return laptopCollections.get(laptops.get(groupPosition)).size();
}
return 1;
}
public Object getGroup(int groupPosition) {
return laptops.get(groupPosition);
}
public int getGroupCount() {
return this.laptops.size();
}
public long getGroupId(int groupPosition) {
return groupPosition;
}
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
ExpensesAdapter.ViewHolder holder = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.expenses_adapter, null);
holder = new ExpensesAdapter.ViewHolder();
holder.month = (TextView) convertView.findViewById(R.id.textMonth);
holder.budget = (TextView) convertView.findViewById(R.id.textAmount);
holder.year = (TextView) convertView.findViewById(R.id.textYear);
convertView.setTag(holder);
} else {
holder = (ExpensesAdapter.ViewHolder) convertView.getTag();
}
holder.month.setText(laptops.get(groupPosition).getMonth());
holder.budget.setText(String.format("%.2f", laptops.get(groupPosition).getBudget()));
holder.year.setText(laptops.get(groupPosition).getYear());
return convertView;
}
public boolean hasStableIds() {
return true;
}
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
Error
10-26 00:03:57.114 23612-23612/com.example.tony.monthlyexpenses
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException
at
com.example.tony.monthlyexpenses.adapter.ExpandableListAdapter.getChild(ExpandableListAdapter.java:42)
at
com.example.tony.monthlyexpenses.adapter.ExpandableListAdapter.getChildView(ExpandableListAdapter.java:87)
at
android.widget.ExpandableListConnector.getView(ExpandableListConnector.java:451)
at android.widget.AbsListView.obtainView(AbsListView.java:2232)
at android.widget.ListView.makeAndAddView(ListView.java:1849)
at android.widget.ListView.fillDown(ListView.java:678)
at android.widget.ListView.fillSpecific(ListView.java:1339)
My apps screen shot
I tried debug but nothing is null !
You can clone my project from link below
https://github.com/wseng92/MonthlyExpenses
Add createCollection(); to button1 setonclick listner
createCollection();
groupList = new ArrayList(); is written inside for loop might be problem? It creates a new arraylist for each loop and as a result your arraysize is 1 always ( last iteration count )
while (cursor.moveToNext()) {
groupList = new ArrayList<ListObj>();
int iD = cursor.getInt(cursor.getColumnIndex("ID"));
String month = cursor.getString(cursor.getColumnIndex("Month"));
double budget = cursor.getDouble(cursor.getColumnIndex("Budget"));
groupList.add(new ListObj(iD,month,budget));
createCollection(); // for child items
if (expListAdapter != null) {
expListAdapter.add(iD, month, budget);
listview.setAdapter(expListAdapter);
}
}
change to
groupList = new ArrayList<ListObj>();
while (cursor.moveToNext()) {
int iD = cursor.getInt(cursor.getColumnIndex("ID"));
String month = cursor.getString(cursor.getColumnIndex("Month"));
double budget = cursor.getDouble(cursor.getColumnIndex("Budget"));
groupList.add(new ListObj(iD,month,budget));
createCollection(); // for child items
if (expListAdapter != null) {
expListAdapter.add(iD, month, budget);
listview.setAdapter(expListAdapter);
}
}
I ran in to a similar problem year or two ago. Can not remember anymore which version it was.
Starting from call
public Object getChild(int groupPosition, int childPosition) {
if (laptopCollections.get(laptops.get(groupPosition)).get(childPosition) ...
What is the value of laptops? It is initialized with constructor
public ExpandableListAdapter(Context context, ArrayList<ListObj> laptops ...
on second parameter, it is created on AddMonthlyExpenses.onCreate()
expListAdapter =
new ExpandableListAdapter(getApplication(), groupList, laptopCollection);
and initially initialized in declaration
ArrayList<ListObj> groupList= new ArrayList<ListObj>();;
For some reason unknown to me - Android peculiarity - in my case this groupList (or similar member field i had) was NULL even it was initialized on declaration.
But moving the initialization inside onCreate() fixed this problem.
Try that. Or at lease debug the row where laptops is referenced.
i think in your code dont work this
laptopCollections.get(laptops.get(groupPosition)).size();
because try find other object instance.
you have so many list in your fragment and adapter you really dont need this. Try keep OOP and refactor this and create better model for this.
or easier way dont use for map key object but id then.
change from
Map<ListObj, List<String>> laptopCollections
to
Map<String,List<String>> laptopCollections where first K is id.
Maybe it will be helpfull.
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;
}
}
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!
I'm newbie. For couple of days I'm trying to resolve this issue, but no luck. Any help ? Thanks in advance.
Below is the images,
I selected few items and then scrolled up
Once scrolled down selection disappears
Below the adapter class I implemented,
/**
* Created by abcd on 27/1/17.
*/
public class ListItemAdapterTaxCheckBox extends BaseAdapter {
//flag = 1 name/id
//flag =2 //ID/Name
public class HolderCheck
{
TextView tv;
CheckBox ck;
}
private static LayoutInflater inflater=null;
Tax[] result;
Context context;
Tax[] selections = null;
String [] IDs = null;
boolean bAllSel = false;
Resources res = null;
public ListItemAdapterTaxCheckBox(Activity mainActivity, Tax[] prgmNameList, Tax[] sel, Resources rs, String [] ids) {
result=prgmNameList;
context=mainActivity;
selections = sel;
if(selections==null)
{
selections = new Tax[1];
selections[0] = new Tax();
}
IDs = ids;
res = rs;
inflater = ( LayoutInflater )context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return result.length + 1;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final HolderCheck holderCk = new HolderCheck();;
View rowView = convertView;
final int pos = position;
rowView = inflater.inflate(R.layout.custom_list_check_box, null);
holderCk.tv = (TextView) rowView.findViewById(R.id.code);
holderCk.ck = (CheckBox) rowView.findViewById(R.id.checkBox1);
if(position==0) {
holderCk.tv.setText(context.getString(R.string.all_text));
}
else {
holderCk.tv.setText("" + result[position-1].m_TaxID + " - " + result[position-1].m_TaxName);
}
holderCk.tv.setTextSize(16);
holderCk.tv.setTextColor(Color.BLACK);
rowView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (holderCk.ck.isChecked()) {
holderCk.tv.setBackgroundColor(Color.WHITE);
holderCk.ck.setChecked(false);
if(pos!=0)
{
if (IDs != null)
IDs[pos -1] = "0";
}
else
{
bAllSel = false;
}
} else {
holderCk.tv.setBackgroundColor(GetResourceColor.getColorWrapper(context, R.color.selHintColor));
holderCk.ck.setChecked(true);
if(pos!=0)
{
if (IDs != null)
IDs[pos -1] = "" + result[pos-1].m_TaxID;
}
else
{
bAllSel = true;
}
}
}
});
return rowView;
}
public String [] getIDs() {
if(bAllSel)
return null;
else {
ArrayList<String> arrayList = new ArrayList<String>();
for (int i = 0, j = 0; i < IDs.length; i++) {
if (IDs[i].trim() != "0") {
arrayList.add(j, IDs[i].trim());
j = j + 1;
if (arrayList.size() == MySQLHelper.MAXITEMSLISTDELETE)
break;
}
}
return arrayList.toArray(new String[arrayList.size()]);
}
}
}
Below the way I'm populating the ListView
//class member
Tax[] valuesTaxID = null;
//inside a method
//default
Tax[] tx = new Tax[1];
tx[0] = new Tax();
if (valuesTaxID != null) {
listV.setAdapter(null);
listV.setAdapter(new ListItemAdapterTaxCheckBox(ctx, valuesTaxID, tx, rs, Ids));
listV.setVisibility(View.VISIBLE);
ListView will create and destroy views when you scroll. Your code is changing a checkbox when a view is clicked, but you store that info nowhere else, you scroll, ListView destroys the view when you scroll, and there you lost the status of the view.
You want to store the "checked" state of the view somewhere. Could be an ArrayList with states, could be a tag attached to the ViewHolders, ... just store it somewhere.
I have a ToDo project with listview that shows the data from SQLite with custom adapter. Also, I have a button to add the new task but, the items in list view will be repeated.
my custom adapter is
public class CustomAdapter extends BaseAdapter {
private final Activity activity;
private final ArrayList < LT_Model > data;
private static LayoutInflater inflater = null;
public CustomAdapter(Activity a, ArrayList < LT_Model > d) {
this.activity = a;
this.data = d;
inflater = (LayoutInflater) this.activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public static class ViewHolder {
public TextView task;
public ImageView imgD;
public ImageView imgE;
public ImageView imgS;
}#
Override
public int getCount() {
if (data.size() <= 0)
return 1;
return data.size();
}
#
Override
public Object getItem(int position) {
return position;
}
#
Override
public long getItemId(int position) {
return position;
}
#
Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_todo, null);
holder = new ViewHolder();
holder.task = (TextView) convertView.findViewById(R.id.task_title);
holder.imgD = (ImageView) convertView.findViewById(R.id.imgDelete);
holder.imgE = (ImageView) convertView.findViewById(R.id.imgEdit);
holder.imgS = (ImageView) convertView.findViewById(R.id.imgCheck);
convertView.setTag(holder);
} else
holder = (ViewHolder) convertView.getTag();
if (data.size() <= 0) {
holder.task.setText("No Data");
} else {
holder.task.setText(data.get(position).getTaskName());
holder.imgD.setImageResource(android.R.drawable.ic_delete);
holder.imgE.setImageResource(data.get(position).getImgComment());
holder.imgS.setImageResource(data.get(position).getImgStatus());
}
return convertView;
}
}
My LT_Model with getter and setter
public class LT_Model {
private String TaskName = "";
private int ImgComment;
private int ImgStatus;
public String getTaskName() {
return TaskName;
}
public void setTaskName(String taskName) {
TaskName = taskName;
}
public int getImgComment() {
return ImgComment;
}
public void setImgComment(int imgComment) {
ImgComment = imgComment;
}
public int getImgStatus() {
return ImgStatus;
}
public void setImgStatus(int imgStatus) {
ImgStatus = imgStatus;
}
}
My UpdateUI which return the data to Arraylist from SQLite in the activity.
My table has 3 columns and I passed them to ArrayList.
private void updateUI() {
ArrayList<LT_Model> taskList = new ArrayList<>();
LT_Model lt_model = new LT_Model();
SQLiteDatabase db = mdb.getReadableDatabase();
Cursor cursor = db.query(DB_Value.Constant.List_Table,
new String[]{DB_Value.Constant._ID, DB_Value.Constant.COL_Task, DB_Value.Constant.COL_Comment,
DB_Value.Constant.COL_Status}, null, null, null, null, null);
while (cursor.moveToNext()) {
//int idx = cursor.getColumnIndex(DB_Value.Constant.COL_Task);
lt_model.setTaskName(cursor.getString(1));
Toast.makeText(getApplicationContext(), lt_model.getTaskName(), Toast.LENGTH_SHORT).show();
if (cursor.getString(2) == null || cursor.getString(2).equals("")) {
lt_model.setImgComment(android.R.drawable.ic_menu_edit);
}else{
lt_model.setImgComment(android.R.drawable.ic_menu_agenda);
}
if (cursor.getInt(3)==1){
lt_model.setImgStatus(android.R.drawable.checkbox_on_background);
}else{
lt_model.setImgStatus(android.R.drawable.checkbox_off_background);
}
taskList.add(lt_model);
}
mTaskListView.setAdapter(new CustomAdapter(dailyNew, taskList));
cursor.close();
db.close();
}
and this is my problem.
When I add the second task the title of first task would change with that, and this is repeated for the others rows.
When you iterate through your cursor, you need to make a new Model for each row, so you're adding a distinct object each time.
while (cursor.moveToNext()) {
LT_Model lt_model = new LT_Model();
I am trying to implement something similar to facebook's search system, where if a user starts typing in a name it brings autocomplete suggestions based on the letters typed, and with an additional option to search for more results. Each result is an object and not a string, and I have tried adding an extra result for search but every time I click on search or one of the objects a replace text occurs with the object as oppose to the name and I know it is a method of the autocomplete widget. Is there another way to go about it?
Here is my code:
private AutoCompleteTextView sx;
sx = (AutoCompleteTextView) findViewById(R.id.sx);
if(sadapter == null) {
sadapter = new Sadapter(PostActivity.this, usersFound);
sx.setAdapter(sadapter);
}
sx.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) {
if (sx.getText().toString().length() <= 3 && sadapter != null) {
usersFound.clear();
sadapter.notifyDataSetChanged();
}
if (sx.getText().toString().length() > 3) {
usersFound.clear();
sadapter.notifyDataSetChanged();
Log.d(Constants.DEBUG, "Changing text " + s);
sxname = s.toString();
testCreate();
sadapter.notifyDataSetChanged();
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
sx.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
DatabaseUser newAdd = usersFound.get(position);
if(position == searchServerIndex) {
sx.setText(sxname);
usersFound.clear();
sadapter.notifyDataSetChanged();
apiGetPossibleCandidates();
} else {
sx.setText("");
}
}
});
private void testCreate() {
DatabaseUser nuser1 = new DatabaseUser("userid", "pictureid", "Jon");
DatabaseUser nuser2 = new DatabaseUser("userid", "pictureid", "Jonny");
DatabaseUser nuser3 = new DatabaseUser("userid", "pictureid", "Jong");
DatabaseUser nuser4 = new DatabaseUser("userid", "pictureid", "Joan");
DatabaseUser searchServer = new DatabaseUser("SearchId", "pictureid", "Search " + sxname);
usersFound.add(nuser1);
usersFound.add(nuser2);
usersFound.add(nuser3);
usersFound.add(nuser4);
searchServerIndex = usersFound.size();
usersFound.add(searchServer);
if(sadapter != null) {
sadapter.notifyDataSetChanged();
}
}
This is the adapter:
public class Sadapter extends ArrayAdapter<DatabaseUser> {
private Context mContext;
private List<DatabaseUser> usersSearch;
private List<DatabaseUser> usersFiltered;
public Sadapter(Context context, List<DatabaseUser> usersAdded) {
super(context, 0, usersAdded);
mContext = context;
usersSearch = usersAdded;
}
#Override
public int getCount() {
return usersSearch.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.user_autosearch_item, null);
}
//helps for recycling
final ViewHolder holder = new ViewHolder();
holder.userTxt = (TextView) v.findViewById(R.id.userTxt);
v.setTag(holder);
String name = usersSearch.get(position).getName();
holder.userTxt.setText(name);
return v;
}
static class ViewHolder {
TextView userTxt;
}
}
you can override getItem() method in your adapater and return the object of DataBaseUser of particular position from the searchlist.. like
#Override public DatabaseUser getItem(int position) {
return usersSearch.get(position);
}
So from your onClick method you can call this method and it will give you DatabaseUser object from which you can retrive your text. I hope it helps you ..