RelativeLayout in ExpandableListView not working - java

I have an custom ExpandableListView Adapter:
public class MyExpandableListView extends BaseExpandableListAdapter {
private Context context;
private List<? extends List<? extends Map<String, ?>>> mChildData;
private List<? extends Map<String, ?>> mGroupData;
public MyExpandableListView(Context context,List<? extends Map<String, ?>> GroupData,
List<? extends List<? extends Map<String, ?>>> ChildData){
this.context = context;
this.mChildData=ChildData;
this.mGroupData=GroupData;
}
#Override
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return mChildData.get(groupPosition).get(childPosition);
}
#Override
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return childPosition;
}
#Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.child_list_layout, null);
}
TextView childtxt = (TextView) convertView.findViewById(R.id.textView1);
childtxt.setText((CharSequence) mChildData.get(groupPosition).get(childPosition).get("body"));
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
return mChildData.get(groupPosition).size();
}
#Override
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return mGroupData.get(groupPosition);
}
#Override
public int getGroupCount() {
// TODO Auto-generated method stub
return mGroupData.size();
}
#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) {
// TODO Auto-generated method stub
if(convertView==null){
LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.group_list_layout, null);
}
TextView time = (TextView)convertView.findViewById(R.id.item1);
TextView title = (TextView)convertView.findViewById(R.id.item2);
time.setText((CharSequence) mGroupData.get(groupPosition).get("time"));
title.setText((CharSequence) mGroupData.get(groupPosition).get("titel"));
View view2 = (View)convertView.findViewById(R.id.view2);
view2.bringToFront();
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;
}
}
My group_list_layout.xml is following:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<View
android:id="#+id/view2"
android:layout_width="2dp"
android:layout_height="fill_parent"
android:layout_marginLeft="5dp"
android:background="#ff000000" />
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:orientation="horizontal" >
<TextView
android:id="#+id/item1"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="row_id"
android:textSize="18sp"
android:width="100dip" />
<TextView
android:id="#+id/item2"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:text="col_1"
android:textSize="18sp"
android:width="300dip" />
</LinearLayout>
</RelativeLayout>
I am trying to display a vertical line in front of the "time" of the group element.
But my view (view2) isn't displayed. Why?

Your LinearLayout is positioned on top of the View element. Instead move the View element after the LinearLayout in the group layout so it will be placed above it.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:orientation="horizontal" >
<TextView
android:id="#+id/item1"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="row_id"
android:textSize="18sp"
android:width="100dip" />
<TextView
android:id="#+id/item2"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:text="col_1"
android:textSize="18sp"
android:width="300dip" />
</LinearLayout>
<View
android:id="#+id/view2"
android:layout_width="2dp"
android:layout_height="fill_parent"
android:layout_marginLeft="5dp"
android:background="#ff000000" />
</RelativeLayout>
Also, inflate your layout like this:
convertView = infalInflater.inflate(R.layout.group_list_layout, parent, false);

As it is a Relative layout adding android:layout_toLeftOf="#id/view2" to the LinearLayout should work.

Related

How to set no indicator for the group having zero child in Expandable ListView?

