Android ExpandableListView makes application to crash - android

I have been adding an ExpandableListView to my application following this tutorial:
http://www.androidhive.info/2013/07/android-expandable-list-view-tutorial/
Now when following this and I run the application it crashes.
Here is my code in MainActivity:
public class MainActivity extends FragmentActivity {
ViewPager viewpager;
ExpandableListAdapter listAdapter;
ExpandableListView expListView;
List<String> listDataHeader;
HashMap<String, List<String>> listDataChild;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewpager = (ViewPager) findViewById(R.id.pager);
PagerAdapter padapter = new PagerAdapter(getSupportFragmentManager());
viewpager.setAdapter(padapter);
expListView = (ExpandableListView) findViewById(R.id.lvExp);
prepareListData();
listAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild);
expListView.setAdapter(listAdapter);
}
private void prepareListData(){
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String, List<String>>();
List<String> top250 = new ArrayList<String>();
top250.add("250");
List<String> test = new ArrayList<String>();
test.add("Din mamma");
listDataChild.put(listDataHeader.get(0), top250);
listDataChild.put(listDataHeader.get(1), test);
}
}
These are the errors that don't tell me so much just that there is a problem on this rows:
at com.hoyer_group.hoyer.MainActivity.prepareListData(MainActivity.java:53)
at com.hoyer_group.hoyer.MainActivity.onCreate(MainActivity.java:37)
Row 37 is:
prepareListData();
Row 53 is:
listDataChild.put(listDataHeader.get(0), top250);
Hope for some clarity in this.
Thanks.

listDataChild.put(listDataHeader.get(0), top250);
Your listDataHeader has no elements in it, but you're trying to access the first element.

I think that your listDataHeader List is empty, so, if you try to get any value, it will get Nothing, so it is your error, there are no elements in the list

In
listDataChild.put(listDataHeader.get(0), top250);
listDataChild.put(listDataHeader.get(1), test);
You are trying to get data from listDataHeader, and in the code you show us you do not did listDataHeader.put anywhere.
So, the Logcat error make sense:
IndexOutOfBoundsException: Invalid index 0, size is 0
Which corresponds with listDataHeader.get(0).

Related

Expandable List View not in right order

my expandable list view doesn't seem to be in right order.
Here is my dataprovider for it:
public class DataProvider {
public static HashMap<String, List<String>> getInfo() {
HashMap<String, List<String>> WorkoutDetails = new HashMap<String, List<String>>();
List<String> Workout_29 = new ArrayList<String>();
Workout_29.add("Week One");
Workout_29.add("Week Two");
Workout_29.add("Week Three");
Workout_29.add("Week Four");
List<String> Workout_30 = new ArrayList<String>();
Workout_30.add("Week One");
Workout_30.add("Week Two");
Workout_30.add("Week Three");
Workout_30.add("Week Four");
List<String> Workout_31 = new ArrayList<String>();
Workout_31.add("Week One");
Workout_31.add("Week Two");
Workout_31.add("Week Three");
Workout_31.add("Week Four");
List<String> Workout_32 = new ArrayList<String>();
Workout_32.add("Week One");
Workout_32.add("Week Two");
Workout_32.add("Week Three");
Workout_32.add("Week Four");
List<String> Workout_37 = new ArrayList<String>();
Workout_37.add("Week One");
Workout_37.add("Week Two");
Workout_37.add("Week Three");
Workout_37.add("Week Four");
WorkoutDetails.put("Workout 29", Workout_29);
WorkoutDetails.put("Workout 30", Workout_30);
WorkoutDetails.put("Workout 31", Workout_31);
WorkoutDetails.put("Workout 32", Workout_32);
WorkoutDetails.put("Workout 37", Workout_37);
return WorkoutDetails;
}
}
Here is where it is created:
public class MyWorkout extends BaseActivity{
ExpandableListView expandableListView;
HashMap<String, List<String>> Workouts_details;
List<String> Workout_list;
WorkoutsAdapter mAdapter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_workout);
mToolBar = activateToolbar();
setUpNavigationDrawer();
getSupportActionBar().setTitle("My Workout");
expandableListView = (ExpandableListView) findViewById(R.id.listViewWorkouts);
Workouts_details = DataProvider.getInfo();
Workout_list = new ArrayList<>(Workouts_details.keySet());
mAdapter = new WorkoutsAdapter(this, Workouts_details, Workout_list);
expandableListView.setAdapter(mAdapter);
As you can see it should be 29,30,31,32,37.. but in reality it is 29,30,32,37,31... Any ideas why? Thanks!
This is most likely because HashMap provides no guarantees about the ordering of its keys in the returned keyset. My guess is that if you subsequently sort the list that you build here, you would get your desired ordering:
Workout_list = new ArrayList<>(Workouts_details.keySet());
// Now sort Workout_list...
// As it is simply a list of strings, we can sort it according to its natural ordering (lexicographical) to get your desired result like so:
java.util.Collections.sort(Workout_list);
You can change HashMap to LinkedHashmap. Like that
LinkedHashMap<String, List<String>> WorkoutDetails = new LinkedHashMap<String, List<String>>();

