I am using an custom adapter and I have the problem with getView method. Here is my code -
#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.list_item, null);
if(position==0){
TextView text1 = (TextView) vi.findViewById(R.id.text1);
text1.setText(data[position]);
}else if(position==1){
TextView text2 = (TextView) vi.findViewById(R.id.text2);
text2.setText(data[position]);
}
return vi;
}
and here is the XML file -
<?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="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:background="#android:color/black"
android:textColor="#android:color/white"
android:id="#+id/text1" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:background="#android:color/green"
android:textColor="#android:color/white"
android:id="#+id/text2" />
</LinearLayout>
Actually my if command is working but the other blank textView also appears with it.
Suppose If position==0 then "#+id/text1" should be displayed, but "#+id/text2" also get displayed with no text.
I want only one textview to be displayed, not the other one. How to do that?
position is the index of the currently displayed item in the adapter, not which TextView is being displayed.
Each row of your Adapter has two TextViews, and I assume you have some string that needs to be displayed in both views.
As an example, try this instead.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
String item = String.valueOf(data[position]);
View v = convertView;
if (v == null) {
v = inflater.inflate(R.layout.list_item, null);
}
TextView text1 = (TextView) v.findViewById(R.id.text1);
TextView text2 = (TextView) v.findViewById(R.id.text2);
text1.setText("1: " + item);
text2.setText("2: " + item);
return v;
}
I want only one textview to be displayed, not the other one. How to do that?
Then it sounds like you don't want two TextViews in one layout...
If you question is literally "How to display more than one TextView in a ListView", then you should put more than one value into that data array.
Related
Im new to android and Im building an app to show stock prices from an XML feed.
I have got an array list containing 3 items. However, I want to change the color of one of the items in the array list to red if its -ve or green if its +ve.
I dont know how to do this or where in my code is best to do it.
Please help....
My Adapter class:
public class TheAdapter extends ArrayAdapter<TheMetal>{
public TheAdapter(Context ctx, int textViewResourceId, List<TheMetal> sites) {
super(ctx, textViewResourceId, sites);
}
#Override
public View getView(int pos, View convertView, ViewGroup parent){
RelativeLayout row = (RelativeLayout)convertView;
Log.i("StackSites", "getView pos = " + pos);
if(null == row){
LayoutInflater inflater = (LayoutInflater)parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = (RelativeLayout)inflater.inflate(R.layout.row_metal, null);
}
TextView dispNameTxt = (TextView)row.findViewById(R.id.displayNameText);
TextView spotPriceTxt = (TextView)row.findViewById(R.id.spotPriceText);
TextView changeTxt = (TextView)row.findViewById(R.id.changeText);
dispNameTxt.setText (getItem(pos).getDisplayName());
spotPriceTxt.setText(getItem(pos).getSpotPrice());
changeTxt.setText(getItem(pos).getChange());
return row;
}
My row_metal layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp" >
<TextView
android:id="#+id/displayNameText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:layout_marginLeft="20dp" />
<TextView
android:id="#+id/spotPriceText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/displayNameText"
android:textSize="19sp"
android:textStyle="bold"
android:gravity="right"
android:layout_alignParentRight="true"
android:layout_marginRight="30dp" />
<TextView
android:id="#+id/changeText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/spotPriceText"
android:layout_toRightOf="#+id/displayNameText"
android:textSize="16sp"
android:gravity="right"
android:layout_alignParentRight="true"
android:layout_marginRight="20dp"
/>
It is so simple. You just need to place these line within your getView() method:
if (Double.parseDouble(getItem(pos).getChange())>=0) {
row.setBackgroundColor(Color.parseColor("#00FF00");
changeTxt.setTextColor(Color.parseColor("#00FF00"));
} else {
row.setBackgroundColor(Color.parseColor("#FF0000");
changeTxt.setTextColor(Color.parseColor("#FF0000"));
}
Change your getView() method to this
#Override
public View getView(int pos, View convertView, ViewGroup parent){
if(convertView == null)
convertView = getLayoutInflater().inflate(R.layout.row_metal, null);
TextView dispNameTxt = (TextView) convertView .findViewById(R.id.displayNameText);
TextView spotPriceTxt = (TextView) convertView .findViewById(R.id.spotPriceText);
TextView changeTxt = (TextView) convertView .findViewById(R.id.changeText);
dispNameTxt.setText(getItem(pos).getDisplayName());
spotPriceTxt.setText(getItem(pos).getSpotPrice());
changeTxt.setText(getItem(pos).getChange());
if( Double.parseDouble(getItem(pos).getSpotPrice()) >= 0 )
convertView.setBackgroundColor(Color.GREEN);
else
convertView.setBackgroundColor(Color.RED);
return convertView;
}
I'm trying to populate custom ListView with this LazyAdapter class from this tutorial
I want to make list view items with custom design. Layout file list_row.xml is in my layouts file just like in the tutorial. This is a slightly modified getView function in LazyAdapter class:
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
//vi = inflater.inflate(R.layout.list_row, null); //EDITED
vi = inflater.inflate(R.layout.list_row, parent, false);
TextView title = (TextView)vi.findViewById(R.id.title); // title
TextView subtitle = (TextView)vi.findViewById(R.id.subtitle); // artist name
//ImageView thumb_image=(ImageView)vi.findViewById(R.id.list_image);
//This is not needed
//HashMap<String, String> post = new HashMap<String, String>();
HashMap<String, String> post;
post = data.get(position);
// Setting all values in listview
title.setText(post.get("title")); //the code crashes here
subtitle.setText(post.get("subtitle"));
//imageLoader.DisplayImage(song.get(CustomizedListView.KEY_THUMB_URL), thumb_image);
return vi;
}
Well this code crashes at title.setText(), because the title is null. I read somewhere that this makes sense because this LazyAdapter is calling findViewById before setContentView or something..
So how do I have to do this? And how does this code work for that guy?
Update
This is the list_row.xml file:
<?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="wrap_content"
android:background="#drawable/list_selector"
android:orientation="horizontal"
android:padding="5dip" >
<!-- Title -->
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#040404"
android:typeface="sans"
android:textSize="14sp"
android:textStyle="bold"/>
<!-- Subtitle -->
<TextView
android:id="#+id/subtitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/subtitle"
android:textColor="#343434"
android:textSize="10sp"
android:layout_marginTop="1dip" />
</RelativeLayout>
To save space I'm only adding ListView xml from the main activity layout file:
<ListView
android:id="#+id/feedListView"
android:layout_marginTop="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/volumeControl1">
</ListView>
Adapter code: http://pastebin.com/niC1yXiJ
And the stack trace: http://pastebin.com/myW8B0Xz
Try passing in the parent when you inflate your cell. Using this method:
public View inflate (int resource, ViewGroup root, boolean attachToRoot)
vi = inflater.inflate(R.layout.list_row, parent, false);
This was a hell of a ride (two sleepless nights). Thanks for all your help, somehow I fixed it! :)
Mostly thanks to this question Null pointer exception in getView() of custom Adapter I made new getView function:
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = new ViewHolder();
View vi = convertView;
if (vi == null) {
LayoutInflater inflater = ((Activity)activity).getLayoutInflater();
vi = inflater.inflate(R.layout.list_row, null);
holder.title = (TextView) vi.findViewById(R.id.title);
holder.subtitle = (TextView) vi.findViewById(R.id.subtitle);
vi.setTag(holder);
} else {
holder = (ViewHolder) vi.getTag();
}
HashMap<String, String> post;
post = data.get(position);
holder.title.setText(post.get("title"));
holder.subtitle.setText(post.get("subtitle"));
return vi;
}
holder is just a simple class:
private class ViewHolder {
public TextView title;
public TextView subtitle;
}
I've done that and I also copied xml drawable files in all drawable folders (merged all). So one of this actions fixed it, but I'm not quite sure what..
If you get android.widget.AbsListView.obtainView(AbsListView.java:1408) exception than your returned View of getView() is probably null.So check first of all that you are not return null view.
I am new to android and am trying to create two fragments and have it so you can slide between the two, one is a list and the otehr a grid. I had the list working when it when I was using an ArrayAdapter and had my EventListFragment extending ListFragment (if code is helpful let me know and ill post that part)
I am now trying to create a custom list view with multiline list items (let me know if there is an easier way and if i have simply overcomplicated the whole thing)
Here is my code:
Event List Fragment:
public class EventListFragment extends Fragment {
ArrayList<EventObject> eventObjects;
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
eventObjects = ((EventsActivity)getActivity()).getEventObjects();
View view = inflater.inflate(R.layout.eventgrid ,container,false);
Listview listView = (ListView) view.findViewById(R.id.listView);
if (listView == null) {
System.out.println("asas");
}
listView.setAdapter(new MyCustomBaseAdapter(getActivity().getBaseContext(), eventObjects));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
Object o = listView.getItemAtPosition(position);
EventObject fullObject = (EventObject)o;
System.out.println("asd");
}
});
return view;
}
}
The corresponding xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<ListView
android:id="#+id/listView"
android:layout_height="wrap_content"
android:layout_width="fill_parent"/>
</RelativeLayout>
The xml for the customgridrow:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="#+id/name"
android:textSize="14sp"
android:textStyle="bold"
android:textColor="#FFFF00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/cityState"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
EDIT
The getView() from MyCustomBaseAdapter :
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.customgridrow, null);
holder = new ViewHolder();
holder.txtName = (TextView) convertView.findViewById(R.id.name);
holder.txtCityState = (TextView) convertView.findViewById(R.id.cityState);
holder.txtPhone = (TextView) convertView.findViewById(R.id.phone);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtName.setText(events.get(position).getName());
holder.txtCityState.setText(events.get(position).getDate());
holder.txtPhone.setText(events.get(position).getVenue());
return convertView;
}
From your comments
You are inflating the wrong layout
You should inflate the one that has listview and initialize the same.
Change
View view = inflater.inflate(R.layout.eventgrid ,container,false);
to
View view = inflater.inflate(R.layout.eventList ,container,false);
Every time you want to add an object to a list, you have to provide a view for the object. Android asks your list adapter, be it custom or system-defined, it asks the adapter what each list item is supposed to look like. This is where getView() comes into play.
public abstract View getView (int position, View convertView, ViewGroup parent):
Get a View that displays the data at the specified position in the data set.
If convertView is null, you will get an NPE.
Tutorials here: http://www.javacodegeeks.com/2013/06/android-listview-tutorial-and-basic-example.html
This question has been asked here a link
Also I want to clarify the question
I have 10 List Items in a Listview
I want to have the deviderheight of each List Items differently like for first Item it should be setDividerheight(2) for 2nd setDividerheight(4) like this..
I have made a custom Adapeter in which I am setting my Layout Like
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
if(position ==2)
{
if (v != convertView && v != null) {
ViewHolder holder = new ViewHolder();
// TextView tv = (TextView) v.findViewById(R.id.artist_albums_textview);
// holder.albumsView = tv;
convertView = mInflater.inflate(R.layout.jazz_artist_list_item, null);
holder.albumsView = (TextView)convertView.findViewById(R.id.artist_albums_textview);
// lv.setDividerHeight(8);
v.setTag(holder);
}
}
else
{
if (v != convertView && v != null) {
ViewHolder holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.jazz_artist_list_item, null);
holder.albumsView = (TextView)convertView.findViewById(R.id.artist_albums_textview);
// lv.setDividerHeight(2);
v.setTag(holder);
}
}
}
but this seems not working properly.
Any idea on above this as how to set the divider height of Listview dynamically
Regards,
Laxmikant
//set Divider as you like
listView.setDivider((Drawable) getResources().getDrawable(R.drawable.orange));
//then set the height dynamically
listView.setDividerHeight(1);
in your Activity which has the ListView. Not the Adapter class.
If you what exactly what you wrote in the question. Do this:
let each listView Item layout contain a TextView and a View(divider after each item), then depending on the position parameter you get in the getView() method change the Height of the View.
ListView Item 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="wrap_content"
android:padding="5dp" >
<TextView
android:id="#+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/logo"
android:padding="5dp"
android:textSize="14dp" >
</TextView>
<View
android:id="#+id/view"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_below="#id/label"
android:background="#drawable/orange" />
</RelativeLayout>
now in the adapter class your ViewHolder contains the TextView and also the View.
so,
Holder.View = (View)convertView.findViewById(R.id.view);
if(position == 0){
(Holder.View).setHeight(2);
}
and so on.
A slight tweak to above got it working for me (no setHeight() method in View?), thanks:
Holder.View = (View)convertView.findViewById(R.id.view);
if(position == 0){
(Holder.View).getLayoutParams().height = *your desired height e.g. 20*;
}
Hey im trying to get a List working, in that case i have a xml defined item, which i inflate in a extended ArrayAdapter. But after i have inflated the xml, then when i try to grab the imageview, it returns null by findviewbyid...
Here is xml for the item:
<?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" >
<TextView
android:id="#+id/product_item_textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="if no image avail show this"
android:visibility="gone"/>
<ImageView
android:id="#+id/product_item_imageview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="visible"
/>
</LinearLayout>
Method that instatiates the item:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
SimpleListItem item= items.get(position);
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = vi.inflate(R.layout.product_item, null);
if(item.getPicture()!=null)
{
ImageView imgVw = (ImageView) findViewById(R.id.product_item_imageview);
String picturePath = item.getPicture();
Bitmap picture = ImageManager.get(getBaseContext(), picturePath);
imgVw.setImageBitmap(picture);
} else {
TextView txtVw = (TextView) findViewById(R.id.product_item_textview);
txtVw.setText(item.getText());
txtVw.setVisibility(View.VISIBLE);
}
return v;
}
Its a,
ImageView imgVw = (ImageView) v.findViewById(R.id.product_item_imageview);
also the same for TextView,
TextView txtVw = (TextView) v.findViewById(R.id.product_item_textview);
Use View v for getting ImageView and TextView from your inflated xml file.
//you are inflating layout in a view v so you need to get them by
ImageView imgVw = (ImageView)v. findViewById(R.id.product_item_imageview);
TextView txtVw = (TextView)v. findViewById(R.id.product_item_textview);