android list inside layout - android

i am working on an Android app that needs showing a list[table], inside the layout[view]
I come from iPhone dev objC land, and i have an app that shows a table[list] inside the view[layout]
So how to show a list inside my layout, and place it to specified location [center],
ps. I havent found a list in the graphical layout editor of the xml, where is the list[table]?
2. I have done some tests with list views, but is a view, that replace the xml view, i want it inside my xml,,
thanks a lot!

Yes, of course, you can do that
1) you need to have listholder.xml here, you can scratch anything in you layout view, either imageview, textview..etc. just don't forget to add ListView inside it. for example:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/head_logo_bg">
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/background_label">
<TextView
android:id="#+id/city_txt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_gravity="center"
android:text="Sydney"
android:textStyle="bold"
android:textSize="17sp"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="40sp">
<ListView
android:id="#android:id/list"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_centerVertical="true"
android:scrollingCache="false"/>
</LinearLayout>
2) For custom your own list item, you have to create listitem.xml i.e.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/listitemone"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10sp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="vertical">
<ImageView android:id="#+id/user_image"
android:layout_width="80px" android:layout_height="80px"
android:layout_alignParentLeft="true"
android:layout_marginRight="5px"
android:src="#drawable/icon"
/>
</LinearLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="5sp"
android:orientation="vertical">
<TextView
android:id="#+id/date_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/date"
android:textStyle="bold"
android:textSize="16sp" />
<TextView
android:id="#+id/date_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignBaseline="#id/date_label"
android:layout_marginRight="20sp"
android:textColor="#FFF"
android:text="MM/dd/YYYY"
android:textStyle="bold"
android:textSize="16sp" />
</RelativeLayout>
</LinerLayout>
3) create customAdapter in your activity, it would look like this;
public class MyListActivity extends ListActivity {
private ArrayList<Yourdata> yourdata = new ArrayList<Youdata>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listholder);
// yourdata might be array, arraylist etc.
MyCustomAdapter listadapter = new MyCustomAdapter(this, R.layout.listitem, yourdata);
setListAdapter(listadapter);
}
private class MyCustomAdapter extends ArrayAdapter<Yourdata>{
//this case, i use Yourdata as type
private ArrayList<Yourdata> items;
public PreviousAdapter(Context context, int textViewResourceId,
ArrayList<Yourdata> 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.listitem, null);
}
Yourdata yt = items.get(position);
if(yt != null){
// Don't forget to use v.findView...., otherwise, it might force close when run app.
TextView dateStr = (TextView)v.findViewById(R.id.date_value);
dateStr.setText(yt.getDate());
}
return v;
}
}
}
P.S. the above code might not exactly right... just give you an idea :)
Here is a source about custom list (you might have seen it) hope it useful
http://www.vogella.de/articles/AndroidListView/article.html

I have try these example it's very nice.
you can get the example from
http://www.codeproject.com/Articles/507651/Customized-Android-ListView-with-Image-and-Text?msg=4567162#xx4567162xx

Related

Why Custom ArrayAdapter not showing TextView in a ListView

