I'm using listview to show the messages from the database..when i add a message it
takes all the string and showing on the listview..here is my xml file and java..
I need to get the message in a singline per rows with '...'. I researched for this question and i found,type
android:singleLine="true" in textview,but i don't know what they mean 'in textview'.becauz i'm using listview.please help.
<?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"
android:background="#drawable/wave" >
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_below="#+id/SearchMessageExit"
android:focusableInTouchMode="true"
>
</ListView>
</LinearLayout>
message.java
public void detailsOfMessage(){
try{
Database_message info = new Database_message(this);
String data = info.getData();
info.close();
if(data.equals(""))
{
Toast.makeText(getApplicationContext(), "Empty Message", Toast.LENGTH_LONG).show();
}
StringTokenizer token = new StringTokenizer(data,"\t");
int rows = token.countTokens();
classes = new String[rows];
int i=0;
while (token.hasMoreTokens())
{
classes[i]=token.nextToken();
i++;
}
listView = (ListView) findViewById(R.id.list);
listView.setOnItemClickListener(this);
listView.setOnLongClickListener(this);
inAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,0);
listView.setAdapter(inAdapter);
for (int r = 0; r < classes.length; r++) {
inAdapter.add(classes[r]);
}
}catch(Exception e){
Toast.makeText(getApplicationContext(), "Empty Message", Toast.LENGTH_LONG).show();
}
}
you are using default layout android.R.layout.simple_list_item_1 for listview item. instead create one layout with textview with single line enable. and pass it to listview. and use custom array adapter for listview.
Do like this:
create list itemview XML
listview_item_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp">
<TextView android:id="#+id/txtTitle"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:textStyle="bold"
android:textSize="22dp"
android:textColor="#000000"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp" />
</LinearLayout>
One class like
Weather.java
public class Weather {
public String title;
public Weather(){
super();
}
public Weather(String title) {
super();
this.title = title;
}
}
and then create array adapter class
public class WeatherAdapter extends ArrayAdapter<Weather>{
Context context;
int layoutResourceId;
Weather data[] = null;
public WeatherAdapter(Context context, int layoutResourceId, Weather[] data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
WeatherHolder holder = null;
if(row == null)
{
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new WeatherHolder();
holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
row.setTag(holder);
}
else
{
holder = (WeatherHolder)row.getTag();
}
Weather weather = data[position];
holder.txtTitle.setText(weather.title);
return row;
}
static class WeatherHolder
{
TextView txtTitle;
}
}
And use like this in your activity:
Weather weather_data[] = new Weather[]
{
new Weather("Cloudy"),
new Weather("Showers"),
new Weather("Snow"),
new Weather("Storm"),
new Weather("Sunny")
};
WeatherAdapter adapter = new WeatherAdapter(this,
R.layout.listview_item_row, weather_data);
listView1.setAdapter(adapter);
Hope it Helps!!!
You need to implement a custom adapter for your ListView.
Along with that you should also implement, a custom_row.xml file for each row of your List View.
For Example:
1. Custom Adapter:
public class CustomAdapterListView extends BaseAdapter
{
private Activity activity;
private static LayoutInflater inflater=null;
private YOUR_DATA_TYPE data;
public CategoryDetailsCustomGridviewAdapter(Activity a, ArrayList<YOUR_DATA_TYPE> d)
{
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount()
{
// TODO Auto-generated method stub
return data.size();
}
#Override
public Object getItem(int position)
{
// TODO Auto-generated method stub
return 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(convertView==null)
{
vi = inflater.inflate(R.layout.YOUR_LISTVIEW_ROW_XML_FILE, null);
}
//Fetching the Data from ArrayList for each row.
TextView custom_row_tv = vi.findViewById(R.id.YOUR_TEXT_VIEW_ID)
YOUR_DATA_TYPE dataToBePopulated = new YOUR_DATA_TYPE;
custom_row_tv.setText(YOUR_DATA_TYPE.ToString());
dataToBePopulated = data.get(position);
return vi;
}
}
2. YOUR_LISTVIEW_ROW_XML_FILE.xml:
<?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" >
<TextView
android:id="#+id/YOUR_TEXT_VIEW_ID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true" >
</TextView>
</RelativeLayout>
3. Setting up Your Custom Adapter:
Public Class YourClass extends Activity
{
onCreate(....)
{
setContentView(R.Layout.YOUR_LAYOUT_FILE);
ArrayList<YOUR_DATA_TYPE> data = new ArrayList<YOUR_DATA_TYPE>();
data.add(...) //Fetch your Data from Data source into this ArrayList.
ListView yourListView = (ListView)findViewById(R,id.YOUR_LISTVIEW_ID);
CustomAdapterListView adapter = new CustomAdapterListView (YourClass.this, data);
yourListView.setAdapter(adapter);
adapter.notifyDataSetChanged();
//YOUR OTHER FUNCTIONALITY......
}
//YOUR OTHER METHODS.....
....
....
}
This way you can simply implement a custom ListView with the Attribute of Single line attached to your TextView embedded within your ListView.
I hope this solves your problem.
Related
I am currently working on a very basic android application and have encountered an obstacle I cannot solve on my own.
In my application I want to have a start screen with a ListView. In each Line of this ListView there should be a Button and a TextView. I want to have approximately 5 Lines. When you click on each of the Button you should be able to get to different Activities. How do I do that? I read something about adapters but I am still not sure how to build this.
Here's my xml code for the TextView and the Button:
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView"
android:id="#+id/rl01">
<TextView
android:layout_width= "wrap_content"
android:layout_height="50dp"
android:id="#+id/text01"
android:text="hello"
android:textSize="24dp"
android:textColor="#color/abc_search_url_text_normal"
android:paddingRight="#dimen/activity_horizontal_margin"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_toRightOf="#id/text01"
android:text="Press Me!"
/>
</RelativeLayout>
The xml layout you have posted, will be used as each listview item.
Step 1:
Create a class which extends BaseAdapter;
public class CustomAdapter extends BaseAdapter
{
Context con;
String[] data;
public CustomAdapter (Context context, String[] data)
{
this.con = context;
this.data = data;
}
#Override
public int getCount() {
return data.length;
}
#Override
public Object getItem(int position) {
return data[position];
}
#Override
public long getItemId(int position) {
return 0;
}
//this method will be called for every item of your listview
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView= inflater.inflate(R.layout.customview, parent, false);
TextView text = (TextView) view.findViewById(your text view id); //recognize your view like this
text.setText(data[position]);
return convertView;
}
}
Step 2:
In your activity, recognize your listview:
yourListViewReference = (ListView) findViewById(R.id.your_list_view_id);
And initialize String array:
String[] data = {"item 1", "item2", "item3"}; //how many items you want
And then create instance of custom adapter you created, and set it to listview:
CustomAdapter ad = new CustomAdapter(this, data);
yourListViewReference.setAdapter(ad);
And sorry for my bad english. I am actually working on it.
This article from Vogella is really useful for what you want to do.
Basically, you'll create an Adapter that extends the BaseAdapter class as follows:
public class Adapter extends BaseAdapter {
private List<Item> mItems;
private Context mContext;
public EventAdapter(Context context, List<Event> items) {
mContext = context;
mItems = items;
}
public View getView(int position, View convertView, ViewGroup parent) {
// This recycles your view and prevents constant inflation, which can really hit your performance.
View rowView = convertView;
if (rowView == null) {
ViewHolder viewHolder = new ViewHolder();
rowView = inflater.inflate(R.layout.yourLayout, parent, false);
viewHolder.text = (TextView) rowView.findViewById(R.id.yourTextViewId);
viewHolder.button = (Button) rowView.findViewById(R.id.yourButtonId);
rowView.setTag(viewHolder);
}
ViewHolder holder = (ViewHolder) rowView.getTag();
// Get the correct item by position
Item item = item.get(position);
// Update the row layout with your item data
holder.text.setText(item.text);
holder.button.setButton(item.button);
// Return your row view
return rowView;
}
#Override
public int getCount() {
return mItems.size();
}
#Override
public Object getItem(int position) {
}
#Override
public long getItemId(int position) {
}
static class ViewHolder {
public TextView text;
public Button button;
}
Afterwards you just need to set this adapter to your ListView or RecyclerView by doing
listView.setAdapter(new Adapter(this, items));
I would write a simple example:
You dont need a button in listview row, just implement onItemClick();
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ListView
android:id="#+id/custom_list"
android:longClickable="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
list_row.xml
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView"
android:id="#+id/rl01">
<TextView
android:layout_width= "wrap_content"
android:layout_height="50dp"
android:id="#+id/text01"
android:text="hello"
android:textSize="24dp"
android:textColor="#color/abc_search_url_text_normal"
android:paddingRight="#dimen/activity_horizontal_margin"
/>
MainActivity.java
oncreate()
{
....
lv1 = (ListView) result.findViewById(R.id.custom_list);
String[] listdata = {"txt1", "txt2", "txt3", "txt4", "txt5"};
ListAdapter listAdapt = new ListAdapter(this, listdata );
lv1.setAdapter(listAdapt);
lv1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
//do ur work here when list row selected
}
});
..
}
ListAdapter.java
public class ListAdapter extends BaseAdapter {
String[] listData;
private LayoutInflater layoutInflater;
public CustomListAdapter(Context aContext, String[] listData) {
this.listData = listData;
layoutInflater = LayoutInflater.from(aContext);
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_row, null);
TextView tv1 = (TextView)convertView.findViewById(R.id.text01);
tv1.setText(listData.[position]);
return convertView;
}
I am new to android and i am working on listview. I am trying to show data using listview in xml and adapter in class file. I am working on following 3 files.
First file: 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"
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="com.listpractice.MainActivity" >
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:drawSelectorOnTop="false"
></ListView>
</RelativeLayout>
Second file: row1.xml
<?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="?android:attr/listPreferredItemHeight" >
<ImageView
android:id="#+id/icon"
android:contentDescription="#string/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:src="#drawable/ic_launcher"
/>
<TextView
android:id="#+id/firstTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_toRightOf="#id/icon"
android:layout_toEndOf="#id/icon"
android:textSize="30sp"
android:text="#string/hello_world"
/>
<TextView
android:id="#+id/secondTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/icon"
android:layout_toEndOf="#id/icon"
android:layout_below="#id/firstTextView"
android:textSize="13sp"
android:text="#string/hello_world"
/>
</RelativeLayout>
Third file: MainActivity.java
package com.listpractice;
import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
public class MainActivity extends ListActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
My Problem : Now i want to show data of row1.xml but i don't have dynamic data. how can i show data using third(.class) file.
check out this link it will help http://androidexample.com/Create_A_Simple_Listview_-_Android_Example/index.php?view=article_discription&aid=65&aaid=90
either you need to create adapter file
public class CustomBaseAdapter extends BaseAdapter{
Context context;
List<RowItem> rowItems;
public CustomBaseAdapter(Context context, List<RowItem> items) {
this.context = context;
this.rowItems = items;
}
/*private view holder class*/
private class ViewHolder {
ImageView imageView;
TextView txtTitle;
//TextView txtDesc;
ImageView imgarrow;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, null);
holder = new ViewHolder();
//holder.txtDesc = (TextView) convertView.findViewById(R.id.desc);
holder.txtTitle = (TextView) convertView.findViewById(R.id.title);
holder.imageView = (ImageView) convertView.findViewById(R.id.icon);
holder.imgarrow=(ImageView)convertView.findViewById(R.id.arrow_icon);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
RowItem rowItem = (RowItem) getItem(position);
//holder.txtDesc.setText(rowItem.getDesc());
holder.txtTitle.setText(rowItem.getTitle());
holder.imageView.setImageResource(rowItem.getImageId());
holder.imgarrow.setImageResource(rowItem.getImg());
return convertView;
}
#Override
public int getCount() {
return rowItems.size();
}
#Override
public Object getItem(int position) {
return rowItems.get(position);
}
#Override
public long getItemId(int position) {
return rowItems.indexOf(getItem(position));
}
}
MainActivity
public class MainActivity extends Activity implements OnItemClickListener{
public static final String[] titles = new String[] { "Krish",
"John Cena", "Kane","Roman Reigns"};
public static final Integer[] images = { R.drawable.fourth,R.drawable.second,R.drawable.first,R.drawable.third};
public static final Integer[] imagearow = {R.drawable.arrow,R.drawable.arrow,R.drawable.arrow,R.drawable.arrow };
ListView listView;
List<RowItem> rowItems;
private ImageView btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.list_item_home);
//list_travels=(ListView)findViewById(R.id.list_travels);
btn=(ImageView)findViewById(R.id.btnaddhotels);
btn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0)
{
Intent i=new Intent(HomeScreen.this,Registerhotel_resorts.class);
startActivity(i);
}
});
rowItems = new ArrayList<RowItem>();
for (int i = 0; i < titles.length; i++) {
RowItem item = new RowItem(images[i], titles[i],imagearow[i]);
rowItems.add(item);
}
listView = (ListView) findViewById(R.id.list_hotels);
CustomBaseAdapter adapter = new CustomBaseAdapter(this, rowItems);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Toast toast = Toast.makeText(getApplicationContext(),
"Item " + (position + 1) + ": " + rowItems.get(position),
Toast.LENGTH_SHORT);
toast.setGravity(Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0);
toast.show();
Intent i1=new Intent(HomeScreen.this,KrishnaParkResort.class);
startActivity(i1);
}
}
You should read this article on Building Layouts with an Adapter. It has some handy concepts which you will need to get your head around.
The fundamental concept is that you need to link your ListView to an Adapter which populates the rows and adds them to the ListView.
Looking at your row1.xml, it looks like you will need a collection of objects which contain;
An image for icon
String for firstTextView
String for secondTextView
You can build a little snippet to create an array of prepopulated objects for test purposes.
public class YourObject {
private Bitmap icon;
private String text1;
private String text2;
public YourObject(Bitmap icon, String text1, String text2) {
this.icon = icon;
this.text1 = text1;
this.text2 = text2;
}
// GETTERS AND SETTERS
}
Then create a collection of them
List<YourObject> data = new ArrayList<>();
for (int z = 0; z < 5; z++) {
YourObject yourObject = new YourObject(yourIcon, "Text1: " + z, "Text2: " + z);
data.add(yourObject);
}
Once you have this collection, you send it to a your Adapter constructor along with the reference to row1.xml, then follow the guide to populate the rows.
I made a listview in a fragment. Now I need to add a simple icon to the listview items. The icon must be the same on every item. This will be a simple arrow (imageview).
Is this possible with the listview I made? And if yes, how do I do it?
So like this format:
My text here --space--space-- >
The code for the fragment:
public class BiblioFragment extends Fragment {
final String[] items = new String[] { "Astma en alcohol", "Astma en huisdieren", "Astma en lichaamsgewicht",
"Astma en ouder worden", "Astmamedicatie", "Bekende mensen met astma", "Longfunctieonderzoek", "Reizen en vakantie",
"Sociaal leven", "Weetjes over astma", "Enzovoort", "Enzovoort", "Enzovoort" };
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_biblio, container, false);
ListView list = (ListView)view.findViewById(R.id.listView1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, items);
list.setAdapter(adapter);
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
Log.v("TAG", "CLICKED row number: " + arg2);
Intent myIntent = new Intent(getActivity(), BiblioDetail.class);
myIntent.putExtra("welkerij", arg2);
startActivity(myIntent);
}
});
return view;
}
}
My XML for that fragment:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#ffffff">
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ListView>
</LinearLayout>
In onCreateView
ListView list = (ListView)view.findViewById(R.id.listView1);
CustomAdapter cus = new CustomAdapter(getActivity(),items);
list.setAdapter(cus);
Use a custom adapter
public class CustomAdapter extends BaseAdapter {
String items[];
LayoutInflater mInflater;
public CustomAdapter(Context context, String[] items) {
mInflater = LayoutInflater.from(context);
this.items = items;
}
#Override
public int getCount() {
return items.length;
}
#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) {
ViewHolder holder;
if(convertView ==null)
{
convertView = mInflater.inflate(R.layout.list_item,parent,false);
holder = new ViewHolder();
holder.tv = (TextView) convertView.findViewById(R.id.textView1);
holder.iv = (ImageView) convertView.findViewById(R.id.imageView1);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.tv.setText(items[position])
// use holder.iv to set whatever image you want according to the position
return convertView;
}
static class ViewHolder
{
ImageView iv;
TextView tv;
}
}
list_item.xml
<?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:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="42dp"
android:layout_marginTop="32dp"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/imageView1"
android:layout_marginLeft="64dp"
android:layout_marginTop="14dp"
android:layout_toRightOf="#+id/imageView1"
android:text="TextView" />
</RelativeLayout>
Snap
Edit:
If you feel this is over kill you can use a compound textview with image on the left and text on the right.
In the above I have used list_item.xml which is a custom layout. I inflate that layout in getView of custom adapter. I set the text to textview. I have set the default launcher icon to imageview. You can change it though.
I have also used a ViewHolder
http://developer.android.com/training/improving-layouts/smooth-scrolling.html
Also check
How ListView's recycling mechanism works
Create ListAdapter
public class ListAdapter extends ArrayAdapter<Item> {
public ListAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
// TODO Auto-generated constructor stub
}
private List<Item> items;
public ListAdapter(Context context, int resource, List<Item> items) {
super(context, resource, items);
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.itemlistrow, null);
}
Item p = items.get(position);
if (p != null) {
ImageView ICon = ( ImageView) v.findViewById(R.id.description);
}
}
return v;
}
In your Activity
ListView yourListView = (ListView) findViewById(R.id.itemListView);
// get data from the table by the ListAdapter
ListAdapter customAdapter = new ListAdapter(this, R.layout.itemlistrow, List<yourItem>);
yourListView .setAdapter(customAdapter);
I'd like to customize some settings (color, margin) for some items on a listview in a listactivity after or before setting the adapter. How can I do that? Is there any function that can I override?
Thank you.
you can use an own listadapter.. http://www.vogella.com/articles/AndroidListView/article.html
This is how you can do to customize item of your list:
Layout of your list:
<?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">
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
Layout of each item:
<?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">
<TextView
android:id="#+id/text"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
</LinearLayout>
And finaly your activity:
public class MyActivity extends ListActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_activitty);
final List<String> list = new ArrayList<String>();
list.add("test");
list.add("test");
list.add("test");
final CustomAdapter adapter = new CustomAdapter(this, list);
final ListView listView = getListView();
listView.setAdapter(adapter);
}
public class CustomAdapter extends BaseAdapter {
private Context mContext;
private List<String> mList;
public CustomAdapter(Context context, List<String> list) {
mContext = context;
mList = list;
}
#Override
public int getCount() {
return mList.size();
}
#Override
public String getItem(int position) {
return mList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final Holder holder;
if (convertView == null) {
// if it is the first time you create the row
// you get the layout of each row here
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list, null);
// you keep your layout in a holder
holder = new Holder();
holder.mText = (TextView) convertView.findViewById(R.id.text);
convertView.setTag(holder);
} else {
// if the row has already been created, you get it from the holder
holder = (Holder) convertView.getTag();
}
// you do what you want with the content
holder.mText.setText(getItem(position));
holder.mText.setTextColor(Color.BLUE);
return convertView;
}
private class Holder {
public TextView mText;
}
}
}
I used the following code create a custom listview ....But the problem with this code it it is selecting only one item..but highlighting many items...i mean ..for example..if i have 8 items in the list..And i can see only 3 items(rest i have to scroll to see)..if i click the first item...it gets highlighted along with the fourth and the 7th item...
public class MainMenu extends Activity {
ListView lmenu;
View v1;
String s;
Class<?> ourclass;
View layout, row;
static int trantype;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.menulist);
Menu Menu_data[] = new Menu[] { new Menu("1.White"),
new Menu("2.Blue"), new Menu("3.Purple"), new Menu("4.Red"),
new Menu("5.Yellow"), new Menu("6.Black"), new Menu("6.Black"),
new Menu("6.Black"), new Menu("6.Black"), new Menu("6.Black"),
new Menu("6.Black"), new Menu("6.Black") };
MenuAdapter adapter = new MenuAdapter(this, R.layout.menutext,
Menu_data);
lmenu = (ListView) findViewById(R.id.mainmenu);
lmenu.setAdapter(adapter);
lmenu.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> ada, View v, int position,
long id) {
// TODO Auto-generated method stub
/*
* v.setBackgroundColor(Color.parseColor("#FCD5B5")); if (!(v1
* == null) && v1 != v)
* v1.setBackgroundColor(Color.parseColor("#EEEEEE")); v1 = v;
*/
Intent swipeit = new Intent(getBaseContext(), Swipeit.class);
trantype = position + 1;
startActivity(swipeit);
}
});
findViewById(R.id.BLogout).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
}
public class Menu {
public String title;
public Menu() {
super();
}
public Menu(String title) {
super();
this.title = title;
}
}
public class MenuAdapter extends ArrayAdapter<Menu> {
Context context;
int layoutResourceId;
Menu data[] = null;
LayoutInflater inflater;
boolean[] arrBgcolor;
private int activeHex, inactiveHex;
public MenuAdapter(Context context, int layoutResourceId, Menu[] data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
activeHex = Color.parseColor("#FCD5B5");
inactiveHex = Color.parseColor("#EEEEEE");
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
arrBgcolor = new boolean[13];
}
#Override
public View getView(final int position, final View convertView,
ViewGroup parent) {
try {
MenuHolder holder = null;
row = convertView;
// convertView.setBackgroundColor(Color.BLACK);
if (row == null) {
LayoutInflater inflater = ((Activity) context)
.getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new MenuHolder();
holder.txtTitle = (TextView) row.findViewById(R.id.tv1);
row.setTag(holder);
} else {
holder = (MenuHolder) row.getTag();
}
Menu Menu = data[position];
holder.txtTitle.setText(Menu.title);
holder.txtTitle.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
resetArrbg();
arrBgcolor[position] = true;
if (arrBgcolor[position]) {
row.setBackgroundColor(activeHex);
} else {
row.setBackgroundColor(inactiveHex);
}
notifyDataSetChanged();
}
});
} catch (Exception e) {
Toast.makeText(getApplicationContext(), String.valueOf(e),
Toast.LENGTH_LONG).show();
}
return row;
}
private void resetArrbg() {
for (int i = 0; i < arrBgcolor.length; i++) {
arrBgcolor[i] = false;
}
}
public class MenuHolder {
TextView txtTitle;
}
}
}
my xml containing list...
<include
android:id="#+id/header"
android:layout_alignParentTop="true"
layout="#layout/header" />
<RelativeLayout
android:id="#+id/Rlmain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/header"
android:orientation="vertical" >
<TextView
android:id="#+id/TMain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginBottom="8dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="8dp"
android:text="Main Menu"
android:textColor="#000000"
android:textSize="15dp" />
<View
android:id="#+id/Vtop"
android:layout_width="fill_parent"
android:layout_height="2dp"
android:layout_below="#+id/TMain"
android:background="#android:color/darker_gray" />
</RelativeLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#+id/Vbot"
android:layout_below="#+id/Rlmain"
android:orientation="vertical" >
<ListView
android:id="#+id/mainmenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#E0E0E0"
android:cacheColorHint="#00000000"
android:divider="#android:color/transparent"
android:dividerHeight="20dp" >
</ListView>
</RelativeLayout>
<View
android:id="#+id/Vbot"
android:layout_width="fill_parent"
android:layout_height="2dp"
android:layout_above="#+id/textView1"
android:background="#android:color/darker_gray" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="© India Transact Services Ltd."
android:textColor="#000000"
android:textSize="15dp" />
</RelativeLayout>
my xml for list....
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LLtv"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#EEEEEE"
android:cacheColorHint="#00000000" >
<TextView
android:id="#+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingBottom="12dp"
android:paddingTop="12dp"
android:textColor="#000000"
android:textSize="20dp" />
</LinearLayout>
Can please anyone help me and tell where i am going wrong?
What you want can't be achieved with your current setup. You need to implement a custom adapter where you have access to the getView() method. For reasons made clearer in the answer here, what you need to do is use some sort of data-container that will hold the status of an individual row using some indicator and then perform your action based on it's position on the container (which should correspond to its position on the listview)
for example, check out this re-write:
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
resetArrbg();
arrBgcolor[position] = true;
if (arrBgcolor[position]) {
v.setBackgroundColor(Color.parseColor("#FCD5B5"));
} else {
v.setBackgroundColor(Color.BLUE);
}
}
boolean[] arrBgcolor = new boolean[list.size()];
private void resetArrbg() {
for (int i = 0; i < arrBgcolor.length; i++) {
arrBgcolor[i] = false;
}
}
Does it make sense now why it can't work with the current set-up? The else part of the method, the part affecting the other views, can never take place because you don't have access to the other positions in the onListItemClick method, but you do in getView(). This is of course, unless you know of a way around this then, by all means, more power to you. all the same i don't think the v1 technique do you any good.
EDIT:
public class MainActivity extends Activity {
ListView lmenu;
View v1;
String s;
Class<?> ourclass;
View layout, row;
static int trantype;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.menulist);
Menu Menu_data[] = new Menu[] { new Menu("1.White"),
new Menu("2.Blue"), new Menu("3.Purple"), new Menu("4.Red"),
new Menu("5.Yellow"), new Menu("6.Black"), new Menu("6.Black"),
new Menu("6.Black"), new Menu("6.Black"), new Menu("6.Black"),
new Menu("6.Black"), new Menu("6.Black") };
MenuAdapter adapter = new MenuAdapter(this, R.layout.menutext, Menu_data);
lmenu = (ListView) findViewById(R.id.mainmenu);
lmenu.setAdapter(adapter);
}
public class Menu {
public String title;
public Menu() {
super();
}
public Menu(String title) {
super();
this.title = title;
}
}
public class MenuAdapter extends ArrayAdapter<Menu> {
Context context;
int layoutResourceId;
Menu data[];
LayoutInflater inflater;
boolean[] arrBgcolor;
private int activeHex, inactiveHex;
public MenuAdapter(Context context, int layoutResourceId, Menu[] data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
activeHex = Color.parseColor("#FCD5B5");
inactiveHex = Color.parseColor("#EEEEEE");
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
arrBgcolor = new boolean[data.length];
resetArrbg();
}
#Override
public View getView(final int position, final View convertView,
ViewGroup parent) {
final MenuHolder holder;
row = convertView;
// convertView.setBackgroundColor(Color.BLACK);
if (row == null) {
row = inflater.inflate(layoutResourceId, parent, false);
holder = new MenuHolder();
holder.txtTitle = (TextView) row.findViewById(R.id.tv1);
row.setTag(holder);
} else {
holder = (MenuHolder) row.getTag();
}
Menu Menu = data[position];
holder.txtTitle.setText(Menu.title);
if (arrBgcolor[position]) {
row.setBackgroundColor(activeHex);
} else {
row.setBackgroundColor(inactiveHex);
}
holder.txtTitle.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
resetArrbg();
arrBgcolor[position] = true;
notifyDataSetChanged();
}
});
return row;
}
private void resetArrbg() {
for (int i = 0; i < arrBgcolor.length; i++) {
arrBgcolor[i] = false;
}
}
public class MenuHolder {
TextView txtTitle;
}
}
}
This happens because of the way ListView reuses Views when populating the list. Lets say you see three rows of the list at any given time. You "highlight" the first row by setting the background color (like you do), and scroll down. When the first row leaves the screen, Android does something smart. Instead of creating a new View for, say, the fifth row, it reuses the View from row one. That's the View you changed the background color of, so row five now got the same background color. Only the data is changed.
As for how to implement a different background color on the selected row, and the selected row only, have a look at this answer. I do believe you got to implement a custom ListAdapter, at least if you're developing for API levels lower than 11.