Reputation: 12803
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
Upvotes: 4
Views: 632
Reputation: 12285
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.
Upvotes: 1
Reputation: 2448
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);
}
}
Upvotes: 2
Reputation: 199
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.
Upvotes: 0