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"
Related
I am developing an app where I show a dropdownlist using a spinner.
I used a custom adapter, here is the code:
public class DemandeCongeAdapter extends BaseAdapter {
public static final String TAG = "DemandeCongeAdapter";
private final Context mContext;
private List<DemandeCongeType> mData;
protected LayoutInflater mInflater;
public DemandeCongeAdapter(Context mContext, List<DemandeCongeType> mData) {
this.mContext = mContext;
this.mData = mData;
this.mInflater = LayoutInflater.from(mContext);
}
static class ViewHolder {
public ViewHolder(View v) {
typedeDemandeName = (TextView) v.findViewById(R.id.type_demande_name);
}
protected final TextView typedeDemandeName;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public DemandeCongeType getItem(int position) {
return mData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.layout_create_demande_conge_custom_spinner, parent, false);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
if (position != 0) {
DemandeCongeType item = getItem(position);
String name = item.getTypdeDemandeName() == null ? "" : item.getTypdeDemandeName();
viewHolder.typedeDemandeName.setText(name);
}
return convertView;
}
}
And for the activity code, here is it:
private List<DemandeCongeType> congeTypes;
private DemandeCongeAdapter spinnerCongeTypeArrayAdapter;
congeTypes.addAll(new ArrayList<>((List<DemandeCongeType>) responseBody));
congeTypes.add(0, new DemandeCongeType());
spinnerCongeTypeArrayAdapter = new
DemandeCongeAdapter(DemandeCongeNewActivity.this, congeTypes);
congeTypeSpinner.setAdapter(spinnerCongeTypeArrayAdapter);
congeTypeSpinner.setSelection(Adapter.NO_SELECTION, false);
Everything works fine, but when I select the spinner for the first time, it shows the list correctly like this:
Once I click outside the spinner and I click for the second time on the spinner, I got it like this:
So I can't the find the problem, please if anyone can help me with that.
Here is the XML code:
<Spinner
android:id="#+id/spinner_type_conge"
fontPath="fonts/light.otf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:background="#null"
android:dropDownWidth="match_parent"
android:ellipsize="end"
android:lines="1"
android:paddingRight="2dp"
android:spinnerMode="dropdown"
android:textSize="13sp" />
And for the spinner item xml:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/type_demande_name"
fontPath="fonts/light.otf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:lines="1"
android:padding="10dp"
android:textColor="#color/annuaire_hint_color"
android:textSize="13sp" />
Try This way i have use this in my Application.
XML Design Code.
Spinner set in your Activity
<Spinner
android:id="#+id/sp_pen_Category"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:background="#android:color/transparent"
android:padding="#dimen/margin_10" />
This file XML File sp_list.xml
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:ellipsize="marquee"
android:padding="15dp"
android:singleLine="true"
android:textColor="#color/black"
android:textSize="#dimen/sub_title">
</CheckedTextView>
This file XML File sp_items.xml
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:ellipsize="marquee"
android:singleLine="true"
android:textColor="#color/black">
</CheckedTextView>
This is Java code when you fill spinner.
ArrayAdapter<String> adp_sp = new ArrayAdapter<String>(Activity.this, R.layout.sp_items, arr_spinner);
adp_sp.setDropDownViewResource(R.layout.sp_list);
sp_pen_Category.setAdapter(adp_sp);
Okay, so I've been looking far and wide, I've been able to add the same child item to every group, but I'm unable to get it to respond to clicks. Right now it's acting like a child header, and I need it to act like the other child items.
Currently my lists are being populated from a HashMap that is located in another file. Because you cannot add to the middle of a HashMap without completely rebuilding it, I figured the best option was to add the child somewhere when the list is being accessed within the adapter. I'm just not sure where or how.
As you can see from the getChildView() I add my repeating child layout (expandedListItemChildHeader), if the position of child is 0. I also added 1 value to the size of the getChildrenCount().
Here's my adapter code:
public class CustomExpandableListAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> expandableListTitle;
private HashMap<String, List<String>> expandableListDetail;
public CustomExpandableListAdapter(Context context, List<String> expandableListTitle,
HashMap<String, List<String>> expandableListDetail) {
this.context = context;
this.expandableListTitle = expandableListTitle;
this.expandableListDetail = expandableListDetail;
}
#Override
public Object getChild(int listPosition, int expandedListPosition) {
return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
.get(expandedListPosition);
}
#Override
public long getChildId(int listPosition, int expandedListPosition) {
return expandedListPosition;
}
#Override
public View getChildView(int listPosition, final int expandedListPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//if we're in the first position then add the list_item_header
if(expandedListPosition == 0)
{
convertView = layoutInflater.inflate(R.layout.list_item_header, null);
TextView expandedListTextView = (TextView) convertView.findViewById(R.id.expandedListItemChildHeader);
expandedListTextView.setText("All Devices");
}
//otherwise add the list_item
if (expandedListPosition > 0 && expandedListPosition < getChildrenCount(listPosition)) {
final String expandedListText = (String) getChild(listPosition, expandedListPosition - 1);
convertView = layoutInflater.inflate(R.layout.list_item, null);
TextView expandedListTextView = (TextView) convertView.findViewById(R.id.expandedListItem);
expandedListTextView.setText(expandedListText);
}
return convertView;
}
#Override
public int getChildrenCount(int listPosition) {
//add a value of one to the size of the count of children per group to make
//room for the child header
return (this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
.size() + 1);
}
#Override
public Object getGroup(int listPosition) {
return this.expandableListTitle.get(listPosition);
}
#Override
public int getGroupCount() {
return this.expandableListTitle.size();
}
#Override
public long getGroupId(int listPosition) {
return listPosition;
}
#Override
public View getGroupView(int listPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String listTitle = (String) getGroup(listPosition);
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list_group, null);
}
TextView listTitleTextView = (TextView) convertView
.findViewById(R.id.listTitle);
listTitleTextView.setTypeface(Typeface.create("sans-serif-medium", Typeface.NORMAL));
listTitleTextView.setText(listTitle);
//Use this conditional to change direction of group indicator icons
//the ImageView in the xml layout is invisible by default.
ImageView groupIndicatorView = (ImageView) convertView.findViewById(R.id.expand_GroupIndicator);
if (getChildrenCount(listPosition) == 0 ) {
groupIndicatorView.setVisibility( View.INVISIBLE );
}
else {
groupIndicatorView.setVisibility( View.VISIBLE );
groupIndicatorView.setImageResource( isExpanded ? R.drawable.ic_expand_less_black_24dp : R.drawable.ic_expand_more_black_24dp );
}
return convertView;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isChildSelectable(int listPosition, int expandedListPosition) {
return true;
}
Following is my expandable list code in my MainActivity which is located in the onCreate() method: (note: the variables listed at the top of the below sample code is outside of the onCreate() method, I just included it for reference.
ExpandableListView expandableListView;
ExpandableListAdapter expandableListAdapter;
List<String> expandableListTitle;
HashMap<String, List<String>> expandableListDetail;
expandableListView = (ExpandableListView) findViewById(R.id.navDrawer_userListView);
expandableListDetail = ExpandableListDataPump.getData();
expandableListTitle = new ArrayList<String>(expandableListDetail.keySet());
expandableListAdapter = new CustomExpandableListAdapter(this, expandableListTitle, expandableListDetail);
expandableListView.setAdapter(expandableListAdapter);
expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
//initialize int var
int previousGroup = 0;
#Override
public void onGroupExpand(int groupPosition) {
//this conditional enables only one drop down group to open at a time
if(groupPosition != previousGroup)
expandableListView.collapseGroup(previousGroup);
previousGroup = groupPosition;
Toast.makeText(
getApplicationContext(),
expandableListTitle.get(groupPosition)
+ " List Expanded.",
Toast.LENGTH_SHORT
).show();
}
});
expandableListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
#Override
public void onGroupCollapse(int groupPosition) {
Toast.makeText(getApplicationContext(),
expandableListTitle.get(groupPosition) + " List Collapsed.",
Toast.LENGTH_SHORT
).show();
}
});
expandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
v.setSelected(true);
//Change title on toolbar to match group selection
getSupportActionBar().setTitle(expandableListTitle.get(groupPosition) + "'s Devices");
//Change subtitle on toolbar to match item selection
//must offset child position by 1 to have room for child header
getSupportActionBar().setSubtitle((String)expandableListAdapter.getChild(groupPosition, childPosition - 1));
Toast.makeText(
getApplicationContext(),
expandableListTitle.get(groupPosition)
+ " -> "
+ expandableListDetail.get(
expandableListTitle.get(groupPosition)).get(
childPosition - 1), Toast.LENGTH_SHORT
).show();
return false;
}
});
Here are my layouts
starting with the list_item_header.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="wrap_content">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="7dp">
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#null"
android:id="#+id/toggle_allDevices"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:paddingLeft="2dp"
android:tint="#color/drawerContent"/>
<TextView
android:id="#+id/expandedListItemChildHeader"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#drawable/expandable_text_selector"
android:paddingLeft="65dp"
android:paddingTop="16dp"
android:textSize="16dp"
android:paddingBottom="16dp" />
</RelativeLayout>
</LinearLayout>
Here is my list_item.xml layout
<?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="wrap_content">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="7dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#null"
android:id="#+id/deviceTypeIcon"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:paddingLeft="14dp"
android:tint="#color/drawerContent"/>
<TextView
android:id="#+id/expandedListItem"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#drawable/expandable_text_selector"
android:paddingLeft="65dp"
android:paddingTop="16dp"
android:textSize="16dp"
android:paddingBottom="16dp" />
</RelativeLayout>
</LinearLayout>
The list_group.xml layout
<?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">
<View
android:layout_width="match_parent"
android:layout_height="0.25dp"
android:layout_alignParentTop="true"
android:background="#color/drawerContent" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="7dp">
<TextView
android:id="#+id/listTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:textColor="#color/drawerContent"
android:background="#color/drawerBg"
android:paddingTop="16dp"
android:textSize="16dp"
android:paddingBottom="16dp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/expand_GroupIndicator"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:src="#drawable/ic_expand_more_black_24dp"
android:paddingRight="15dp"
android:tint="#color/drawerContent"
android:visibility="invisible"/>
</RelativeLayout>
</LinearLayout>
And finally the snippet of my NavigationView from
the main activity:
<android.support.design.widget.NavigationView
android:background="#color/drawerBg"
app:itemTextColor="#color/drawerContent"
app:itemIconTint="#color/drawerContent"
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true">
<ExpandableListView
android:id="#+id/navDrawer_userListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#color/drawerContent"
android:textColor="#color/drawerContent"
android:background="#color/drawerBg"
android:dividerHeight="#null"
android:paddingTop="?attr/actionBarSize"
android:layoutDirection="rtl"
android:choiceMode="singleChoice"
android:groupIndicator="#null">
</ExpandableListView>
</android.support.design.widget.NavigationView>
Any help would be greatly appreciated! Thanks!
Okay, I was able to solve the last part of my issue. it turns out that all I had to do is put a conditional in my onChildClick() method to adjust for which index I was accessing using the following code:
//this conditional corrects for our new child header that is added in getChildView()
String newChildSelect = "";
if (childPosition == 0) {
newChildSelect = "All Devices";
getSupportActionBar().setSubtitle(newChildSelect);
}
else
{
newChildSelect = expandableListDetail.get(expandableListTitle.get(groupPosition)).get(childPosition - 1);
//Change subtitle on toolbar to match item selection
getSupportActionBar().setSubtitle((String)expandableListAdapter.getChild(groupPosition, childPosition - 1));
}
I Want Something Like Shown In Image Below... As Item 3, Item 4 And Item 7 Has A Toggle Switch But Item 1, Item 2, Item 5, Item 6 Doesn't Have. Can Anyone Help Me To Make This Layout And Make Toggle Switch Work Too
I Want This (Made In Photoshop)
My Java File
import android.content.*;
import android.view.*;
import android.widget.*;
class CustomSettingsAdapter extends ArrayAdapter<String> {
String[] settingItems = {
"Themes",
"Entry Tune",
"Remember Last Location",
"About Us",
"Exit"
};
public CustomSettingsAdapter(Context context, String[] Items) {
super(context, R.layout.main_settings_listview, Items);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
View customView = layoutInflater.inflate(R.layout.main_settings_listview, parent, false);
String itemName = getItem(position);
TextView textView =(TextView) customView.findViewById(R.id.itemName);
Switch mButton = (Switch) customView.findViewById(R.id.Switch);
if (position == 1 || position == 2) {
mButton.setVisibility(View.VISIBLE);
}
textView.setText(settingItems[position]);
return customView;
}
}
** XML **
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp"
android:minHeight="48dp"
android:id="#+id/mainActivityListBackground"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Item Number"
android:id="#+id/itemName"
android:layout_marginLeft="5dp"
android:textSize="18sp"
android:layout_centerVertical="true"
/>
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/Switch"
android:visibility="invisible"
android:layout_alignParentRight="true"
/>
</RelativeLayout>
</RelativeLayout>
Use this code it help you.
item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/code"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_weight="1"
android:textSize="16dp" />
<Switch
android:id="#+id/toggleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:gravity="center"
android:text="Off"
android:visibility="invisible" />
</LinearLayout>
and use this adapter
public class PhoneAdapter extends BaseAdapter {
private Context context;
public PhoneAdapter(Context context) {
this.context = context;
}
#Override
public int getCount() {
return 7;
}
#Override
public Object getItem(int i) {
return i;
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(final int i, View convertView, ViewGroup viewGroup) {
convertView = View.inflate(context, R.layout.item, null);
TextView mCode = (TextView) convertView.findViewById(R.id.code);
Switch mButton = (Switch) convertView.findViewById(R.id.toggleButton);
mCode.setText("item"+i+1);
if (i == 2 || i == 3 || i == 6)
mButton.setVisibility(View.VISIBLE);
return convertView;
}}
and this is output:-
feel free to ask if you stuck anywhere in between.
EDIT:- getView() is use for identify which button is clicked so you don't want to care about it .In the getView() the i variable is used for identify which item is clicked.
Just set your OnchangeListner inside getView() and your problem solve.
You can use recycler view.You can do this by creating two xml for two different designs,and on basis of condition you can set view in layout inflater.Use these methods for extra views.
#Override
public int getViewTypeCount() {
return VIEW_TYPE_COUNT;
}
#Override
public int getItemViewType(int position) {
return position;
}
You can also refer to this link.
Can you help me identify why there is a space between the group and the child? In my case I want spaces between all groups and the child should be right below the group with no space (but of course space to the next group. My problem looks like this:
I have set the Group divider to this drawable (expandable_list_group_divider):
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size android:height="10dp"/>
</shape>
And the child divider to this (#drawable/expandable_list_child_divider):
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size android:height="0dp"/>
</shape>
I have defined the layout like this in the xml(it is a compund control):
<com.jws.MyExpandableListView
android:id="#+id/expList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:scrollbars="none"
android:divider="#drawable/expandable_list_group_divider"
android:childDivider="#drawable/expandable_list_child_divider"/>
The custom view class:
public class MyExpandableListView extends ExpandableListView {
protected ArrayList<Departure> departures;
public MyExpandableListView(Context context, AttributeSet attrs) {
super(context, attrs);
setGroupIndicator(null);
setChildIndicator(null);
setHorizontalFadingEdgeEnabled(true);
setVerticalFadingEdgeEnabled(true);
setFadingEdgeLength(60);
departures = new ArrayList<Departure>();
this.setAdapter(new MyExpandableListAdapter(context, this, departures));
}
}
And finally the expandable list adapter
public class DeparturesExpandableListAdapter extends BaseExpandableListAdapter {
private final int DIVIDER_HEIGHT = 20;
private LayoutInflater inflater;
private ArrayList<Departure> departures;
private Context context;
private ExpandableListView expListView;
public DeparturesExpandableListAdapter(Context context, ExpandableListView expListView, ArrayList<Departure> departures)
{
this.context = context;
inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
this.departures = departures;
this.expListView = expListView;
}
// This Function used to inflate parent rows view
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parentView)
{
final Departure departure = departures.get(groupPosition);
if(!isExpanded)
expListView.setDividerHeight(DIVIDER_HEIGHT);
else
expListView.setDividerHeight(-4);
expListView.setFooterDividersEnabled(false);
// Inflate grouprow.xml file for parent rows
convertView = inflater.inflate(R.layout.view_departure_overview, parentView, false);
//Data handling in the view...
return convertView;
}
// This Function used to inflate child rows view
#Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
View convertView, ViewGroup parentView)
{
final Departure departure = departures.get(groupPosition);
if(isLastChild)
expListView.setDividerHeight(DIVIDER_HEIGHT);
// Inflate childrow.xml file for child rows
convertView = inflater.inflate(R.layout.view_departure_details, parentView, false);
//Data handling...
return convertView;
}
#Override
public Object getChild(int groupPosition, int childPosition)
{
return departures.get(groupPosition);
}
//Call when child row clicked
#Override
public long getChildId(int groupPosition, int childPosition)
{
return childPosition;
}
#Override
public int getChildrenCount(int groupPosition)
{
return 1;
}
#Override
public Object getGroup(int groupPosition)
{
return departures.get(groupPosition);
}
#Override
public int getGroupCount()
{
if(departures != null)
return departures.size();
return 0;
}
//Call when parent row clicked
#Override
public long getGroupId(int groupPosition)
{
return groupPosition;
}
#Override
public void notifyDataSetChanged()
{
// Refresh List rows
super.notifyDataSetChanged();
}
#Override
public boolean isEmpty()
{
return ((departures == null) || departures.isEmpty());
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition)
{
return false;
}
#Override
public boolean hasStableIds()
{
return false;
}
#Override
public boolean areAllItemsEnabled()
{
return true;
}
}
Image for comments:
this is tested and is proven to work, i wanted to come back to this even months later because none of the other methods gave me results quite how i wanted them. these are displayed exactly how OP (and myself) wanted
this is my groups or categories or whatever. basically the first linear layout is just a wrapper for a view which acts as a spacer between the categories, and then another linear layout that handles all my formatting
in the ExpandableListView(not shown) i have the divider height set to 0. the spacing is instead handled by the views
<?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="wrap_content"
android:orientation="vertical">
<View
android:layout_width="fill_parent"
android:layout_height="6dp"
android:background="#android:color/transparent"/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp"
android:background="#50601CBA">
<TextView
android:id="#+id/lblListHeader"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="17dp"
android:textColor="#FFFFFF" />
</LinearLayout>
</LinearLayout>
then in the child i have this.
<?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="55dip"
android:orientation="vertical" >
<TextView
android:id="#+id/lblListItem"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="12sp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:textColor="#FFFFFF"
android:background="#50601CBA"
/>
</LinearLayout>
I used the following settings in the xml file and there is no gap between the parent and the child.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#f4f4f4" >
<ExpandableListView
android:id="#+id/expListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/bg_black"
android:divider="#FF8800"
android:dividerHeight="2px" />
</RelativeLayout>
Most probably this is an issue with a margin setting you've got.
In order to remove dividers just from the child views and not between the parents in the expandable List:
add android:childDivider="#00000000" in the ExapandableListView attributes in XML:
<ExpandableListView
android:id="#+id/elv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:childDivider="#00000000"
android:dividerHeight="0dp"
/>
Refer http://qtcstation.com/2011/03/working-with-the-expandablelistview-part-1/
Remove all the margins and divider height, and instead add a blank space on top of groupview itself. It should do the trick.
Assuming that you want spacing between the parents, but not between parent & child.
I have failed to find a proper way of achieving it. So I did a not a smart fix, by not setting the divider height, instead since I had a custom layout for every parent item, I added a LinearLayout with a fixed height of 25dp at the top of my custom parent layout, as a result I could achieve the desire functionality, but there was a side effect , when you touch the list item, the spacing as well as the list item both are highlighted on touch.
Use negative margin for child view in view_departure_details.Something like this:
<TextView
android:id="text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="-10dp"
android:text="#string/my_best_text"
android:background="#FF0000"
/>
I know some people consider it a bad practice to use negative margin but right it seems to be the easiest way.
Other way(the time-consuming way) is to implement you own expandable listview so that you have more control on how things are drawn.
Set the child view programmatically like:
expandableListView.setDividerHeight(1);
expandableListView.setChildDivider(new ColorDrawable(Color.Black);
And group view From xml like :
<TextView
android:id="#+id/tv_title_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="#+id/iv_arrow"
android:layout_width="20dp"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_height="20dp"
/>
<View
android:id="#+id/header_view"
android:layout_width="match_parent"
android:layout_marginTop="10dp"
android:layout_alignParentBottom="true"
android:layout_height="1dp" />
You can set Transparency between them like..
android:childDivider="#android:color/transparent"
Modify the view's padding in the method public View getChildView() using the setPadding() method of the view.
Example:
#Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
View convertView, ViewGroup parentView){
final Departure departure = departures.get(groupPosition);
if(isLastChild)
expListView.setDividerHeight(DIVIDER_HEIGHT);
// Inflate childrow.xml file for child rows
convertView = inflater.inflate(R.layout.view_departure_details, parentView, false);
//Data handling...
convertView.setPadding(0, 0, 0, 0);
return convertView;
}
In the same way, if you want modify padding of the group, you will have to modify the padding in the getGroupView() method.
Just set the child background color as same of exandableListView
example:
<ExpandableListView
android:id="#+id/expandableListView"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:indicatorLeft="#null"
android:clipChildren="true"
android:background="#color/colorGrayTransparent"
/>
and child item color like this :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:layout_marginBottom="12dp"
android:background="#color/colorGrayTransparent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
....
</LinearLayout>
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.