I have a custom listview with the following layout (list_single.xml):
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent" >
<TableRow android:layout_width="fill_parent">
<ImageView
android:id="#+id/img"
android:layout_width="64dp"
android:layout_height="64dp"/>
<TextView
android:id="#+id/txt"
android:textSize="24dp" android:textStyle="bold"
android:paddingTop="20dp" android:paddingLeft="10dp"
android:layout_width="fill_parent"
android:layout_height="64dp" />
</TableRow>
</TableLayout>
Then i have a CustomList extender class that is assigning this layout:
public class CustomList extends ArrayAdapter<String> {
private final Activity context;
private final String[] web;
private final Integer[] imageId;
public CustomList(Activity context,
String[] web, Integer[] imageId) {
super(context, R.layout.list_single, web);
this.context = context;
this.web = web;
this.imageId = imageId;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView= inflater.inflate(R.layout.list_single, null, true);
TextView txtTitle = (TextView) rowView.findViewById(R.id.txt);
ImageView imageView = (ImageView) rowView.findViewById(R.id.img);
txtTitle.setText(web[position]);
imageView.setImageResource(imageId[position]);
return rowView;
}
}
Then inside the OnCreate event handler i add a listener:
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
However the only clickable area in the row is the icon though i want the whole row to be clickable. I checked some other similar questions here but i couldn't find solution for the TableLayout.
Thank you so much
you should set
android:focusableInTouchMode="true"
android:focusable="true"
in your table layout. Generally its not a good idea to use table layout n row layout of listview. For your case, you could easily do that by any other layout e.g. linearlayout,relativelayout etc
Following yours suggestions i replaced Table with Relative layout and now everything works as expected. Thank you so much guys. It's much appreciated.
<?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">
<ImageView
android:id="#+id/img"
android:layout_width="64dp"
android:layout_height="64dp" android:paddingLeft="20dp" />
<TextView
android:id="#+id/txt"
android:textSize="24dp"
android:textStyle="bold"
android:paddingTop="20dp"
android:paddingLeft="84dp"
android:layout_width="fill_parent"
android:layout_height="64dp" />
</RelativeLayout>
Sorry for not being able to vote (it requires minimum 15 points which i do not have as i am n00b) THANK You so much for the help. It's much appreciated.
Related
My Problem is --> I put a white line as a view in the Fragment item xml but it doesn't appear when i debug it. How can i get the changes i make in the fragment item xml file. Because i tried some little changes like alpha property change but it didnt change is it because of this is a listview and has itself design? Please help me about that problem.
The xml code and adapter code are below.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="vertical"
android:gravity="center"
android:paddingTop="5dp"
>
<ImageView
android:id="#+id/menulogo"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/infoicon"
android:layout_gravity="center"
android:paddingTop="5dp"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="vertical"
android:gravity="center">
<TextView
android:id="#+id/txtMenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="Company Name"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_weight="1" />
</LinearLayout>
<View
android:id="#+id/line"
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_below="#+id/txtMenu"
android:background="#FFFFFF"
/>
</LinearLayout>
My listview adapter codes right down below.
public class MenuListAdapter extends ArrayAdapter<Menu_Item> {
private final ArrayList<Menu_Item> list;
private final Activity context;
private int[] colors = new int[]{0x34a4a4a4, 0x34fafafa};
public MenuListAdapter(Activity context, ArrayList<Menu_Item> list) {
super(context, R.layout.menu_item, list);
this.context = context;
this.list = list;
}
static class ViewHolder {
public ImageView menulogo;
public TextView txtMenu;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.menu_item, null);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.menulogo = (ImageView) view.findViewById(R.id.menulogo);
viewHolder.txtMenu = (TextView) view.findViewById(R.id.txtMenu);
view.setTag(viewHolder);
int colorPos = position % colors.length;
view.setBackgroundColor(colors[colorPos]);
} else {
view = convertView;
}
ViewHolder holder = (ViewHolder) view.getTag();
holder.txtMenu.setText(list.get(position).getMenuName());
//holder.menulogo.setImageBitmap(list.get(position).getMenuImage());
String menuName=list.get(position).getMenuName();
if (menuName.equals("Info")){
holder.menulogo.setImageResource(R.drawable.infoicon);
}
if (menuName.equals("Odalar")){
holder.menulogo.setImageResource(R.drawable.accomodation);
}
if (menuName.equals("Galeri")){
holder.menulogo.setImageResource(R.drawable.galeryicon);
}
if (menuName.equals("Aktiviteler")){
holder.menulogo.setImageResource(R.drawable.activitiesicon);
}
if (menuName.equals("Robin's Kids Club")){
holder.menulogo.setImageResource(R.drawable.kidsclub);
}
if (menuName.equals("Restaurants")){
holder.menulogo.setImageResource(R.drawable.restaurantsicon);
}
view.setId(list.get(position).getMenu_id());
return view;
}
#Override
public int getViewTypeCount() {
if (getCount() != 0)
return getCount();
return 1;
}
}
I found an answer to my question and wanted to share it with you.
I only used these 2 properties below of ListView
android:divider="#FFFFFF"
android:dividerHeight="1dip"
Like this...
<ListView
android:id="#+id/menuList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:divider="#FFFFFF"
android:dividerHeight="1dip"
/>
In ListView XML add these two lines
<ListView
android:divider="#android:color/white"
android:dividerHeight="5dip"
.
.
</ListView>
Try to change the View with id line for a Space component. It is an extension of View, and works better for what you want.
Here is a description of the widget:
https://developer.android.com/reference/android/widget/Space.html
I search a lot for an answer and didn't find one that suit me.
I found out that when I set my layout_heigh to 500dp -> all the item shown, but when it has normal size (layout_heigh=wrap_content) then only the first item is shown.
this is my code:
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Add Task"
android:onClick="addTask" />
<ListView android:id="#+id/myListView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawSelectorOnTop="false"/>
</LinearLayout>
xml_item.xml: this is for one item to duplicate in the listView
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants">
<TextView
android:layout_width="100dp"
android:layout_height="50dp"
android:id="#+id/itemText"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:padding="15dp"
android:textSize="20sp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/doneBtn"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"
android:text="Done" />
</RelativeLayout>
MyListAdapter: a class in the main_activity that extends the ArrayAdapter class so I can put in one row both TextView and a button.
private class MyListAdapter extends ArrayAdapter<String> {
private int layout;
public MyListAdapter(Context context, int resource, List<String> objects) {
super(context, resource, objects);
layout= resource;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder mainHolder= null;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView= inflater.inflate(layout, parent, false);
ViewHolder viewHolder= new ViewHolder();
viewHolder.item= (TextView) convertView.findViewById(R.id.itemText);
viewHolder.btn= (Button) convertView.findViewById(R.id.doneBtn);
viewHolder.btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getContext(), itemArray.get(position), Toast.LENGTH_SHORT).show();
}
});
convertView.setTag(viewHolder);
}
else {
mainHolder= (ViewHolder) convertView.getTag();
mainHolder.item.setText(getItem(position));
}
return convertView;
}
public class ViewHolder {
TextView item;
Button btn;
}
}
Thanks for all! :)
but when it has normal size (layout_heigh=wrap_content)
It is a very bad idea using a ListView by giving it a height=wrap_content.
This forces ListView to measure a few children out of the adapter at layout time, to know how big it should be.
You can check it your self debugging the getView() method inside the adapter.
In your case, using a LinearLayout just add a top margin (50dp as the Button) to your listView and use layout_heigh=match_parent.
Otherwise use a RelativeLayout.
Change your listview to take up as much room as is can considering the height of any sibling views (in this case your button). Here's how to do that with the android:layout_weight attribute
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Add Task"
android:onClick="addTask" />
<ListView android:id="#+id/myListView"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
</LinearLayout>
I use the following code to use the ArrayAdapter for my ListView:
ArrayList<String> mylist = new ArrayList<String>();
String xml = ParseXMLMethods.getXML();
Document doc = ParseXMLMethods.XMLfromString(xml);
NodeList children = doc.getElementsByTagName(KEY_ITEM);
for (int i = 0; i < children.getLength(); i++) {
Element e = (Element)children.item(i);
mylist.add(ParseXMLMethods.getValue(e, KEY_TITLE));
mylist.add(ParseXMLMethods.getValue(e, KEY_CITY));
mylist.add(ParseXMLMethods.getValue(e, KEY_COUNT));
}
adapter1=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
mylist);
list2.setAdapter(adapter1);
Here I am able to see only Title, but I want to see all three in my listView Row.For this I create another layout R.layout.list_layout2 as follows:
My layout
<?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="50dp"
android:paddingLeft="6dp"
>
<TextView
android:id="#+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:padding="1dp"
android:textSize="16dp"
android:textStyle="bold"
/>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="1dp"
android:textSize="12dp"
android:textColor="#000000" />
<TextView
android:id="#+id/subtitle2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:textSize="12dp"
android:textColor="#000000"
android:layout_toRightOf="#+id/subtitle" />
</RelativeLayout>
</LinearLayout>
How can I use this layout?
You're going to want to look at a Custom ListView Adapter. Note that your original code uses a custom ListView but not the Adapter. You're going to want to create your own Adapter that extends ArrayAdapter since your ListView row is more complex than just one TextView.
See Tutorial and enter link description here.
Ex:
list_row.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TableRow>
<ImageView
android:id="#+id/img"
android:layout_width="50dp"
android:layout_height="50dp"/>
<TextView
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="50dp" />
</TableRow>
</TableLayout>
CustomList.java
public class CustomList extends ArrayAdapter<String>{
private final Activity context;
private final String[] web;
private final Integer[] imageId;
public CustomList(Activity context, String[] web, Integer[] imageId) {
super(context, R.layout.list_single, web);
this.context = context;
this.web = web;
this.imageId = imageId;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView= inflater.inflate(R.layout.list_row, null, true);
TextView txtTitle = (TextView) rowView.findViewById(R.id.txt);
ImageView imageView = (ImageView) rowView.findViewById(R.id.img);
txtTitle.setText(web[position]);
imageView.setImageResource(imageId[position]);
return rowView;
}
}
In the example above, you're going to want to switch out the ImageView and replace it with your TextViews.
Copying other people's code that I only half understand, I have succeeded in making a listview, each element of which contains three TextViews and a CheckBox.
The code involves the following two xml files. First "customrowview.xml":
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="142dp"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView android:id="#+id/text1"
android:layout_width="match_parent"
android:layout_height="fill_parent"/>
<TextView android:id="#+id/text2"
android:layout_width="match_parent"
android:layout_height="fill_parent"/>
<TextView android:id="#+id/text3"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right" >
<CheckBox
android:id="#+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" />
<Button
android:id="#+id/editbut"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Edit" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
Then "customlistview.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"
>
<ListView android:id="#id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000fff"
android:layout_weight="2"
android:drawSelectorOnTop="false">
</ListView>
<TextView android:id="#id/android:empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFff00"
android:text="No data"
/>
</LinearLayout>
I get access to the list via:
listView = (ListView) findViewById(R.id.mylist);
The code also involves:
SimpleAdapter adapter = new SimpleAdapter(
this,
list,
R.layout.custom_row_view,
new String[] {"label","daysordate","time"},
new int[] {R.id.text1,R.id.text3, R.id.text2}
);
listView.setAdapter(adapter);
Now what I want to do is something like listView.setlistenerforbuttonwithinlist() !
But can not work out how to do it. I know there have been related questions on SO before, but I can not understand the answers :-(
EDIT: After seeing azgolfers answer... I made a custom adapter as follows:
public class myadapter extends SimpleAdapter
{
LayoutInflater mLayoutInflater;
public void myadapter(Context context)
{
mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View view = null;
if (convertView != null)
{
view = convertView;
}
else
{
view = mLayoutInflater.inflate(R.layout.custom_row_view, null);
}
Button buttonEdit = (Button) view.findViewById(R.id.editbut);
buttonEdit.setOnClickListener(new OnClickListener()
{
public void onClick(View arg0)
{
Log.i("xx","Button pressed!");
}
});
return super.getView(position, convertView, parent);
}
public myadapter(Context context, List<? extends Map<String, ?>> data,int resource, String[] from, int[] to)
{
super(context, data, resource, from, to);
// TODO Auto-generated constructor stub
}
}
Unfortunatly this crashes at the line
view = mLayoutInflater.inflate(R.layout.custom_row_view, null);
With a null pointer exception... not sure why :-(
First, you need to extend your own Adapter, probably from an ArrayAdapter. ArrayAdapter has a method called getView that you will need to override and provide the UI for a listview row at a certain position. e.g.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView != null) {
view = convertView;
} else {
view = mLayoutInflater.inflate(R.layout.custom_row_view, null);
}
Button buttonEdit = (Button) view.findViewById(R.id.editbut);
buttonEdit.setOnClickListener(...);
}
In getView(), since you are building the UI of the row, you have a chance here to set the click handler on your button.
Also, you also need to add this to your Button's xml tag:
android:focusable="false"
android:focusableInTouchMode="false"
Without that, button inside a listview will not fire OnClick event when pressed.
try to сhange
view = mLayoutInflater.inflate(R.layout.custom_row_view, null);
to
view = mLayoutInflater.inflate(R.layout.custom_row_view, parent, false);
Good luck!
I've faced a problem by adding a question for my questionnaire from res/values.
As I need a ListView followed by checkbox in each line, I've created a custom ListView.
This is my list_item.xml
I've deleted android:text="#string/textLarge" and "#string/textSmall" lines, that's why it has an empty line in TextView tags.
<LinearLayout android:id="#+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="2dp">
<TextView
android:id="#+id/textView_large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp">
</TextView>
<TextView
android:id="#+id/textView_small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp">
</TextView>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="2dp"
android:gravity="right">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/checkBxc">
</CheckBox>
</LinearLayout>
</LinearLayout>
and a simple list
<?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"
>
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"></ListView>
my Main.java file is next
public class Main extends ListActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setListAdapter(new MyAdapter(this,
android.R.layout.simple_list_item_2, R.id.textView_large,
getResources().getStringArray(R.array.questions)));
}
private class MyAdapter extends ArrayAdapter<String> {
public MyAdapter(Context context, int resource, int textViewResourceId,
String[] strings) {
super(context, resource, textViewResourceId, strings);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.list_item, parent, false);
String[] items = getResources().getStringArray(R.array.questions);
CheckBox chk = (CheckBox) row.findViewById(R.id.checkBxc);
TextView txtLarge = (TextView) row.findViewById(R.id.textView_large);
TextView txtSmall = (TextView) row.findViewById(R.id.textView_small);
txtLarge.setText(items[position]);
return row;
and it works correctly if I add an item from questions.xml, but it displays only 1 line, however I need to make a question as an item (i.e "Do you do some sports?") and some comment below (i.e "Check it if you do"). How could I do that?
You have to create a custom ArrayAdapter (a class that extends from ArrayAdapter) and set it for your list-view listView.setAdapter(yourAdapter)
In this adapter you have to override the getView method (to return your custom list-item-view).
See also this example:
http://android-codes-examples.blogspot.com/2011/03/customized-listview-items-selection.html
This piece:
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.list_item, parent, false);
is not good: you create new item view always, even if it already exists destroying excessive objects costs time. And you can use functionality of the ArrayAdapter itself. Look here.