How to Customize Listview Row Android

Android custom Row Item for ListView

Add this row.xml to your layout folder

<?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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Header"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/text"/>


</LinearLayout>

make your main xml layout as this

<?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="horizontal" >

<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>

</LinearLayout>

This is your adapter

class yourAdapter extends BaseAdapter {

Context context;
String[] data;
private static LayoutInflater inflater = null;

public yourAdapter(Context context, String[] data) {
// TODO Auto-generated constructor stub
this.context = context;
this.data = data;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public int getCount() {
// TODO Auto-generated method stub
return data.length;
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return data[position];
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View vi = convertView;
if (vi == null)
vi = inflater.inflate(R.layout.row, null);
TextView text = (TextView) vi.findViewById(R.id.text);
text.setText(data[position]);
return vi;
}
}

Your java activity

public class StackActivity extends Activity {

ListView listview;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
listview = (ListView) findViewById(R.id.listview);
listview.setAdapter(new yourAdapter(this, new String[] { "data1",
"data2" }));
}
}

the results

Sample Image

Android custom listview row

First,you should create a xml to describe what your list cell likes,called cell.xml,for example:

 <?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="vertical" android:background="@color/spink">

<TextView
android:id="@+id/name_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
android:textAppearance="?android:attr/textAppearanceLarge" />

<TextView
android:id="@+id/address_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Address"
android:textAppearance="?android:attr/textAppearanceMedium" />

</LinearLayout>

Second,create a adapter.It helps your listview to show data:

public class MyAdapter extends BaseAdapter {
private LayoutInflater mInflater = null;
private ArrayList<People> peopleList;

private final class ViewHolder {
TextView nameTextView;
TextView addressTextView;
}

private ViewHolder mHolder = null;

public MyAdapter(Context context) {
mContext = context;
mInflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public int getCount() {
return peopleList.size();
}

@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
mHolder = new ViewHolder();
convertView = mInflater.inflate(R.layout.cell, null);
convertView.setTag(mHolder);
} else {
mHolder = (ViewHolder)convertView.getTag();
}

mHolder.nameTextView (TextView)convertView.findViewById(R.id.name_textView);
mHolder.nameTextView.setText(peopleList.get(position).getName());
mHolder.addressTextView = (TextView)convertView.findViewById(R.id.address_textView);
mHolder.addressTextView.setText(peopleList.get(position).getAddress());

return convertView;
}
}

Finally,when you want to show the data,do this in your activity:

listView.setAdapter(new MyAdapter());

hope it helps you.

how to customize listview row android

To do so, you will need to create your own custom adapter. In the getView method (which returns the View to display for each list item), apply the color you want to your TextView's background.
The cool thing about customAdapters is that you can do absolutely anything, and display much more complicated Views for your list items, because you are not restricted to TextViews anymore, you can change your list item XML layout to any kind of View/Layout...

Something like this:

MyAdapter.java

public class MyAdapter extends BaseAdapter{
private LayoutInflater inflater;
private ArrayList<String> data;

public MyAdapter(Context context, ArrayList<String> data){
// Caches the LayoutInflater for quicker use
this.inflater = LayoutInflater.from(context);
// Sets the events data
this.data= data;
}

public int getCount() {
return this.data.size();
}

public String getItem(int position) throws IndexOutOfBoundsException{
return this.data.get(position);
}

public long getItemId(int position) throws IndexOutOfBoundsException{
if(position < getCount() && position >= 0 ){
return position;
}
}

public int getViewTypeCount(){
return 1;
}

public View getView(int position, View convertView, ViewGroup parent){
String myText = getItem(position);

if(convertView == null){ // If the View is not cached
// Inflates the Common View from XML file
convertView = this.inflater.inflate(R.id.my_row_layout, null);
}

// Select your color and apply it to your textview
int myColor;
if(myText.substring(0, 1) == "a"){
myColor = Color.BLACK;
}else{
....
}

convertView.findViewById(R.id.myTextViewId).setBackground(myColor);
// Of course you will need to set the same ID in your item list XML layout.

return convertView;
}
}

and then in your activity set the adapter like this:

public class Main extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

List<String> words = populateList();
List<String> l = removeDoubles(words);
Collections.sort(l);

ListView lv = (ListView)findViewById(R.id.listview);

MyAdapter adapter = new MyAdapter(getApplicationContext(), l);

lv.setAdapter(adapter);

lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {

}
});
}

How to customize listview to have different layouts for first and second position of row items?