I have made a custom ArrayAdapter and tried to add the another TextView "Breed" of the animals, but when i execute the program , its not showing the Breed. Where am i doing wrong ? I am scratching my head since long. please help where is the mistake ?
MainActivity.Java
public class MainActivity extends AppCompatActivity {
ListView simpleList;
ArrayList<Item> animalList=new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
simpleList = (ListView) findViewById(R.id.simpleListView);
animalList.add(new Item("Lion",R.drawable.lion,"Khatarnak"));
animalList.add(new Item("Tiger",R.drawable.tiger,"Fudu"));
animalList.add(new Item("Monkey",R.drawable.monkey,"Lallu"));
animalList.add(new Item("Elephant",R.drawable.elephant,"Jabardast"));
animalList.add(new Item("Dog",R.drawable.dog,"ItemDog"));
animalList.add(new Item("Cat",R.drawable.cat,"MeeMee"));
MyAdapter myAdapter=new MyAdapter(this,R.layout.list_view_items,animalList);
simpleList.setAdapter(myAdapter);
}
}
MyAdapter.Java
public class MyAdapter extends ArrayAdapter<Item> {
ArrayList<Item> animalList = new ArrayList<>();
public MyAdapter(Context context, int textViewResourceId, ArrayList<Item> objects) {
super(context, textViewResourceId, objects);
animalList = objects;
}
#Override
public int getCount() {
return super.getCount();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.list_view_items, null);
TextView textView = (TextView) v.findViewById(R.id.textView);
ImageView imageView = (ImageView) v.findViewById(R.id.imageView);
TextView breedView = (TextView)v.findViewById(R.id.breed);
textView.setText(animalList.get(position).getAnimalName());
imageView.setImageResource(animalList.get(position).getAnimalImage());
breedView.setText(animalList.get(position).getBreed());
return v;
}
}
Item.Java
public class Item {
String animalName;
int animalImage;
String breedName;
public String getBreed() {
return breedName;
}
public void setBreed(String breed) {
this.breedName = breedName;
}
public Item(String animalName,int animalImage,String breedName)
{
this.animalImage=animalImage;
this.animalName=animalName;
this.breedName = breedName;
}
public String getAnimalName()
{
return animalName;
}
public int getAnimalImage()
{
return animalImage;
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
android:id="#+id/simpleListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#000"
android:dividerHeight="2dp"/>
</RelativeLayout>
list_view_items.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="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="5dp" />
<TextView
android:id="#+id/textView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Demo"
android:textColor="#000" />
<TextView
android:id="#+id/breed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Breed"
android:textColor="#000" />
</LinearLayout>
This is most likely a problem with the linear layout for each item. The orientation is horizontal, which lays each view one after the other horizontally. The problem is that the text view for the animal type has a width of fill_parent leaving no space for the breed view. If you change it to wrap_content it'll probably work for some of the cases, but might not work with everything.
In any case I think this is a problem with the views' positions and sizes. Try and move them around. Perhaps even a simple change would be placing them vertically:
<?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="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="5dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/textView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Demo"
android:textColor="#000" />
<TextView
android:id="#+id/breed"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Breed"
android:textColor="#000" />
</LinearLayout>
</LinearLayout>
There's perhaps a more efficient way of doing this, but this is just an example. The inner linear layout places one text view on to of the other.
PS: your getCount method is not really doing anything. You can remove it.
replace your layout with my code your issue will resolve.
<?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="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="5dp" />
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:text="Demo"
android:textColor="#000" />
<TextView
android:id="#+id/breed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Breed"
android:textColor="#000" />
</LinearLayout>

Android ListView Customization (title, description, details, footer)

As I'm new to Android, I'm struggling to design a custom layout which is going to be my listview row. I like my list view row should contain title description, details and footer. My listview row hold data like the image I attached. Please see the attached image
You must need to create your_layout_row.xml first
<?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="60dp"
android:orientation="horizontal"
android:layout_margin="14dp"
>
<LinearLayout
android:layout_width="60dp"
android:layout_height="60dp"
>
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:paddingLeft="10dp"
android:layout_height="60dp"
/>
</LinearLayout>
<TextView
android:gravity="center_vertical"
android:paddingBottom="10dp"
android:paddingRight="5dp"
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="20dp"
android:text="TextView"
android:textStyle="normal|italic"
android:textSize="17dp" />
</LinearLayout>
now here you have your listview layout.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/TaskList_layout_background_color"
>
<ListView
android:id="#+id/lv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:dividerHeight="10dp"
android:paddingBottom="5dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="5dp" >
</ListView>
</RelativeLayout>
now create your class Model
for example :
class ModelClass
{
String text;
public ModelClass(String _text)
{
text = _text;
}
public String getText()
{
return this.text;
}
}
now create your custom adapter class
public class CustomAdapter extends ArrayAdapter<ModelClass> {
// declaring our ArrayList of items
private ArrayList<ModelClass> objects;
/* here we must override the constructor for ArrayAdapter
* the only variable we care about now is ArrayList<Item> objects,
* because it is the list of objects we want to display.
*/
public CustomAdapter(Context context, int textViewResourceId, ArrayList<ModelClass> objects) {
super(context, textViewResourceId, objects);
this.objects = objects;
}
/*
* we are overriding the getView method here - this is what defines how each
* list item will look.
*/
#Override
public View getView(int position, View convertView, ViewGroup parent){
// assign the view we are converting to a local variable
View v = convertView;
// first check to see if the view is null. if so, we have to inflate it.
// to inflate it basically means to render, or show, the view.
if (v == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.your_layout_row null);
}
/*
* Recall that the variable position is sent in as an argument to this method.
* The variable simply refers to the position of the current object in the list. (The ArrayAdapter
* iterates through the list we sent it)
*
* Therefore, i refers to the current Item object.
*/
ModelClass i = objects.get(position);
if (i != null) {
// This is how you obtain a reference to the TextViews.
// These TextViews are created in the XML files we defined.
TextView tt = (TextView) v.findViewById(R.id.textView);
// check to see if each individual textview is null.
// if not, assign some text!
if (tt != null){
tt.setText( objects.get(position).getText());
}
}
// the view must be returned to our activity
return v;
}
}
now in your main activity set your listview adapter to this customAdapter.
ArrayList<MyModel> myList = new new ArrayList<MyModel>();
myList.add("1");
myList.add("2");
myList.add("3");
myList.add("4");
ListView myListView = (ListView)findViewById(R.id.lv_list);
CustomAdapter adapter= new CustomAdapter(acitivity, 0, myList);
myListView.setAdapter(adapter);
In this case, you have to custom adapter.
Actually Relative is more suitable for designs. But now I'll write with LinearLayout to be easy.
here is the custom layout for listview item...
<?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">
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="30dp"
android:text="Title"
android:background="#android:color/holo_red_light"
android:gravity="center"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_weight="1"
android:gravity="center"
android:background="#android:color/holo_green_light"
android:text="DESC"/>
<TextView
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_weight="1"
android:gravity="center"
android:background="#android:color/holo_blue_light"
android:text="Other Detais"/>
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="30dp"
android:text="Footer"
android:background="#android:color/holo_red_light"
android:gravity="center"/>
</LinearLayout>
copy and modify above answer by Hein Htet Aung
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="Title"
android:background="#android:color/holo_red_light"
android:gravity="center"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:padding="20dp"
android:background="#android:color/holo_green_light"
android:text="DESC"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="20dp"
android:layout_weight="1"
android:gravity="center"
android:background="#android:color/holo_blue_light"
android:text="Other Detais"/>
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp"
android:text="Footer"
android:background="#android:color/holo_red_light"
android:gravity="center"/>

How to display multiple number of TextViews inside each row in ListView?

I am creating a Help page in which I have a set of questions and answers. These questions and answers have different styles. Here is the xml file, which describes the layout of a question & answer set:
<?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"
android:layout_gravity="center">
<TextView
android:text="#string/Help_first_question"
android:id="#+id/text1"
android:padding="5dip"
android:background="#e0f3ff"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="#+id/panel1"
android:visibility="gone"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_margin="2dip"
android:text="#string/Help_first_answer"
android:padding="5dip"
android:background="#FFFFFF"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
I want to display multiple questions and answers within a listView, whereby each row contains a set of the question and the answer. My listview looks like :
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</ListView>
so it will look like :
first row : Q
A
second row : Q
A
third row : Q
A
What is the best approach for achieving this?
create custom adapter and use the below layout to achieve your goal
<LinearLayout 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:orientation="vertical"
tools:context=".MainActivity" >
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
You need to implement a custom ListAdapter implementing all of the abstract methods.
Let's create a QuestionAndAnswerListAdapter, which you can make your ListView by setting it up in onCreate:
public void onCreate(Bundle savedInstanceState) {
super(savedInstanceState);
setContentView(R.layout.listview);
QuestionsAndAnswersListAdapter adapter = new QuestionsAndAnswersListAdapter(data);
ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);
}
The adapter itself would look something like this:
public QuestionsAndAnswersListAdapter implements ListAdapter {
private QuestionAndAnswer[] data;
public QuestionsAndAnswersListAdapter(QuestionAndAnswer[] data) {
this.data = data;
}
public View getView(int position, View view, ViewGroup parent) {
if(view == null) {
//Only creates new view when recycling isn't possible
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.question_and_answer_list_item, null);
}
QuestionAndAnswer thisQA = data[position];
TextView questionView = (TextView) view.findViewById(R.id.text1);
questionView.setText(thisQA.question);
TextView answerView = (TextView) view.findViewById(R.id.answer);
answerView.setText(thisQA.answer);
return view;
}
// ...
}
getView is really the central method to get right. The rest of the methods you need to implement to live up to the ListAdapter interface are pretty straight-forward. Check the reference to see exactly what they are.