I want to set no indicator for the groups having zero child .I have used expandable list view .This is the screenshot Initial layout.Initially the groups with zero child have no indicator .But as soon as I expand my group with a definite number of childs then the groups with no child also starts showing the indicator .
MainActivity.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:ads="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
android:clickable="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ExpandableListView
android:id="#+id/exp_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="160dp"
android:indicatorRight="?android:attr/expandableListPreferredItemIndicatorRight"
android:background="#android:color/white"
android:footerDividersEnabled="true"
android:groupIndicator="#null">
</ExpandableListView>
<!--<ListView-->
<!--android:background="#android:color/white"-->
<!--android:id="#+id/menuList"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:layout_marginTop="10dp" />-->
</LinearLayout>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
Listheader.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="5dp"
android:orientation="horizontal">
<ImageView
android:id="#+id/iconimage"
android:layout_width="40dp"
android:layout_height="40dp"
android:padding="10dp"/>
<TextView
android:id="#+id/submenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:textColor="#000000"
android:textSize="16sp"
android:gravity="center_vertical" />
</LinearLayout>
</LinearLayout>
ExpandableListAdapter.java
package com.global.market;
import android.content.Context;
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.ImageView;
import android.widget.TextView;
import java.util.HashMap;
import java.util.List;
/**
* Created by Samarth on 17-Jul-16.
*/
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context mContext;
private List<ExpandedMenuModel> mListDataHeader; // header titles
// child data in format of header title, child title
private HashMap<ExpandedMenuModel, List<String>> mListDataChild;
ExpandableListView expandList;
public ExpandableListAdapter(Context context, List<ExpandedMenuModel> listDataHeader,
HashMap<ExpandedMenuModel, List<String>> listChildData, ExpandableListView mView) {
this.mContext = context;
this.mListDataHeader = listDataHeader;
this.mListDataChild = listChildData;
this.expandList = mView;
}
#Override
public int getGroupCount() {
int i = mListDataHeader.size();
Log.d("GROUPCOUNT", String.valueOf(i));
return this.mListDataHeader.size();
}
#Override
public int getChildrenCount(int groupPosition) {
int childCount = 0;
if (groupPosition<2) {
childCount = this.mListDataChild.get(this.mListDataHeader.get(groupPosition))
.size();
}
return childCount;
}
#Override
public Object getGroup(int groupPosition) {
Log.d("Group",groupPosition+"");
return this.mListDataHeader.get(groupPosition);
}
#Override
public Object getChild(int groupPosition, int childPosition) {
// Log.d("CHILD", mListDataChild.get(this.mListDataHeader.get(groupPosition))
// .get(childPosition).toString());
return this.mListDataChild.get(this.mListDataHeader.get(groupPosition))
.get(childPosition);
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
ExpandedMenuModel headerTitle = (ExpandedMenuModel) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this.mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.listheader, null);
}
TextView lblListHeader = (TextView) convertView
.findViewById(R.id.submenu);
ImageView headerIcon = (ImageView) convertView.findViewById(R.id.iconimage);
// lblListHeader.setTypeface(null, Typeface.BOLD);
lblListHeader.setText(headerTitle.getIconName());
headerIcon.setImageResource(headerTitle.getIconImg());
if (isExpanded && getChildrenCount(groupPosition)>0) {
lblListHeader.setCompoundDrawablesWithIntrinsicBounds(0, 0,
R.drawable.collapse, 0);
}
else if(getChildrenCount(groupPosition)>0){
// If group is not expanded then change the text back into normal
// and change the icon
lblListHeader.setCompoundDrawablesWithIntrinsicBounds(0, 0,
R.drawable.expand, 0);
}
return convertView;
}
#Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
final String childText = (String) getChild(groupPosition, childPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this.mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.list_submenu, null);
}
TextView txtListChild = (TextView) convertView
.findViewById(R.id.submenu);
txtListChild.setText(childText);
return convertView;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
I think you add an Icon in your GroupView. Then, during getGroupView(), you check how many child view that group have and decide whether to display the "Empty" icon
Group View Layout:
<LinearLayout>
<LinearLayout
...>
<ImageView
.../>
<TextView
... />
<ImageView>
<!-- IMAGEVIEW ICON TO SHOW THIS GROUP IS EMPTY -->
android:id="#+id/empty_group_icon"
android:visibility="invisible"
</ImageView>
</LinearLayout>
</LinearLayout>
And inside your getGroupView()
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
...
if(getChildrenCount(groupPosition) > 0)
convertView.findViewById(R.id.empty_group_icon).setVisibility(View.INVISIBLE);
else
convertView.findViewById(R.id.empty_group_icon).setVisibility(View.VISIBLE);
return convertView;
}

Android Listview remove any space between items

I want to remove any space between different items in a ListView.
Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:id="#+id/wrapper"
android:padding="0dp"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/comment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:textColor="#000000"/>
</LinearLayout>
And Listview
<ListView
android:id="#+id/listView1"
android:transcriptMode="alwaysScroll"
android:stackFromBottom="true"
android:dividerHeight="0dp"
android:divider="#null"
android:listSelector="#android:color/transparent"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
But there is still some space between the items. Can anyone help me?
The line android:dividerHeight="10dp" causes the gaps between your lines. I color-coded the overall UI:
Once I set the dividerHeight line above from "10dp" to "0dp" I got this:
Ok, so here is the full set of code I used so you can see where you may have gone wrong.
MainActivity:
package com.ds.listviewtest;
import android.app.ListActivity;
import android.content.Context;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.TextView;
public class MainActivity extends ListActivity {
static final String[] FRUITS = new String[] {
"Apple", "Avocado", "Banana",
"Blueberry", "Coconut", "Durian", "Guava", "Kiwifruit",
"Jackfruit", "Mango", "Olive", "Pear", "Sugar-apple"
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new SimpleAdapter(FRUITS));
setContentView(R.layout.activity_main);
}
private class SimpleAdapter implements ListAdapter
{
String[] items;
public SimpleAdapter(String[] items)
{
this.items = items;
}
#Override
public void registerDataSetObserver(DataSetObserver observer) {
// TODO Auto-generated method stub
}
#Override
public void unregisterDataSetObserver(DataSetObserver observer) {
// TODO Auto-generated method stub
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return items.length;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return items[position];
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.list_item, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.comment);
textView.setText(items[position]);
return rowView;
}
#Override
public int getItemViewType(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
public int getViewTypeCount() {
// TODO Auto-generated method stub
return 1;
}
#Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean areAllItemsEnabled() {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean isEnabled(int position) {
// TODO Auto-generated method stub
return true;
}
}
}
Here is list_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:background="#android:color/holo_orange_dark"
android:id="#+id/wrapper"
android:padding="0dp"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/comment"
android:background="#android:color/holo_blue_light"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:text="This is a test comment"
android:textColor="#000000"/>
</LinearLayout>
Finally here is activity_main.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:background="#android:color/holo_red_light"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#android:color/holo_green_light"
android:dividerHeight="0dp" /> <!-- EDIT THIS VALUE HERE TO 0DP -->
</RelativeLayout>
Simply, give your divider height a negative value.
Example :
android:dividerHeight="-20dp"
This will remove spaces between ListView values.

