I'm a newbie in android programming, i want to create an app with ListView and multiple subitems Need some advice, link for samples.
Application may look like this.
Thanks
enter image description here
For this layout you should have notion of adapters and custom adapters .
Then go through the following link -
https://www.learn2crack.com/2013/10/android-custom-listview-images-text-example.html
Expandable ListView will surely solve your problem !
Follow this link :
http://www.androidhive.info/2013/07/android-expandable-list-view-tutorial/
and let me know if this works for you!!
This is simple expandable list example.
first-
1-create ExpandableListView in activity_main.xml
2-Intialize and set Adapter on MainActivity.java file.
3-create your adapter.
4-create parent and child layout xml file.
my code below........
activity_main.xml..............................
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Expandable List"
android:layout_gravity="center"
android:textColor="#30b171"
android:background="#dde3ec"
android:textAppearance="?android:attr/textAppearanceLarge" />
<ExpandableListView
android:id="#+id/expandableListView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ExpandableListView>
</LinearLayout>
MainActivity.java.........
package com.example.expandblelistapp;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.ExpandableListView;
public class MainActivity extends Activity {
ExpandableListView explist;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
explist=(ExpandableListView) findViewById(R.id.expandableListView1);
MyExpandableListAdapter adapter=new MyExpandableListAdapter(this);
explist.setAdapter(adapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
MyExpandableListAdapter.java..
package com.example.expandblelistapp;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class MyExpandableListAdapter extends BaseExpandableListAdapter{
String[] groups={"Android","Apache_tomcat","Apple","Microsoft","Oracle"};
String[][] children={
{"JellyBean","HoneyComb","Kitkat","CupCake","Lollipop",},
{"tomcat server","xampp server","wamp server","lamp server"},
{"iphone","ipad","iwatch"},
{".net","sqlServer","msoffice","xbox","explorer",},
{"sap","business suite"},
};
Integer[] img={R.drawable.android,R.drawable.apachetomcat,R.drawable.apple,
R.drawable.microsoft,R.drawable.oracle};
Integer[][] childrenimg={
{R.drawable.jellybean,R.drawable.gingerbread,R.drawable.kitkat,R.drawable.cupcake,R.drawable.lollipop},
{R.drawable.images,R.drawable.images,R.drawable.images,R.drawable.images,},
{R.drawable.iphone,R.drawable.ipad,R.drawable.iwatch},
{R.drawable.net,R.drawable.outlook,R.drawable.office,R.drawable.xbox,R.drawable.explore},
{R.drawable.osap,R.drawable.oserver},
};
Context ctx;
public MyExpandableListAdapter(Context context) {
ctx=context;
}
#Override
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return children[groupPosition][childPosition];
}
#Override
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return childPosition;
}
#Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
return children[groupPosition].length;
}
#Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater=(LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView=inflater.inflate(R.layout.child_layout,parent,false);
ImageView i=(ImageView) convertView.findViewById(R.id.imageView2);
i.setImageResource(childrenimg[groupPosition][childPosition]);
TextView dis=(TextView)convertView.findViewById(R.id.childtext);
dis.setText(getChild(groupPosition, childPosition).toString());
return convertView;
}
#Override
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return groups[groupPosition];
}
#Override
public int getGroupCount() {
// TODO Auto-generated method stub
return groups.length;
}
#Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
LayoutInflater inflater=(LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView=inflater.inflate(R.layout.parent_layout,parent,false);
ImageView i=(ImageView) convertView.findViewById(R.id.imageView1);
i.setImageResource(img[groupPosition]);
TextView dis=(TextView)convertView.findViewById(R.id.parenttext);
dis.setText(groups[groupPosition]);
return convertView;
}
#Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return false;
}
}
parent_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/parenttext"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
child_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="#+id/imageView2"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/childtext"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="Large Text"
android:textSize="15sp"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
Related
I am trying to implement expandable list view. When the list is expanded, it is not scrollable anymore. The header got misplaced.
Here is the layout for the lisltview in my main activity:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_below="#+id/dashboard_scrollview">
<ExpandableListView
android:id="#+id/leaderboard_list_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:transcriptMode="alwaysScroll" />
</RelativeLayout>
and after the list view is tapped, it expanded but is unable to scroll:
I'm wondering why the header and the first element are not showing up in the list view.
MainActivity:
public void setupLeaderboardListView(){
leaderboardDetail = ExpandableLeaderboardData.getData();
leaderboardListView.setStackFromBottom(true);
leaderboardtitle = new ArrayList<String>(leaderboardDetail.keySet());
leaderboardAdapter = new LeaderboardAdapter(this, leaderboardtitle, leaderboardDetail);
leaderboardListView.setAdapter(leaderboardAdapter);
leaderboardListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
Toast.makeText(getApplicationContext(),
leaderboardtitle.get(groupPosition) + " List Expanded.",
Toast.LENGTH_SHORT).show();
}
});
leaderboardListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
#Override
public void onGroupCollapse(int groupPosition) {
Toast.makeText(getApplicationContext(),
leaderboardtitle.get(groupPosition) + " List Collapsed.",
Toast.LENGTH_SHORT).show();
}
});
leaderboardListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
Toast.makeText(
getApplicationContext(),
leaderboardtitle.get(groupPosition)
+ " -> "
+ leaderboardDetail.get(
leaderboardtitle.get(groupPosition)).get(
childPosition), Toast.LENGTH_SHORT
).show();
return false;
}
});
}
List datasource:
List<String> cricket = new ArrayList<String>();
cricket.add("India");
cricket.add("Pakistan");
cricket.add("Australia");
cricket.add("England");
cricket.add("South Africa");
cricket.add("India");
cricket.add("Pakistan");
cricket.add("Australia");
cricket.add("England");
cricket.add("South Africa");
I tried setting layout_height=match_parent for the expandable list, but it did not work
This can happen when your ExpandableListView has wrap_content for a width and height. To fix, make it the same as the parent RelativeLayout
<ExpandableListView
android:id="#+id/leaderboard_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:transcriptMode="alwaysScroll" />
First of all: ListView is depricated, It should have been dead long ago and yet, i keep seeing post on it!!!
Second:
Move to recyclerView, here are some resources that will help ya:
1. Nice introduction to it: https://developer.android.com/training/material/lists-cards.html
2. My dialog cheetSheet app (something like demo app), one of the dialogs uses expandable recyclverview library, give it a try https://github.com/WithoutCaps/DialogsCheatSheet
Use this code, it's working fine.
This is main activity layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ExpandableListView
android:id="#+id/expandable_listview"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ExpandableListView>
</LinearLayout>
Your Parent Item Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/tv_parent_item"
android:layout_marginLeft="10dp"
android:layout_gravity="center_vertical"
android:textSize="20sp"
/>
</LinearLayout>
Your child item 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="horizontal"
>
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/iv_child_item"
android:background="#drawable/ic_launcher"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginLeft="100dp"
android:layout_marginTop="5dp" >
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/tv_child_item1"
android:layout_marginLeft="10dp"
android:textSize="15sp"
android:text="Test"
/>
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/tv_child_item2"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:textSize="15sp"
android:text="Test"
/>
</LinearLayout>
Custom Adapter class:
import java.util.HashMap;
import java.util.List;
import com.example.expandablelistview.R;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;
public class ExpandableAdapter extends BaseExpandableListAdapter{
private Context context;
private List<String> parentList;
private HashMap<String , List<Songs>> childList;
ImageLoader imageLoader = ImageLoader.getInstance();
DisplayImageOptions options;
public ExpandableAdapter(){
}
public ExpandableAdapter(Context context,List<String> parentList,
HashMap<String,List<Songs>> childList)
{
this.context=context;
this.parentList=parentList;
this.childList=childList;
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_launcher)
.showImageForEmptyUri(R.drawable.ic_launcher)
.showImageOnFail(R.drawable.ic_launcher)
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
.defaultDisplayImageOptions(options)
.build();
imageLoader.getInstance().init(config);
}
#Override
public int getGroupCount() {
// TODO Auto-generated method stub
return this.parentList.size();
}
#Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
return this.childList.get(this.parentList.get(groupPosition)).size();
}
#Override
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return this.parentList.get(groupPosition);
}
#Override
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return this.childList.get(this.parentList.get(groupPosition)).get(childPosition);
}
#Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
#Override
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return childPosition;
}
#Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
String headerTitle = (String) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.parent_item, null);
}
TextView lblListHeader = (TextView) convertView
.findViewById(R.id.tv_parent_item);
lblListHeader.setTypeface(null, Typeface.BOLD);
lblListHeader.setText(headerTitle);
ExpandableListView eLV = (ExpandableListView) parent;
eLV.expandGroup(groupPosition);
return convertView;
}
#Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Songs childText = (Songs) getChild(groupPosition, childPosition);
if(convertView==null)
{
LayoutInflater infalInflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.child_item , null);
}
TextView artist = (TextView) convertView.findViewById(R.id.tv_child_item1);
TextView song = (TextView) convertView.findViewById(R.id.tv_child_item2);
ImageView image = (ImageView) convertView.findViewById(R.id.iv_child_item);
artist.setText(childText.getArtist());
song.setText(childText.getSong());
String imgUrl=childText.getArtwork();
imageLoader.displayImage(imgUrl, image);
return convertView;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return true;
}
}
For Main Activity OnCreate() method:
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
expListView = (ExpandableListView) findViewById(R.id.expandable_listview);
listParent = new ArrayList<String>();
listChild = new HashMap<String, List<Songs>>();
new GetData().execute();
listAdapter = new ExpandableAdapter(this, listParent, listChild);
expListView.setAdapter(listAdapter);
expListView.setOnGroupClickListener(new OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
Toast.makeText(getApplicationContext(),
"Group Clicked " + listParent.get(groupPosition),
Toast.LENGTH_SHORT).show();
return false;
}
});
expListView.setOnGroupExpandListener(new OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
}
});
expListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {
#Override
public void onGroupCollapse(int groupPosition) {
}
});
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(),
listParent.get(groupPosition)
+ " : "
+ listChild.get(
listParent.get(groupPosition)).get(
childPosition), Toast.LENGTH_SHORT)
.show();
return false;
}
});
}
In Expandable List view xml used android:nestedScrollingEnabled="true"
am creating an android application whereby am required to create a gridview with clickable image buttons each leading to a different activities.Also the gridview should be scrollable since i have many buttons to add .Can anyone help on how to do this? thank you.
Here is a sample of what am trying to do:
sample clickable gridview:
activitymain.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<GridView
android:id="#+id/gridView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/textView1"
android:numColumns="3" >
</GridView>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25dp"
android:textStyle="bold"
android:text=" Computer Languages..." />
</RelativeLayout>
programlist.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView1"
android:layout_gravity="center"
android:layout_width="88dp"
android:layout_height="88dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/textView1"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:text="TextView" />
</LinearLayout>
In MainActivity.java
package com.gnetspace.simplegridview;
import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.widget.AdapterView;
import android.widget.GridView;
public class MainActivity extends Activity {
GridView gv;
Context context;
ArrayList prgmName;
public static String [] prgmNameList={"Let Us C","c++","JAVA","Jsp","Microsoft .Net","Android","PHP","Jquery","JavaScript"};
public static int [] prgmImages={R.drawable.images,R.drawable.images1,R.drawable.images2,R.drawable.images3,R.drawable.images4,R.drawable.images5,R.drawable.images6,R.drawable.images7,R.drawable.images8};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gv=(GridView) findViewById(R.id.gridView1);
gv.setAdapter(new CustomAdapter(this, prgmNameList,prgmImages));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Create a folder by name drawable in res directory.
public static int [] prgmImages={R.drawable.images,R.drawable.images1,R.drawable.images2,R.drawable.images3,R.drawable.images4,R.drawable.images5,R.drawable.images6,R.drawable.images7,R.drawable.images8};
Create CustomAdapter and paste the following code.
package com.gnetspace.simplegridview;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class CustomAdapter extends BaseAdapter{
String [] result;
Context context;
int [] imageId;
private static LayoutInflater inflater=null;
public CustomAdapter(MainActivity mainActivity, String[] prgmNameList, int[] prgmImages) {
// TODO Auto-generated constructor stub
result=prgmNameList;
context=mainActivity;
imageId=prgmImages;
inflater = ( LayoutInflater )context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return result.length;
}
#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;
}
public class Holder
{
TextView tv;
ImageView img;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Holder holder=new Holder();
View rowView;
rowView = inflater.inflate(R.layout.program_list, null);
holder.tv=(TextView) rowView.findViewById(R.id.textView1);
holder.img=(ImageView) rowView.findViewById(R.id.imageView1);
holder.tv.setText(result[position]);
holder.img.setImageResource(imageId[position]);
rowView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(context, "You Clicked "+result[position], Toast.LENGTH_LONG).show();
}
});
return rowView;
}
}
the source link is caveofprograming
I've been looking at other people's answers on this question, but so far nothing seems to be working.
Currently I have an ExpandableListAdapter built from one of the examples that came with the SDK. As far as displaying data I got it to work fine for, but I can't get the onChildClick event to work at all. I've tried setting the focusable attribute on my XML elements to false, but I'm still not having any luck.
Currently this is what I have for code:
MainActivity.java
package com.example.expandablelisttest;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.ExpandableListView;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ExpandableListView expandableListView = (ExpandableListView) findViewById(R.id.expandableListView1);
ExpandableListAdapter expandableAdapter = new ExpandableListAdapter();
expandableListView.setAdapter(expandableAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
ExpandableListAdapter.java
package com.example.expandablelisttest;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.TextView;
import android.widget.Toast;
public class ExpandableListAdapter extends BaseExpandableListAdapter
implements ExpandableListView.OnChildClickListener
{
private String[] groups = { "People Names", "Dog Names", "Cat Names", "Fish Names" };
private String[][] children = {
{ "Arnold", "Barry", "Chuck", "David" },
{ "Ace", "Bandit", "Cha-Cha", "Deuce" },
{ "Fluffy", "Snuggles" },
{ "Goldy", "Bubbles" }
};
public Object getChild(int groupPosition, int childPosition) {
return children[groupPosition][childPosition];
}
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent)
{
if (convertView ==null)
{
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
convertView = layoutInflater.inflate(R.layout.child_view, null);
}
TextView childTxt = (TextView) convertView.findViewById(R.id.childTxt);
childTxt.setText(getChild(groupPosition, childPosition).toString());
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
return children[groupPosition].length;
}
#Override
public Object getGroup(int groupPosition) {
return groups[groupPosition];
}
#Override
public int getGroupCount() {
return groups.length;
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent)
{
if (convertView ==null)
{
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
convertView = layoutInflater.inflate(R.layout.group_view, null);
}
TextView groupTxt = (TextView) convertView.findViewById(R.id.groupTxt);
groupTxt.setText(getGroup(groupPosition).toString());
return convertView;
}
#Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id)
{
Log.d("Result:", "Click event triggered");
return true;
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ExpandableListView
android:id="#+id/expandableListView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" >
</ExpandableListView>
</LinearLayout>
child_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:focusable="false" >
<TextView
android:id="#+id/childTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:focusable="false"/>
</LinearLayout>
group_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:focusable="false" >
<TextView
android:id="#+id/groupTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="36dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:focusable="false" />
</LinearLayout>
If anyone can see why my click event isn't firing and can help me out. I'd greatly appreciate it. Thanks in advance.
This is happening mainly because your child is not getting selected when your trying to click on it because in the adapter which contains method for doing this is called isChildSelectable() which returns flase by default , so make it true as u want it to get selected and the problem is resolved... thanks :)
The OnChildClickListener doesn't belong in the Adapter it should be added to the ExpandableListView instead inside your Activity.
Like this:
expandableListView.setOnChildClickListener(new OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
// Handle clicks on the children here...
return false;
}
});
change boolean return value true if you are using isChildSelectable return value false in adapter.You can use this
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
instead of
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
I am implementing Expandable List view in android and i am getting the above titled error. Please help me.
Main activity is -
package com.expand;
import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.Toast;
public class MyExpandableListViewActivity extends Activity {
/** Called when the activity is first created. */
static final String groupElements[]= {
"India",
"Australia",
"England",
"South Africa"
};
static final String[][] childElements=
{
{
"Sachin Tendulkar",
"Raina",
"Dhoni",
"Yuvi"
},
{
"Ponting",
"Adam Gilchrist",
"Michael Clarke"
},
{
"Andrew Strauss",
"kevin Peterson",
"Nasser Hussain"
},
{
"Graeme Smith",
"AB de villiers",
"Jacques Kallis"
}
};
DisplayMetrics metrics;
int width;
ExpandableListView expandList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
expandList = (ExpandableListView)findViewById(R.id.expandList1);
metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
width = metrics.widthPixels;
//ExpAdapter adapter = new ExpAdapter(MyExpandableListViewActivity.this, groupElements, childElements);
expandList.setAdapter(new ExpAdapter(MyExpandableListViewActivity.this, groupElements, childElements));
expandList.setIndicatorBounds(width - GetDipsFromPixel(50), width - GetDipsFromPixel(10));
expandList.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
// TODO Auto-generated method stub
Log.e("onGroupExpand", "OK");
}
});
expandList.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
#Override
public void onGroupCollapse(int groupPosition) {
// TODO Auto-generated method stub
Log.e("onGroupCollapse", "OK");
}
});
expandList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
//getting the item that is selected
//String s = (String) expandList.getItemAtPosition((int) id);
Toast.makeText(MyExpandableListViewActivity.this, "You have selected :" , Toast.LENGTH_SHORT).show();
return false;
}
});
}
public int GetDipsFromPixel(float pixels)
{
// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
return (int) (pixels * scale + 0.5f);
}
}
ExpAdapter class is -
I have implemented the adapter in other class and have called it in mt main activity
package com.expand;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;
public class ExpAdapter extends BaseExpandableListAdapter {
public Context myContext;
public String[][] childElements;
TextView childValues;
public String[] groupElements;
public ExpAdapter(Context context, String[] group, String[][] childs)
{
this.myContext=context;
this.groupElements = group;
this.childElements = childs;
}
#Override
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return childElements[groupPosition][childPosition];
}
#Override
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if(convertView==null){
LayoutInflater inflator = (LayoutInflater)myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflator.inflate(R.layout.child_rows, parent);
}
childValues = (TextView)convertView.findViewById(R.id.rowValues);
childValues.setText(childElements[groupPosition][childPosition]);
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
return groupElements[groupPosition].length();
}
#Override
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return groupElements[groupPosition];
}
#Override
public int getGroupCount() {
// TODO Auto-generated method stub
return groupElements.length;
}
#Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if(convertView==null){
LayoutInflater inflator = (LayoutInflater)myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflator.inflate(R.layout.group_rows, null);
}
TextView group = (TextView)convertView.findViewById(R.id.groupId);
group.setText(groupElements[groupPosition]);
return convertView;
}
#Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return true;
}
}
main.xml-
this is the xnl that is displayed at the first by the main activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ExpandableListView
android:id="#+id/expandList1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="#+id/android:empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
</TextView>
</ExpandableListView>
</LinearLayout>
group_row.xml
this is the xml for the group elements
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gropu_name"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:orientation="vertical" >
<TextView
android:id="#+id/groupId"
android:layout_height="40dp"
android:layout_width="wrap_content"
android:paddingLeft="30dp"
android:gravity="center_vertical"
android:textSize="16dp"
android:textStyle="bold"
/>
</LinearLayout>
child_row.xml
this is the xml for the child elements
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:orientation="horizontal" >
<TextView
android:id="#+id/rowValues"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:gravity="center_vertical"
android:paddingLeft="50dp"
android:textSize="12dp" />
</LinearLayout>
Seems like Adapterview does not allow adding new view,
I encountered same problem
Solve it by replacing following line
convertView = inflator.inflate(R.layout.child_rows, parent);
to
convertView = inflator.inflate(R.layout.child_rows, null);
UPDATE
Instead of not using a parent at all, you should simply tell the Inflater not to attach the inflated view to the parent with
convertView = inflator.inflate(R.layout.child_rows, parent, false);
See also this answer.
The reason is that adapter takes care of attaching views to parent itself.
Note that you can also get this error when your layout xml is invalid.
As were noted above,
Instead of not using a parent at all, you should simply tell the
Inflater not to attach the inflated view to the parent with
convertView = inflator.inflate(R.layout.child_rows, parent, false);
See also this answer.
The reason is that adapter takes care of attaching views to parent itself.
According to Android Lint your child view should always provide a reference to its parent view when inflated. I had the exact same error in my code. Is was occurring because the TextView was placed inside the ExpandableListView. When I rearranged my xml layout the error stopped appearing.
This error can also be caused because of instant run feature. I was working on listview and because of this error app kept crashing. Uninstalling the app and running again resolved the error.
Hey guys i have a ListActivity... a very simple at that... and it keeps throwing NullPointer Exception though i have done it exactly as the Sample List7 except that i have used the Layout inflater... below is the code... Can u plz comment the error i have done here??
import java.util.Vector;
import android.app.Activity;
import android.app.ListActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemSelectedListener;
public class CustomList extends ListActivity implements OnItemSelectedListener{
Vector<String> VTitle;
Vector<String> VDescription;
TextView display;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
VTitle.addElement("First Title");
VTitle.addElement("Second Title");
VTitle.addElement("Third Title");
VTitle.addElement("Fourth Title");
VDescription.addElement("1 Description");
VDescription.addElement("2 Description");
VDescription.addElement("3 Description");
VDescription.addElement("4 Description");
display = (TextView)findViewById(R.id.display);
setListAdapter(new CustomAdapter(this));
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
display.setText(VTitle.elementAt(position));
}
class CustomAdapter extends BaseAdapter {
protected Activity mContext;
public CustomAdapter(Activity context) {
mContext = context;
// TODO Auto-generated constructor stub
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return VTitle.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
View row = convertView;
if(row==null) {
LayoutInflater inflater = mContext.getLayoutInflater();
row = inflater.inflate(R.layout.row,null);
}
TextView title = (TextView)row.findViewById(R.id.title);
title.setText(VTitle.elementAt(position));
TextView description = (TextView)row.findViewById(R.id.description);
description.setText(VDescription.elementAt(position));
ImageView image = (ImageView)row.findViewById(R.id.image);
switch(position){
case 0:
image.setImageResource(R.drawable.check);
break;
case 1:
image.setImageResource(R.drawable.dos);
break;
case 2:
image.setImageResource(R.drawable.smily);
break;
case 3:
image.setImageResource(R.drawable.wrong);
break;
}
return(row);
}
}
#Override
public void onItemSelected(AdapterView parent, View v, int position, long id) {
// TODO Auto-generated method stub
display.setText(VTitle.elementAt(position));
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
And the xmls are like this....
"main.xml"
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id = "#+id/display"
android:text="something"
/>
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:drawSelectorOnTop="false"
android:layout_height="0px">
</ListView>
</LinearLayout>
"row.xml"
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ImageView>
<TextView
android:text="Title"
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<TextView
android:text="description"
android:id="#+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
VTitle and VDescription aren't initialized
Before accessing one of these attributes, you should :
VTitle = new Vector<String>();
VDescription = new Vector<String>();
Moreover in java, the first letter of an attribute name should be lowercase, and in android this first letter should be an m, to denote a member field.