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.
Related
I have a soundboard app, and I want to make a search bar so users can find the sounds by search. I have multiple tabs for the buttons. The buttons have different images, which are stored in an array. Each buton has textview below them, as a title. My questions is how to make a search bar so the users can find sounds from all of the 10 Tabs(around 300 sounds overall) at the same time? I have 10 Tabs so that means I have 30 arrays with different informations like the sound of the button, the image of the button, and the text for the textview below the buttons. Here are the codes:
single_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_height="match_parent">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/button"
android:longClickable="true"
android:onClick="werbung"
android:padding="0dp"
android:text=""
android:textColor="#ffffff"
android:textSize="17dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textview"
android:layout_width="0dp"
android:layout_height="42dp"
android:layout_below="#id/button"
android:layout_alignLeft="#id/button"
android:layout_centerInParent="true"
android:gravity="center"
android:text=""
android:textColor="#color/black"
android:textSize="17sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button" />
</android.support.constraint.ConstraintLayout>
The arrays containing the texts for the textview, and the sounds and images for the buttons in Tab1.java(all of the tabs' code is the same, just with different arrays):
public String[] items = {
"text1", "text2", "text3"
};
public static int[] soundfiles ={
R.raw.sound1, R.raw.sound2, R.raw.sound3
};
public static int[] images ={
R.drawable.image1, R.drawable.image2, R.drawable.image3
};
The buttons with the text below them are created from the single_item.xml with this code(this is also in the Tab.java):
// CustomGrid Adapter
public class CustomGridAdapter extends BaseAdapter {
private Context context;
private String[] items;
LayoutInflater inflater;
public CustomGridAdapter(Context c, String[] items) {
this.context = c;
this.items = items;
inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return items.length;
}
#Override
public Object getItem(int position) {
return items[position];
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.single_item, null);
}
Button button = (Button) convertView.findViewById(R.id.button);
TextView textView = (TextView) convertView.findViewById(R.id.textview);
textView.setText(items[position]);
button.setBackgroundResource(images[position]);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (context instanceof MainActivity) {
((MainActivity) context).TabEightItemClicked(position);
}
}
});
return convertView;
}
}
Tab 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"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="#+id/tab1">
<GridView
android:background="#ffffff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tabOneGridView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:numColumns="auto_fit"
android:horizontalSpacing="0dp"
android:verticalSpacing="0dp"
android:columnWidth="155dp"
android:stretchMode="spacingWidthUniform"/>
</RelativeLayout>
Tab design: https://i.stack.imgur.com/NlC09.png
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've working on ListView with a custom BaseAdapter which I've watched on the Slidenerd tutorial series here:(It's not important to watch to understand my question)
http://www.youtube.com/watch?v=_l9e2t4fcfM&list=PLonJJ3BVjZW6hYgvtkaWvwAVvOFB7fkLa&index=91
After running the code on the virtual device there is no error but not ListView too.
Is it possible to tell me what's the problem of my code?
public class List extends Activity {
ListView lv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
lv = (ListView) findViewById(R.id.listView);
lv.setAdapter(new EhsanAdapter(this));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.list, menu);
return true;
}
}
class SingleRow{
String title;
String description;
int image;
public SingleRow(String title,String description,int image) {
this.title = title;
this.description=description;
this.image=image;
}
}
class EhsanAdapter extends BaseAdapter{
ArrayList<SingleRow> list;
Context context;
public EhsanAdapter(Context c) {
list = new ArrayList<SingleRow>();
context = c;
Resources res = c.getResources();
String[] titles = res.getStringArray(R.array.titles);
String[] descriptions = res.getStringArray(R.array.descriptions);
int[] images = {R.drawable.image1,R.drawable.image2,R.drawable.image3,R.drawable.image4,R.drawable.image5};
for(int i=0;i<10;i++){
list.add(new SingleRow(titles[i], descriptions[i], images[i]));
}
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int i) {
return list.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.single_row, viewGroup,false);
TextView title = (TextView) row.findViewById(R.id.txtTitle);
TextView description = (TextView) row.findViewById(R.id.txtDescription);
ImageView image = (ImageView) row.findViewById(R.id.imgPic);
SingleRow temp = list.get(i);
title.setText(temp.title);
description.setText(temp.description);
image.setImageResource(temp.image);
return row;
}
}
The layout of activity:
<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: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=".List" >
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
</RelativeLayout>
The layout of single row:
<?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" >
<ImageView
android:layout_margin="10dp"
android:id="#+id/imgPic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:src="#drawable/image1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Title"
android:id="#+id/txtTitle"
android:layout_alignTop="#+id/imgPic"
android:layout_toRightOf="#+id/imgPic"
android:layout_alignParentRight="true">
</TextView>
<TextView
android:id="#+id/txtDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/imgPic"
android:layout_marginLeft="25dp"
android:layout_toRightOf="#+id/imgPic"
android:layout_marginTop="20dp"
android:text="Description"
android:ems="10">
</TextView>
</RelativeLayout>
Remove the line LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); from getView() method and instead add it in the constructor of EhsanAdapter class.
I see different issues:
The layout of single row contains a relative layout which the android:layout_height="match_parent" should be android:layout_height="wrap_content"
Then inside the Adapter you are neither recycling the views nor using the ViewHolder pattern:
http://developer.android.com/training/improving-layouts/smooth-scrolling.html
About ViewHolder pattern implementation optimisation in ListView
http://www.jmanzano.es/blog/?p=166
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null){ //The row view is not created, let's do it:
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.single_row, viewGroup,false);
TextView title = (TextView) row.findViewById(R.id.txtTitle);
TextView description = (TextView) row.findViewById(R.id.txtDescription);
ImageView image = (ImageView) row.findViewById(R.id.imgPic);
// Here we add the title, description and image inside the ViewHolder
....
}else{
//With the View holder pattern we get the views inside the row view to fill it later
....
}
// Now we get the SingleRow and we fill it using the ViewHolder pattern
SingleRow temp = list.get(i);
....
return row;
}
You only have 5 images and you wrote i<10 you should've wrote i<5 the amount of "titles" and "descriptions" and "images" must be the same.
for(int i=0;i<5;i++){
list.add(new SingleRow(titles[i], descriptions[i], images[i]));
}
I'm just getting my feet wet with Android and have built a UI that contains a TabHost with three tabs. Each tab is powered by its own Activity. The first Tab contains a listview with a prepopulated set of rows and is built from a custom ArrayAdapter.
The problem I'm running into is that none of the ListView rows are tappable. In other words, when I tap on them there is no orange selection. If I use the scroll ball on my Nexus One it will select, but any touch gestures don't seem to be responding.
All the UI is being handled using XML files with a main.xml housing the TabHost -> LinearLayout -> TabWidget/FrameLayout and a nearby_activity.xml file containing my ListView UI
<?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:id="#+id/android:empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="#string/nearby_no_events"
/>
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1.0"
android:choiceMode="multipleChoice"
android:divider="#d9d9d9"
android:dividerHeight="1px"
android:cacheColorHint="#eee"
/>
</LinearLayout>
And the relevant code from my Activity that is set to show in the selected tab.
public class NearbyActivity extends ListActivity
{
private ArrayList<Event> m_events = null;
private EventAdapter m_adapter = null;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.nearby_activity);
getEvents();
this.m_adapter = new EventAdapter(this, R.layout.eventrow, m_events);
setListAdapter(this.m_adapter);
}
private void getEvents()
{
m_events = new ArrayList<Event>();
for (int i = 0; i < 100 ; i++)
{
Event e = new Event();
e.setEventName("Event " + i);
e.setVenueName("Staples Center");
e.setStartDate(new Date());
m_events.add(e);
}
}
private class EventAdapter extends ArrayAdapter<Event>
{
private ArrayList<Event> items;
public EventAdapter(Context context, int textViewResourceId, ArrayList<Event> items)
{
super(context, textViewResourceId, items);
this.items = items;
}
#Override
public View getView (int position, View convertView, ViewGroup parent)
{
View v = convertView;
if (v == null)
{
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.eventrow, null);
}
Event e = items.get(position);
if (e != null)
{
TextView nameText = (TextView)v.findViewById(R.id.eventName);
TextView venueNameText = (TextView)v.findViewById(R.id.venueName);
if (nameText != null)
{
nameText.setText(e.getEventName());
}
if(venueNameText != null)
{
venueNameText.setText(e.getVenueName());
}
}
return v;
}
}
}
My listview row's are populated by an XML file as well.
<?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="?android:attr/listPreferredItemHeight"
android:orientation="vertical"
android:padding="4dip">
<TextView
android:id="#+id/eventName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:inputType="text"
android:singleLine="true"
android:ellipsize="marquee"
android:textSize="18sp"
android:textColor="#000"
/>
<TextView
android:id="#+id/venueName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/eventName"
android:layout_alignParentBottom="true"
android:layout_marginRight="55dip"
android:singleLine="true"
android:ellipsize="end"
android:scrollHorizontally="true"
android:textSize="13sp"
android:textColor="#313131"
android:layout_alignWithParentIfMissing="true"
android:gravity="center_vertical"
/>
</RelativeLayout>
Thanks for any help you can offer.
You want a Listview tappable, well you need implement the method onListItemClick()
#Override
protected void onListItemClick(ListView l, View v, final int position, long id) {
super.onListItemClick(l, v, position, id);
Toast.makeText(this, "This is my row number " + position,Toast.LENGTH_LONG).show();
}
and to ensure the orange colour you must set the property
android:focusable="false"
in your Listview Row.xml