Listview cells are not clickable

I have a custom list adapter that populates a listview.
I am trying to get each item in the listview to be clickable. When clicked, I want the app to load another activity and populate it with the proper data. The data comes from a java list of listing.java.
I can't seem to get it to respond to clicks, here is what I've tried so far:
//this is in the onCreate method
final ListView listview = (ListView) findViewById(R.id.listview);
listingsAdapter = new ListingsAdapter(this, mylistings);
listview.setAdapter(listingsAdapter);
here is my first attempt (this was just to get toast working, but it didn't work)
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, final View view,int position, long id) {
Toast.makeText(getApplicationContext(),
"Click ListItem Number " + position, Toast.LENGTH_LONG).show();
};
});
I have also tried this:
listview.setOnItemClickListener( new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Intent i = new Intent(HomeScreenActivity.this, DetailedViewActivity.class);
startActivity(i);
};
});
Help would be appreciated. Let me know if I should post my adapter as well!
Here is the adaptor:
public class ListingsAdapter extends BaseAdapter{
List<Listing> listings;
Context context;
LayoutInflater inflater;
public ListingsAdapter(Context context, List<Listing> listings){
this.context = context;
this.listings = listings;
inflater = (LayoutInflater) context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public boolean isEnabled(int position)
{
return true;
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
View _localView = convertView;
if (_localView == null){
_localView = inflater.inflate(R.layout.main_cell, parent, false);
}
TextView text1 = (TextView) _localView.findViewById(R.id.firstline);
TextView text2 = (TextView) _localView.findViewById(R.id.secondLine);;
Listing listing = listings.get(position);
text1.setText(listing.getTitle());
text2.setText(listing.getAddress());
return _localView;
}
#Override
public int getCount(){
// TODO Auto-generated method stub
return listings.size();
}
#Override
public Object getItem(int arg0){
return listings.get(arg0);
}
#Override
public long getItemId(int arg0){
// TODO Auto-generated method stub
return arg0;
}
}
this is the main_cell.xml file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="6dp"
android:background="#CC7C43"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true">
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_marginRight="6dip"
android:contentDescription="TODO"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/secondLine"
android:layout_width="fill_parent"
android:layout_height="26dip"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_toRightOf="#id/icon"
android:ellipsize="marquee"
android:singleLine="true"
android:text="Description"
android:textSize="12sp" />
<TextView
android:id="#+id/firstline"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#id/secondLine"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_alignWithParentIfMissing="true"
android:layout_toRightOf="#id/icon"
android:gravity="center_vertical"
android:text="Example application"
android:textSize="16sp"/>
</RelativeLayout>
Right, so I am recovering from a severe hangover and I just remembered that I promised to elaborate on the link I posted - disregard the link!
You should add the following piece of code to your ListingsAdapter:
#Override
public boolean isEnabled(int position)
{
return true;
}
And you should edit the RelativeLayout in your main_cell.xml from
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="6dp"
android:background="#CC7C43"
android:longClickable="true">
to
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="6dp"
android:background="#CC7C43">
This works, I have tested it.
try to initialize local instance of View:
#Override
public View getView(int position, View convertView, ViewGroup parent){
View _localView = convertView;
if (_localView == null){
_localView = inflater.inflate(R.layout.main_cell, parent, false);
}
TextView text1 = (TextView) _localView.findViewById(R.id.firstline);
TextView text2 = (TextView) _localView.findViewById(R.id.secondLine);;
Listing listing = listings.get(position);
text1.setText(listing.getTitle());
text2.setText(listing.getAddress());
return _localView;
}
UPD:
Also modify other necessary methods in your adapter class, because you need to get id of an item clicked for using it in onItemClick method:
#Override
public Object getItem(int arg0){
// TODO Auto-generated method stub
listings.get(arg0);
}
#Override
public long getItemId(int arg0){
// TODO Auto-generated method stub
return arg0;
}
as an example. Hope this will help you.

Changing the location of indicator in ExpandableListView causing problems

I'm trying to set my indicator to be next to the textview, but I just can't get the right code to do it.
XML:
<TextView
android:id="#+id/lblListHeader"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
android:textColor="#000000"
android:textSize="17dp" />
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/lblListHeader"
android:src="#drawable/custom_arrow" />
This is the only stack of code that I have found researching but I can't get it to work:
//inside getGropView method
View v;
if (convertView == null) {
v = newGroupView(isExpanded, parent);
} else {
v = convertView;
}
bindView(v, mGroupData.get(groupPosition), mGroupFrom, mGroupTo);
((ImageView) v.findViewById(R.id.videos_group_indicator))
.setImageResource(isExpanded?R.drawable.videos_chevron_expanded:R.drawable.videos_chevron_collapsed);
return v;
The main problem is that it "underlines" the newGroupView method etc. because I don't have such method and it is not mentioned how to create it in the example I was looking at.
Also, once I get the solution, could someone please try and explain this code to me? I have read it through a lot of time and I just can't get myself to understand it, I'm a beginner.
Here's an example of custom expandable list view:
What you want to see if you apply this code in your new project:
create this code into activity
public class ExpActivity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Находим наш list
ExpandableListView listView = (ExpandableListView)findViewById(R.id.exListView);
//Создаем набор данных для адаптера
ArrayList<ArrayList<String>> groups = new ArrayList<ArrayList<String>>();
ArrayList<String> children1 = new ArrayList<String>();
ArrayList<String> children2 = new ArrayList<String>();
children1.add("Child_1");
children1.add("Child_2");
groups.add(children1);
children2.add("Child_1");
children2.add("Child_2");
children2.add("Child_3");
groups.add(children2);
//Создаем адаптер и передаем context и список с данными
ExpListAdapter adapter = new ExpListAdapter(getApplicationContext(), groups);
listView.setAdapter(adapter);
}
}
add expandableListView into 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"
>
<ExpandableListView
android:id="#+id/exListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:indicatorLeft="250dp"
android:indicatorRight="300dp"
/>
</LinearLayout>
create an adapter class
public class ExpListAdapter extends BaseExpandableListAdapter {
private ArrayList<ArrayList<String>> mGroups;
private Context mContext;
public ExpListAdapter (Context context,ArrayList<ArrayList<String>> groups){
mContext = context;
mGroups = groups;
}
#Override
public int getGroupCount() {
return mGroups.size();
}
#Override
public int getChildrenCount(int groupPosition) {
return mGroups.get(groupPosition).size();
}
#Override
public Object getGroup(int groupPosition) {
return mGroups.get(groupPosition);
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return mGroups.get(groupPosition).get(childPosition);
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.group_view, null);
}
if (isExpanded){
//Изменяем что-нибудь, если текущая Group раскрыта
}
else{
//Изменяем что-нибудь, если текущая Group скрыта
}
TextView textGroup = (TextView) convertView.findViewById(R.id.textGroup);
textGroup.setText("Group " + Integer.toString(groupPosition));
return convertView;
}
#Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.child_view, null);
}
TextView textChild = (TextView) convertView.findViewById(R.id.textChild);
textChild.setText(mGroups.get(groupPosition).get(childPosition));
Button button = (Button)convertView.findViewById(R.id.buttonChild);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(mContext,"button is pressed",5000).show();
}
});
return convertView;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
the names of methods and parameters is quite informative. methods getGroupView and getChildView returns View for pparents and children accordingly. using the parameter isExpanded in the method getGroupView, we ca, for instance, change the back of group in different states. using LayoutInflater we use custom layout for our list.
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">
<TextView
android:id="#+id/textGroup"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="20dp"
android:textColor="#android:color/white"
android:textStyle="bold"
/>
</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">
<TextView
android:id="#+id/textChild"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:textColor="#android:color/white"
/>
<Button
android:id="#+id/buttonChild"
android:layout_width="100dp"
android:layout_height="40dp"
android:layout_marginLeft="150dp"
android:layout_marginTop="10dp"
android:text="Button"
android:focusable="false"
/>
</LinearLayout>
in the child view we added a button, in the adapter method getChildView controlling its pressed. in the similar way we can add buttons and other elements in group_view.xml .
also, we can pin listeners to our list.
•OnChildClickListener — pressing on an element
•OnGroupCollapseListener – collapsing group
•OnGroupExpandListener – expanding group
•OnGroupClickListener – press on group
now lets look at groupIndicater - indicator of the group state. it's placement pointed in main.xml with parameters indicatorLeft, indicatorRigh - corresponding to left and right border. by default the indicator placed on the left side, what is not so cool.
also we can add custom images, for that, we need to add indicator.xml in the folder drawable with this code.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_expanded="true"
android:drawable="#drawable/imageOpen">
</item>
<item android:state_empty="true"
android:drawable="#drawable/imageClose">
</item>
</selector>
where imageOpen is for expanded group
imageClose is for collapsed group
next time we need to add a row for parameters of our list in main.xml
android:groupIndicator="#drawable/indicator"