You can inflate each row with different view in the adapter. Use:

public View getView(int position, View convertView, ViewGroup parent) {
if(position==0)
{
//view 1
}

else if(position==1)
{
//View 2
}

else
{
Rest of the list elements
}

ListView with customized Row Layout - Android

You need to create your own ArrayAdapter:

private class YourAdapter extends ArrayAdapter<String> {
// do some work
}

Then you should specify how will look your row with XML, exactly for your goal, i recommend to you use RelativeLayout and it can looks like this:

row.xml

<?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">

<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
/>

<TextView
android:id="@+id/email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/name"
/>

</RelativeLayout>

So then in YourAdapter you have to set super constuctor:

public YourAdapter() {
super(YourActivity.this, R.layout.row, data);
}

Then for customize your data in ListView + more effective implementation i recommend to you override getView() method and also use Holder design pattern.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
LayoutInflater inflater = getLayoutInflater();
if (convertView == null) {
convertView = inflater.inflate(R.layout.row, null, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.getUpperText().setText(dataSource[position]);
holder.getLowerText().setText(dataSource[position]);

return convertView;
}

Finally just initialize ListView and set Adapter:

ListView list = (ListView) findViewById(R.id.list);
list.setAdapter(new YourAdapter());


Note: Design pattern Holder represents arbitrary object that holds child widgets of each row, so you need to find them only once and then with Holder object you will always have access to them.

Implementation of Holder can looks like this:

public class ViewHolder {
private View row;
private TextView upperText = null, lowerText = null;

public ViewHolder(View row) {
this.row = row;
}

public TextView getUpperText() {
if (this.upperText == null) {
this.upperText = (TextView) inView.findViewById(R.id.someId);
}
return this.upperText;
}

public TextView getLowerText() {
if (this.lowerText == null) {
this.lowerText = (TextView) inView.findViewById(R.id.someId);
}
return this.lowerText;
}
}


Hope it helps.

How to customize the appearance of a Listview rows

Consider using a CardView, it will help you to get the rounded corners. Inside the CardView create a RelativeLayout in order to get the rest of the stuff you've mentioned above.

Here is a good tutorial : Using the CardView | CodePath Android Cliffnotes

Dynamically adding custom row to listview

But as per requirements, my each listview row won't just be a single
string. Instead, it'll be collection of views consisting of imageview
and textviews stored in row.xml.

=> The ListView you are displaying is using normal adapter. If you want your item contains multiple views like Imageview, Textview or any view, then you have to define Custom adapter class by extending either BaseAdapter or ArrayAdapter.

What will replace adapter = new
ArrayAdapter(this,android.R.layout.simple_list_item_1,
listItems); ? Will it be adapter = new
ArrayAdapter(this,R.layout.row, listItems); ??

=> Here ArrayAdapter will not work because your row xml layout may contains different views like ImageView, TextView, Button or any other widget. So I would suggest you to define your own adapter class where you have to override getView() method.

How do I refer to imageview and textviews of each row? How do I set
and get data from them? How do I recognize their click events?

=> As I said above, once you define custom adapter class, you will have to override getView() method where you can find any views of your row xml layout file, reference it and set/display whatever data you want.

Is use of Adapter must? or can I get away with it?

=> Yes its must, without adapter you won't be able to display in data-binded widgets like GridView, ListView, Spinner, Gallery, etc.

Example for defining custom adapter:

  1. My talk on ListView
  2. http://www.vogella.com/articles/AndroidListView/article.html

Custom list item to ListView android

It is possible by using a SimpleAdapter.

Here is an example :

    // Create the item mapping
String[] from = new String[] { "title", "description" };
int[] to = new int[] { R.id.title, R.id.description };

Now "title" is mapped to R.id.title, and "description" to R.id.description (defined in the XML below).

    // Add some rows
List<HashMap<String, Object>> fillMaps = new ArrayList<HashMap<String, Object>>();

HashMap<String, Object> map = new HashMap<String, Object>();
map.put("title", "First title"); // This will be shown in R.id.title
map.put("description", "description 1"); // And this in R.id.description
fillMaps.add(map);

map = new HashMap<String, Object>();
map.put("title", "Second title");
map.put("description", "description 2");
fillMaps.add(map);

SimpleAdapter adapter = new SimpleAdapter(this, fillMaps, R.layout.row, from, to);
setListAdapter(adapter);

This is the corresponding XML layout, here named row.xml :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/description"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>

I used two TextViews but it works the same with any kind of view.



Related Topics



Leave a reply



Submit