Android ListView creates the views but doesn't display them

I am having problems with ListView on android. I have an Activity with an EditText view and a button. The idea is user should enter some info in the EditText field, touch the Search button which retrieves a list from a web service that it is displayed in the same activity below the EditText and the Button. Everything fine, I got the data from Internet but items weren't displaying. I was using the notifyDataSetChanged(). After a couple of hours with no success, I decided trying to put some items manually and it turns out that again nothing was displayed, hence I think I am doing something wrong when I am trying to set the listview and the adapter. So here is the code..
the xml of the activity activity_search.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp">
<EditText
android:id="#+id/edit_search"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="5"
android:inputType="text"
android:hint="Enter info"
android:ems="10" >
<requestFocus />
</EditText>
<Button
android:id="#+id/button_search"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#android:drawable/ic_menu_search"
android:contentDescription="Search"
android:ems="10" />
</LinearLayout>
<ListView
android:id="#+id/listview_items"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawSelectorOnTop="false" />
The XML of the item row.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="5dp">
<TextView
android:id="#+id/row_code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/Common_TextContent"
android:textAppearance="#android:style/TextAppearance.Holo.Medium" />
<TextView
android:id="#+id/row_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="#string/Common_TextContent"
android:textAppearance="#android:style/TextAppearance.Holo.Small" /></LinearLayout>
the custom Adapter:
public class ItemsListAdapter extends ArrayAdapter<ItemsList> {
private int[] colors = new int[] { 0x30ffffff, 0x30808080 };
public AssetListAdapter(Context context,
List<ItemsList> itemsList) {
super(context, 0, itemsList);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.row, null);
}
convertView.setBackgroundColor(colors[position % colors.length]);
TextView code = (TextView) convertView.findViewById(R.id.row_code);
code.setText(getItem(position).getCode());
TextView name = (TextView) convertView.findViewById(R.id.row_name);
name.setText(getItem(position).getName());
return convertView;
}
and the onCreate method on the Activity
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
_listView = (ListView) findViewById(R.id.listview_items);
_listItems = new ArrayList<ItemsList>();
_listItems.add(new ItemsList ("cosa1", "cosa1", "cosa1", "cosa1"));
_listItems.add(new ItemsList ("cosa2", "cosa2", "cosa2", "cosa2"));
_listItems.add(new ItemsList ("cosa3", "cosa3", "cosa3", "cosa3"));
_adapter = new ItemsListAdapter(this, _listItems);
_listView.setAdapter(_adapter);
}
The ItemsList is just an Object with 4 strings with all the getters implemented.
When I debug in the getView method of the Adapter, the view (convertView) is created and it has the right information. It is just that is not showing those in the screen. What am I doing wrong?
Thanks...
Your second LinearLayout has a height of match_parent. Try wrap_content instead.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">