NullPointer Exception in custom ListView Adapter

I am getting a NullPointer Exception in custom ListView Adapter android application.
This is my custom class with a few variables and getter.
public class ViewClass {
String ItemName, Category, Amount, TotalAmount;
//get,set methods here
}
This is my Main Activity class.
public class ViewList extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ArrayList<ViewClass> details = new ArrayList<ViewClass>();
ViewClass[] v = new ViewClass[5];
for (int i = 0; i < 5; i++) {
v[i] = new ViewClass();
v[i].setItemName("Item Name");
v[i].setAmount("Rs 1111");
v[i].setCategory("cateGory");
v[i].setTotalAmount("aaaa");
details.add(v[i]);
}
ListView msgList = (ListView) findViewById(R.id.MessageList);
msgList.setAdapter(new CustomListAdapter(details, this));
// msgList.setOnItemClickListener(new OnItemClickListener() {
// public void onItemClick(AdapterView<?> a, View v, int position,
// long id) {
//
// String s = (String) ((TextView) v.findViewById(R.id.From))
// .getText();
// Toast.makeText(ViewList.this, s, Toast.LENGTH_SHORT).show();
// }
// });
}
}
This is the XML file for ListItem Layout, the name is list_item_trans
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/tvBGColor1"
android:layout_width="10dp"
android:layout_height="fill_parent"
android:background="#android:color/background_dark" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/space" />
<TextView
android:id="#+id/tvItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="#+id/tvAmount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/space" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/tvBGColor2"
android:layout_width="10dp"
android:layout_height="fill_parent"
android:background="#android:color/background_dark" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/space" />
<TextView
android:id="#+id/tvCat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp" />
<TextView
android:id="#+id/tvTotalAmount"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:textSize="12sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/space" />
</LinearLayout>
This is as the name suggests, the CustomListAdapter
public class CustomListAdapter extends BaseAdapter{
private ArrayList<ViewClass> _data;
Context _c;
CustomListAdapter(ArrayList<ViewClass> data, Context c) {
_data = data;
_c = c;
}
public int getCount() {
// TODO Auto-generated method stub
return _data.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return _data.get(position);
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) _c
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.list_item_message, null);
}
TextView tvItemName = (TextView) v.findViewById(R.id.tvItem);
TextView tvCategory = (TextView) v.findViewById(R.id.tvCat);
TextView tvAmount = (TextView) v.findViewById(R.id.tvAmount);
TextView tvTotalAmount = (TextView) v.findViewById(R.id.tvTotalAmount);
ViewClass msg = _data.get(position);
tvItemName.setText(msg.ItemName);
tvCategory.setText("Subject: " + msg.Category);
tvAmount.setText(msg.Amount);
tvTotalAmount.setText(msg.TotalAmount);
return v;
}
}
I am getting the error on in the getView method of the CustomListAdapter
tvItemName.setText(msg.ItemName);
This is the XML file for ListItem Layout, the name is list_item_trans
So The xml layout name is list_item_trans.xml
v = vi.inflate(R.layout.list_item_message, null);
You are inflating list_item_message.xml but your layout name is list_item_trans.xml
Maybee the error is here ?
List item layout is list_item_trans, but you are inflating list_item_message.
Change this line:
v = vi.inflate(R.layout.list_item_message, null);
Into this:
v = vi.inflate(R.layout.list_item_trans, null);
NullPointer Exception in custom ListView Adapter is caused
because you are inflating list_item_message.xml instead of list_item_trans.xml and initializing textviews from list_item_trans.xml
so just change
v = vi.inflate(R.layout.list_item_message, null);
To this
v = vi.inflate(R.layout.list_item_trans, null);

Categories

Resources