Implementing an expandable listview in tab fragment

Followed the tutorial from androidhive to create an expandable listview.
http://www.learn-android-easily.com/2013/07/android-tabwidget-example.html
Followed tutorial to create horizontal tabs.
Edited the Tab Widget Example (Second tutorial) to put the expandable listview in the tabs. Did this by creating the expandable list adapter java file in the project and copying the expandable list code into the tab activity file. (Brought in the required xml files too) The tab activity then looked like this:
import android.app.Activity;
import android.os.Bundle;
import android.widget.ExpandableListView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class Tab1Activity extends Activity
{
ExpandableListAdapter listAdapter;
ExpandableListView expListView;
List<String> listDataHeader;
HashMap<String, List<String>> listDataChild;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.expandable_listview);
// get the listview
expListView = (ExpandableListView) findViewById(R.id.lvExp);
// preparing list data
prepareListData();
listAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild);
// setting list adapter
expListView.setAdapter(listAdapter);
}
// Preparing the list data
private void prepareListData()
{
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String, List<String>>();
// Adding child data
listDataHeader.add("Top 250");
listDataHeader.add("Now Showing");
listDataHeader.add("Coming Soon..");
// Adding child data
List<String> top250 = new ArrayList<String>();
top250.add("The Shawshank Redemption");
top250.add("The Godfather");
top250.add("The Godfather: Part II");
top250.add("Pulp Fiction");
top250.add("The Good, the Bad and the Ugly");
top250.add("The Dark Knight");
top250.add("12 Angry Men");
List<String> nowShowing = new ArrayList<String>();
nowShowing.add("The Conjuring");
nowShowing.add("Despicable Me 2");
nowShowing.add("Turbo");
nowShowing.add("Grown Ups 2");
nowShowing.add("Red 2");
nowShowing.add("The Wolverine");
List<String> comingSoon = new ArrayList<String>();
comingSoon.add("2 Guns");
comingSoon.add("The Smurfs 2");
comingSoon.add("The Spectacular Now");
comingSoon.add("The Canyons");
comingSoon.add("Europa Report");
listDataChild.put(listDataHeader.get(0), top250);
// Header, Child data
listDataChild.put(listDataHeader.get(1), nowShowing);
listDataChild.put(listDataHeader.get(2), comingSoon);
}
}
Worked fine. Tried to do the same with project from here:
http://www.androidhive.info/2013/10/android-tab-layout-with-swipeable-views-1/
Here I've got a few errors. I think that setContentView can't be used with fragments so I got rid of it and kept the original inflater.
Similarly I think I need to use something else instead of the findViewById and change my arguments for the ExpandableListAdapter(). Not really sure what this needs to be changes to however..
My tab fragment:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class GamesFragment extends Fragment
{
ExpandableListAdapter listAdapter;
ExpandableListView expListView;
List<String> listDataHeader;
HashMap<String, List<String>> listDataChild;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_games, container, false);
super.onCreate(savedInstanceState);
// get the listview
expListView = (ExpandableListView) findViewById(R.id.lvExp);
// preparing list data
prepareListData();
listAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild);
// setting list adapter
expListView.setAdapter(listAdapter);
return rootView;
}
// Preparing the list data
private void prepareListData()
{
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String, List<String>>();
// Adding child data
listDataHeader.add("Top 250");
listDataHeader.add("Now Showing");
listDataHeader.add("Coming Soon..");
// Adding child data
List<String> top250 = new ArrayList<String>();
top250.add("The Shawshank Redemption");
top250.add("The Godfather");
top250.add("The Godfather: Part II");
top250.add("Pulp Fiction");
top250.add("The Good, the Bad and the Ugly");
top250.add("The Dark Knight");
top250.add("12 Angry Men");
List<String> nowShowing = new ArrayList<String>();
nowShowing.add("The Conjuring");
nowShowing.add("Despicable Me 2");
nowShowing.add("Turbo");
nowShowing.add("Grown Ups 2");
nowShowing.add("Red 2");
nowShowing.add("The Wolverine");
List<String> comingSoon = new ArrayList<String>();
comingSoon.add("2 Guns");
comingSoon.add("The Smurfs 2");
comingSoon.add("The Spectacular Now");
comingSoon.add("The Canyons");
comingSoon.add("Europa Report");
listDataChild.put(listDataHeader.get(0), top250); // Header, Child data
listDataChild.put(listDataHeader.get(1), nowShowing);
listDataChild.put(listDataHeader.get(2), comingSoon);
}
}
My tab fragment layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#ff8400" >
<ExpandableListView
android:id="#+id/lvExp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ExpandableListView>
</RelativeLayout>
Do let me know if I am going about this the wrong way. All I'm looking to do is create swipe views with tabs which have expandable listviews in them.
1) Call findViewById() on the View returned
findViewById in Fragment
2) Change the first argument in the ExpandableListAdapter from 'this' to 'getActivity()'
My new onCreateView looks like this:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.tab_expandable_list, container, false);
// get the listview
expListView = (ExpandableListView) view.findViewById(R.id.lvExp);
// preparing list data
prepareListData();
listAdapter = new ExpandableListAdapter(getActivity(), listDataHeader, listDataChild);
// setting list adapter
expListView.setAdapter(listAdapter);
return view;
}

