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
Related
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>>();
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;
}
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).
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.
I am creating expandable listview like this image so many tables, when i click any one show its child my questions how to create database just show only 1 like computer electronic when click on that tap show its childs i found this tutorial is use hardcode data plz how can i used sqlite database for expandablelistview?
public class MainActivity 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.activity_main);
// 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);
// Listview Group click listener
expListView.setOnGroupClickListener(new OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
// Toast.makeText(getApplicationContext(),
// "Group Clicked " + listDataHeader.get(groupPosition),
// Toast.LENGTH_SHORT).show();
return false;
}
});
// Listview Group expanded listener
expListView.setOnGroupExpandListener(new OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
Toast.makeText(getApplicationContext(),
listDataHeader.get(groupPosition) + " Expanded",
Toast.LENGTH_SHORT).show();
}
});
// Listview Group collasped listener
expListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {
#Override
public void onGroupCollapse(int groupPosition) {
Toast.makeText(getApplicationContext(),
listDataHeader.get(groupPosition) + " Collapsed",
Toast.LENGTH_SHORT).show();
}
});
// Listview on child click listener
expListView.setOnChildClickListener(new OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
// TODO Auto-generated method stub
Toast.makeText(
getApplicationContext(),
listDataHeader.get(groupPosition)
+ " : "
+ listDataChild.get(
listDataHeader.get(groupPosition)).get(
childPosition), Toast.LENGTH_SHORT)
.show();
return false;
}
});
}
/*
* 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);
}
}
In your prepareListData()
// Adding child data
List<String> top250 = getTop250();
public List<String> getTop250() {
List<String> top250List = new ArrayList<String>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_CONTACTS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
// Adding contact to list
top250List.add(cursor.getString(0));
} while (cursor.moveToNext());
}
// return top 250 list
return top250List;
}
similarly get other lists and add it to child, hope this helps and for CURD in sqlite DB look here