Reputation: 31
I am tying to find a way to combine the group view and the child views in a list like this
except that it will be an expandable list instead.
Thank you.
Upvotes: 3
Views: 1549
Reputation: 1483
I've taken the liberty to draw up some sample code for this. It made the most sense to just create your own custom view extending from ExpandableListView
(especially if you want the rounded corners), a custom adapter to handle the groups and children, and then have your main.xml
just include multiple custom views. As you can see from the screenshot, I've managed to reproduce it pretty closely.
So here's the code:
RoundedExpandableListView.java
public class RoundedExpandableListView extends ExpandableListView {
public RoundedExpandableListView(Context context) {
super(context);
}
public RoundedExpandableListView(Context context, AttributeSet attrs) {
super(context, attrs);
// for setting the background color and rounded corners
int bgColor = attrs.getAttributeIntValue("http://schemas.android.com/apk/res/android", "background", 0xffffff);
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.RoundedExpandableListView);
int radius = a.getInteger(R.styleable.RoundedExpandableListView_radius, 0);
PaintDrawable drawable = new PaintDrawable();
drawable.getPaint().setColor(bgColor);
drawable.setCornerRadius(radius);
setBackgroundDrawable(drawable);
a.recycle();
}
}
GroupedViewAdapter.java
public class GroupedViewAdapter extends BaseExpandableListAdapter {
private Context mContext;
private String[] mGroups;
private Object[][] mChildren;
private int mGroupLayoutId;
private int mChildLayoutId;
private Drawable mTitleDrawable;
public GroupedViewAdapter(Context c, String[] k, Object[][] v, int titleDrawableResId) {
this(c, k, android.R.layout.simple_expandable_list_item_1, v,
android.R.layout.simple_expandable_list_item_1, titleDrawableResId);
}
public GroupedViewAdapter(Context c, String[] k, int groupLayoutResId, Object[][] v,
int childLayoutResId, int titleDrawableResId) {
super();
mContext = c;
mGroups = k;
mChildren = v;
mGroupLayoutId = groupLayoutResId;
mChildLayoutId = childLayoutResId;
mTitleDrawable = mContext.getResources().getDrawable(titleDrawableResId);
mTitleDrawable.setBounds(0, 0, 48, 48); // not necessarily the best way, but just to show example
}
@Override
public int getGroupCount() {
return mGroups.length;
}
@Override
public int getChildrenCount(int groupPosition) {
return (mChildren[groupPosition] == null) ? 0 : mChildren[groupPosition].length;
}
@Override
public void onGroupCollapsed(int groupPosition) {
super.onGroupCollapsed(groupPosition);
}
@Override
public void onGroupExpanded(int groupPosition) {
super.onGroupExpanded(groupPosition);
}
@Override
public String getGroup(int groupPosition) {
return mGroups[groupPosition];
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return (mChildren[groupPosition] == null) ? null : mChildren[groupPosition][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) {
View v;
if (convertView != null) {
v = convertView;
} else {
LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = li.inflate(mGroupLayoutId, parent, false);
}
TextView tv = ((TextView) v);
tv.setText(getGroup(groupPosition));
tv.setTag(getGroupId(groupPosition));
// set title group special properties
if (groupPosition == 0) {
tv.setTextSize(20);
tv.setCompoundDrawables(mTitleDrawable, null, null, null);
} else if (isExpanded) {
tv.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.icon_expanded, 0);
} else {
tv.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.icon_collapsed, 0);
}
return tv;
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
View v;
if (convertView != null) {
v = convertView;
} else {
LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = li.inflate(mChildLayoutId, parent, false);
}
TextView tv = ((TextView) v);
tv.setText((String)getChild(groupPosition, childPosition));
tv.setTag(getChildId(groupPosition, childPosition));
return tv;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
MainActivity.java
public class MainActivity extends Activity {
private RoundedExpandableListView mContact;
private RoundedExpandableListView mAddress;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContact = (RoundedExpandableListView) findViewById(R.id.listview_contact);
mAddress = (RoundedExpandableListView) findViewById(R.id.listview_address);
mContact.setAdapter(new GroupedViewAdapter(this,
getResources().getStringArray(R.array.contact_list_items), // I chose to create this directly in XML, but you can generate it via Java like I did the children below
R.layout.drawer_list_item,
createChildList(),
R.layout.drawer_list_item,
R.drawable.ic_action_email));
mAddress.setAdapter(new GroupedViewAdapter(this,
getResources().getStringArray(R.array.address_list_items),
R.layout.drawer_list_item,
createChildList(),
R.layout.drawer_list_item,
R.drawable.ic_action_map));
mContact.setGroupIndicator(null); // since the adapter is changing how to show the group indicator icon
mAddress.setGroupIndicator(null); // since the adapter is changing how to show the group indicator icon
}
private String[][] createChildList() {
// Do stuff here to generate the list of children. Since the examples
// didn't have any, I didn't add any here.
return null; // Change this once you have children
}
}
res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res/com.example.sample"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#95c91d" >
<com.example.sample.RoundedExpandableListView
android:id="@+id/listview_contact"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginBottom="20dp"
android:paddingLeft="10dp"
android:background="#ffffff"
local:radius="20" />
<com.example.sample.RoundedExpandableListView
android:id="@+id/listview_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginBottom="20dp"
android:paddingLeft="10dp"
android:background="#ffffff"
local:radius="20"
android:layout_below="@+id/listview_contact" />
</RelativeLayout>
res/layout/drawer_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textSize="14sp"
android:text="test"
android:paddingTop="@dimen/list_item_margin"
android:paddingRight="@dimen/list_item_margin"
android:paddingBottom="@dimen/list_item_margin"
android:drawableLeft="@android:drawable/ic_menu_manage"
android:drawablePadding="12dp"
/>
res/values/attrs.xml (for creating custom attributes for your View
)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RoundedExpandableListView">
<attr name="radius" format="integer" />
</declare-styleable>
</resources>
res/values/strings.xml
<!-- stuff up here -->
<string-array name="contact_list_items">
<item name="item_title">Contact</item>
<item name="item_number">+41 41 41</item>
<item name="item_email">[email protected]</item>
<item name="item_website">www.website.com</item>
</string-array>
<string-array name="address_list_items">
<item name="item_title">Address</item>
<item name="item_address">xxxxxx\nxxxxxxxxxxx\nxxxxxxxxxx\nxxxxxxx</item>
<item name="item_other">PDF</item>
</string-array>
That should be it! Good luck!
Upvotes: 1