How to populate listDataHeader in an expandable list view with Data from database?

I'm new to android development. I found this tutorial about expandable listview but it's only from a fixed data. Then after some search, I was able to set the listDataChild with data from my database. But now I'm stuck on How I can populate listDataHeader with Data from database.
Here is what I've done so far:
public class Manage_Students extends Activity {
ExpandableListAdapter listAdapter;
ExpandableListView expListView;
List<String> listDataHeader;
HashMap<String, List<String>> listDataChild;
SimpleCursorAdapter cursorAdapter;
Cursor cursor;
private LoginDataBaseAdapter loginDataBaseAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.students);
// get the listview
expListView = (ExpandableListView) findViewById(R.id.lvExp);
// get Instance of Database Adapter
loginDataBaseAdapter=new LoginDataBaseAdapter(this);
loginDataBaseAdapter=loginDataBaseAdapter.open();
// preparing list data
prepareListData();
listAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild);
// setting list adapter
expListView.setAdapter(listAdapter);
}
/*
* Preparing the list data
*/
private void prepareListData() {
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String, List<String>>();
listDataHeader.add("Subject");
List<String> audio = loginDataBaseAdapter.retrievevalue("g");
listDataChild.put(listDataHeader.get(0),audio); // Header, Child data
}
}
and my adapter:
public List<String> retrievevalue(String value)
{
ArrayList<String> dataList = new ArrayList<String>();
Cursor cu=db.rawQuery("SELECT Section from Sections where Subjid ='"+value+"'",null);
cu.moveToFirst();
if (!cu.isAfterLast())
{
do
{
dataList.add(cu.getString(0));
}
while (cu.moveToNext());
cu.close();
}
// return the ArrayList that holds the data collected from
// the database.
return dataList;
//
}
You cannot add or populate child data from this method as base adapter thinks of getting the child data and group data at the same time. So, create your own custom adapter and pass only parent or group data in it and when the group data is clicked, you add child data from there.

Android layout design..adjust on heading