onListItemClick() is bypassed for ListView with a custom adapter

I realize there are a ton of questions regarding this issue, but the solution of setting every view in the row.xml to focusable="false" and focusableInTouchMode="false" do not work, nor does getting the ListView from the ListActivity and setting setItemsCanFocus(false).
Weirdly, when registered for a context menu, the long tap works. The regular tap though? Nope. I tried setting listeners like OnItemClickListener to no avail.
I read somewhere that I might be able to remedy this by overriding getView() in my Adapter? I'm not too sure how that works though. Note, I don't want to know what view the user has clicked; I just care about the list row being clicked to initiate the corresponding code in onListItemClick().
Maybe there's something in my row.xml that's all wrong? Or is it affected by the way I set my ListView's adapter (placed in onResume() instead of onCreate() to update information)?
<?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"
android:focusable="false"
android:focusableInTouchMode="false">
<TextView style="?android:attr/listSeparatorTextViewStyle"
android:id="#+id/listSectionHeader"
android:layout_width = "fill_parent"
android:layout_height="wrap_content"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:paddingLeft="5dp"
android:textColor="#android:color/white"
android:visibility="gone"
android:focusable="false"
android:focusableInTouchMode="false"/>
<RelativeLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="70dp"
android:background="#drawable/list_button"
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="true"
android:longClickable="true"
>
<TextView android:id="#+id/itemID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:textStyle="bold"
android:layout_alignParentLeft="true"
android:focusable="false"
android:focusableInTouchMode="false"/>
<CheckBox
android:id="#+id/returnedCheckbox"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_margin="10dp"
android:checked="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false"
/>
<LinearLayout
android:layout_toRightOf="#id/returnedCheckbox"
android:layout_margin="5dp"
android:layout_centerVertical="true"
android:orientation="vertical"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false">
<TextView
android:id="#+id/stuffName"
android:layout_width="fill_parent"
android:lines="1"
android:layout_height="wrap_content"
android:ellipsize="end"
android:scrollHorizontally="true"
android:text="Hey there"
android:textSize="25sp"
android:textColor="#FFF"
android:shadowColor="#000"
android:focusable="false"
android:focusableInTouchMode="false"
/>
<RelativeLayout
android:id="#+id/detailsLayout"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false">
<TextView
android:id="#+id/dueListItem"
android:layout_width="wrap_content"
android:lines="1"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="#string/dueListing"
android:focusable="false"
android:focusableInTouchMode="false"/>
<TextView
android:id="#+id/dueDate"
android:layout_toRightOf="#id/dueListItem"
android:layout_marginLeft="2dp"
android:layout_width="90dp"
android:lines="1"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="HEHEHE"
android:focusable="false"
android:focusableInTouchMode="false"/>
<ImageView
android:id="#+id/starMark"
android:layout_alignRight="#id/detailsLayout"
android:layout_toRightOf="#id/dueDate"
android:layout_marginLeft="10dp"
android:layout_marginTop="2dp"
android:layout_height="15dp"
android:layout_width="15dp"
android:scaleType="fitXY"
android:adjustViewBounds="true"
android:src="#drawable/list_starred"
android:visibility="invisible"
android:focusable="false"
android:focusableInTouchMode="false"/>
</RelativeLayout>
</LinearLayout>
<ImageView
android:id="#+id/contactPic"
android:layout_alignParentRight="true"
android:layout_height="48dp"
android:layout_width="48dp"
android:background="#FFF"
android:layout_margin="10dp"
android:layout_centerVertical="true"
android:scaleType="fitCenter"
android:padding="3dp"
android:focusable="false"
android:focusableInTouchMode="false"
/>
<ImageView
android:id="#+id/lentArrow"
android:visibility="invisible"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/indicator_lent"
android:layout_marginTop="42dp"
android:layout_marginRight="1dp"
android:focusable="false"
android:focusableInTouchMode="false"/>
</RelativeLayout>
</LinearLayout>
The Onlistitemclick will never be called because there is a clickable view in your list item. Remove the checkbox and see if you are able to get the clicks.
There is an alternative to using using a checkbox directly in your item layout. Use android:choiceMode="multipleChoice" for listview if it suits your needs.
Take a look at this link in how to create a custom adapter:
http://android-er.blogspot.com/2010/06/using-convertview-in-getview-to-make.html
In the Override getView() method, you could just set the row.setOnClickListener() to do what you needed to do when that list item is clicked.
Ideally, you would use convertView to fill a ViewHolder class so that you aren't recreating list items when they have already been created, but that's a different question.
Edit
Here's a slimmed down custom implementation of extending a SimpleCursorAdapter:
public class CatchCursorAdapter extends SimpleCursorAdapter {
private final Context mContext;
private final Cursor mCursor;
private final int layout;
private final LayoutInflater inflater;
private final class ViewHolder {
public ImageView catchImage;
public ImageView catchStar;
public TextView catchSpecies;
}
public CatchCursorAdapter(Context context, int layout, Cursor cursor) {
super(context, layout, cursor, new String[] { }, new int[] { });
this.mContext = context;
this.mCursor = cursor;
this.inflater = LayoutInflater.from(context);
this.layout = layout;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = inflater.inflate(layout, parent, false);
viewHolder = new ViewHolder();
viewHolder.catchImage = (ImageView)convertView.findViewById(R.id.catch_image);
viewHolder.catchSpecies = (TextView)convertView.findViewById(R.id.catch_species);
viewHolder.catchStar = (ImageView)convertView.findViewById(R.id.catch_starfavorite);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder)convertView.getTag();
}
convertView.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//Perform an action when this list item is clicked
}
});
viewHolder.catchStar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//You can also have buttons within your list item that can be clicked
//independently of the parent list item.
}
});
//Set the rest of your views
return convertView;
}
}
I didn't have to do anything to my adapter; onListItemClick() just miraculously worked on its own for some reason. I'm scratching my head even more right now.
Incidentally, I extended CursorAdapter, not SimpleCursorAdapter, which I understand is sort of different. From what I read, CursorAdapter extension requires only overriding the newView() and bindView() instead of the usual getView() based on this http://www.workreloaded.com/2011/02/android-extending-cursoradapter-for-custom-listview/.

Categories

Resources