I want to implement tab in my application. Tab works well. Now implementing expandable list view in one of the tab... That means activity extends Fragment and not FragmentActivity... But I face a problem in expendable list view... How can I overcome this... Here is my code...
public class Setting extends Fragment{
ExplistAdapter listAdapter;
ExpandableListView expListView;
List<String> listDataHeader;
HashMap<String, List<String>> listDataChild;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.setting, container, false);
expListView = (ExpandableListView)rootView. findViewById(R.id.lvExp);
// preparing list data
prepareListData();
listAdapter = new ExplistAdapter(this, listDataHeader, listDataChild);
// setting list adapter
expListView.setAdapter(listAdapter);
return rootView;
}
private void prepareListData() {
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String, List<String>>();
// Adding child data
listDataHeader.add("Top 250");
listDataHeader.add("Now Showing");
listDataHeader.add("Coming Soon..");
// Adding child data
List<String> top250 = new ArrayList<String>();
top250.add("Remaining Battery");
top250.add("Set Alarm Distance");
top250.add("Pick Alarm Tone");
top250.add("Set Vibrate");
List<String> nowShowing = new ArrayList<String>();
nowShowing.add("Remaining Battery");
nowShowing.add("Set Alarm Distance");
nowShowing.add("Pick Alarm Tone");
nowShowing.add("Set Vibrate");
List<String> comingSoon = new ArrayList<String>();
comingSoon.add("2 Guns");
comingSoon.add("The Smurfs 2");
comingSoon.add("The Spectacular Now");
comingSoon.add("The Canyons");
comingSoon.add("Europa Report");
listDataChild.put(listDataHeader.get(0), top250); // Header, Child data
listDataChild.put(listDataHeader.get(1), nowShowing);
listDataChild.put(listDataHeader.get(2), comingSoon);
}
}
error show on
listAdapter = new ExplistAdapter(this, listDataHeader, listDataChild);
Use getActivity() instead of this in your constructor. i suggest you to remove filling data into method onActivityCreated(). As getActivity() is ensured to return the activity creating the fragment only after getting this method called. And this is according to Android Developers docs link: http://developer.android.com/guide/components/fragments.html
So, remove your filling of data into onActivityCreated() and use getActivity() as the context passed to your adapter

repeating ListView

Hey guys I am a working on displaying a list of items on listview, the code I am using is
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom_list_view);
ListView lv= (ListView)findViewById(R.id.listview);
rtrnList = new ArrayList<HashMap<String,String>>();
getmyLocation();
listclass = new listClass(offersobj);
listclass.populate();
rtrnList = listclass.getListArray();
adapter = new SimpleAdapter(
this,
rtrnList,
R.layout.custom_row_view,
new String[] {"Name","Msg","time"},
new int[] {R.id.text1,R.id.text2, R.id.text3}
);
lv.setAdapter(adapter);
}
problem is say I am displaying three names Avinash, Arun, Rajesh. When application starts these three names are displayed on list. When I close and again start the application the values are repeating Avinash, Arun, Rajesh,Avinash, Arun, Rajesh. I am not able to figure out how to solve this.
The code you show seems fine. My guess is that listclass.populate() modifies offersobj and that offersobj is reused over several creations of your activity. So, whenever the activity is created, additional data is populated.
public class ListViewA extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView lv= (ListView)findViewById(R.id.listview);
// create the grid item mapping
String[] from = new String[] {"rowid", "col_1", "col_2", "col_3"};
int[] to = new int[] { R.id.item1, R.id.item2, R.id.item3, R.id.item4 };
// prepare the list of all records
List<HashMap<String, String>> fillMaps = new ArrayList<HashMap<String, String>>();
for(int i = 0; i < 10; i++){
HashMap<String, String> map = new HashMap<String, String>();
map.put("rowid", "" + i);
map.put("col_1", "col_1_item_" + i);
map.put("col_2", "col_2_item_" + i);
map.put("col_3", "col_3_item_" + i);
fillMaps.add(map);
}
// fill in the grid_item layout
SimpleAdapter adapter = new SimpleAdapter(this, fillMaps, R.layout.grid_item, from, to);
lv.setAdapter(adapter);
}
}
for more example see this linkthis alsolistview about adapter, for create a hashmap, why bitmap type imported cannot show image in listview?What adapter shall I use to use HashMap in a ListView

Categories

Resources