I created the Layout design using java code only not from the XML Layout Designs. The code I used is following
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv = new TextView(mContext);
tv.setText(hotelList.get(position).name);
return tv;
}
How to use layoutInflator for creating layout fro this. I need 2 more textviews in a single list item. the whole list contains 10 different list items
Please provide some codes for this. Help appreciated
I have gone through this before by having my static class too. Check this out, it will help:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
if ( rowView == null) {
LayoutInflater inflator = this._activity.getLayoutInflater();
rowView = inflator.inflate(R.layout.todolistlisting, null);
TodoListViewHolder viewHolder = new TodoListViewHolder();
viewHolder._name = (TextView) rowView.findViewById(R.id.tVTLName);
viewHolder._completed = (TextView) rowView.findViewById(R.id.tVTLCCount);
viewHolder._remaining = (TextView) rowView.findViewById(R.id.tVTLRCount);
rowView.setTag(viewHolder);
}
TodoListViewHolder holder = (TodoListViewHolder) rowView.getTag();
VO_TodoList votodolist = this._items.get(position);
holder._name.setText(votodolist._title);
holder._completed.setText(votodolist._completed);
holder._remaining.setText(votodolist._remaining);
return rowView;
}
TodoListViewHolder is my view component holder here. like your TextView.
I guess you know how to make XML layout for this layout. So just make the XML layout and get the object of the main layout using the following code:
LinearLayout mainLayout=(LinearLayout) View.inflate(R.layout.yourlayout); //if yourlayout.xml is the name of the xml file you made and put in the layout folder.
To get the child of the layout, let's say if it's a TextView with the id text, then the code would be:
TextView textView=(TextView)mainLayout.findViewById(R.id.text);
You can add view at runtime by using inflater like this
LinerLayout linearLayout = (LinearLayout)inflater.inflate(R.layout.news_categories_item, null);
TextView categoryValueTextView = (TextView)linearLayout.findViewById(R.id.news_category_item_value);
mMainLinearLayout.addView(categoryValueTextView);
Here i am inflating one text view which is there in another linear layout(this is simple linear layout which holds only textview) at runtime and adding it to my main linear layout.
you can get the inflater object in your acitivity by using getLayoutInflater(). And if you want to get inflater in adapter you have to pass inflater object to constructor of adapter from your activity.
Related
I'm using one from the built-in list item layout in my app.
I want to change the style of this list like text color or size of text .
I'm using simple_list_item_1 from these items .
Can you help me how I can do that.
You should make a custom Layout and inflate it in getView() method of Adapter.
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row;
row = inflater.inflate(R.layout.custom, parent, false);
TextView title, detail;
ImageView i1;
title = (TextView) row.findViewById(R.id.title);
detail = (TextView) row.findViewById(R.id.detail);
i1=(ImageView)row.findViewById(R.id.img);
title.setText(Title[position]);
detail.setText(Detail[position]);
i1.setImageResource(imge[position]);
return (row);
}
you can look into this thing more on Custom Listview
and from my personal opinion you can use RecyclerView for better Customisation.
Do you mean in the Android Studio preview?
If so, tools:listitem="#layout/list-item-layout" is your friend.
Create your own layout and place it in your app layout directory and refer that in your code instead of simple_list_item_1
Example here
R.layout.<yourLayoutName>
instead of
android.R.layout.simple_list_item_1
And customize the layout as you like it!!
Am getting the following warning in Eclipse:
"Unconditional layout inflation from view adapter: Should use View Holder pattern (use recycled view passed into this method as the second parameter) for smoother scrolling"
The code which i had used is:
class myadapter extends ArrayAdapter<String>
{
Context context;
int[] images;
String[] mytitle;
String[] mydescp;
myadapter(Context c, String[] tittle, int[] imgs, String[] desc)
{
super(c, R.layout.single_row, R.id.listView1, tittle);
this.context=c;
this.images=imgs;
this.mytitle= tittle;
this.mydescp=desc;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflator.inflate(R.layout.single_row, parent, false);
ImageView myImage = (ImageView) row.findViewById(R.id.imageView1);
TextView myText = (TextView) row.findViewById(R.id.textView1);
TextView mydesc = (TextView) row.findViewById(R.id.textView2);
myImage.setImageResource(images[position]);
myText.setText(mytitle[position]);
mydesc.setText(mydescp[position]);
return row;
}
}
Am getting warning in the line : View row = inflator.inflate(R.layout.single_row, parent, false);
And it causes my android application to Force Close... What can i do it now??
Any Suggestions???
You need to recycle your views.What android as a system cares about is only the items that are visible.So you have to recycle the row items which are out of focus to be re-used for the newitems.
Or else imagine the amount of caching involved.
#Override
public View getView(int position, View row, ViewGroup parent) {
// TODO Auto-generated method stub
if(row==null){
LayoutInflater inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflator.inflate(R.layout.single_row, parent, false);
}
ImageView myImage = (ImageView) row.findViewById(R.id.imageView1);
TextView myText = (TextView) row.findViewById(R.id.textView1);
TextView mydesc = (TextView) row.findViewById(R.id.textView2);
myImage.setImageResource(images[position]);
myText.setText(mytitle[position]);
mydesc.setText(mydescp[position]);
return row;
}
You should re-use the view instead of inflating again and again. This brings down performance.
From your code,
View row = inflator.inflate(R.layout.single_row, parent, false);
this will inflate everytime when you scroll. To maximize the performance, use it like
//re-use
if (row == null)
{
inflate code here
}
else
{
you already have a view `row`, just use it.
}
You can see, for the first time row will be null & it will inflate and store it in View row. But, from the next time, it's not going to inflate again and again instead it will use the View row. (Re-use)
"Unconditional layout inflation from view adapter: Should use View Holder pattern (use recycled view passed into this method as the second parameter) for smoother scrolling"
It's not the error it's just the warning for asking you to use ViewHolder Pattern. Let me explain you why it's important.
Without ViewHolder Pattern :
The first time it was loaded, convertView is null. We’ll have to inflate our list item layout and find the TextView via findViewById().
The second time it was loaded, convertView is not null, good! We don’t have to inflate it again. But we’ll use findViewById() again.
The following times it was loaded, convertView is definitely not null. But findViewById() is constantly called, it will work but, it slows down the performance especially if you have lots of items and Views in your ListView.
With the ViewHolder Design Pattern :
The first time it was loaded, convertView is null. We’ll have to inflate our list item layout, instantiate the ViewHolder, find the TextView via findViewById() and assign it to the ViewHolder, and set the ViewHolder as tag of convertView.
The second time it was loaded, convertView is not null, good! We don’t have to inflate it again. And here’s the sweet thing, we won’t have to call findViewById() since we can now access the TextView via its ViewHolder.
The following time it was loaded, convertView is definitely not null. The findViewById() is never called again, and that makes our smooth ListView scrolling.
Why to use?
Your code might call findViewById() frequently during the scrolling of ListView, which can slow down performance. Even when the Adapter returns an inflated view for recycling, you still need to look up the elements and update them. A way around repeated use of findViewById() is to use the view holder design pattern.
So, what is ViewHolder?
A ViewHolder object stores each of the component views inside the tag field of the Layout, so you can immediately access them without the need to look them up repeatedly. First, you need to create a class to hold your exact set of views.
How to use?
Make a separate class as ViewHolder & declare what you use like EditText,TextView etc..
static class ViewHolder {
TextView text;
TextView timestamp;
ImageView icon;
ProgressBar progress;
int position;
}
Then populate the ViewHolder and store it inside the layout.
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) { // if convertView is null
convertView = mInflater.inflate(R.layout.mylayout,
parent, false);
holder = new ViewHolder();
// initialize views
convertView.setTag(holder); // set tag on view
} else {
holder = (ViewHolder) convertView.getTag();
// if not null get tag
// no need to initialize
}
//update views here
return convertView;
}
Source :
Making ListView Scrolling Smooth from Android documentation
Android ViewHolder Pattern example
Hi Vinesh Senthilvel ,
Don't worry
Use my code below , It will definetely solve your problem,
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflator.inflate(R.layout.single_row, null, false);
ImageView myImage = (ImageView) row.findViewById(R.id.imageView1);
TextView myText = (TextView) row.findViewById(R.id.textView1);
TextView mydesc = (TextView) row.findViewById(R.id.textView2);
myImage.setImageResource(images[position]);
myText.setText(mytitle[position]);
mydesc.setText(mydescp[position]);
return row;
}
If still problem persists then post logcat exception stack trace ,I will help you
There is a another approach , You just have to import android.view.LayoutInflater; and take the context of parent (ViewGroup) - parent.getContext() ,It will work
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.single_row, parent, false);
You have to use this code
View row = convertView;
before this line,
View row = inflator.inflate(R.layout.single_row, parent, false);
Hope it works..
the problems is, that I wan't to make ListView with elements which are containing image, description and two buttons. I'm making them in my own BaseAdapter extension, but fragment which is containing ListView is closing (wihtout errors in logcat..). I've found, that ListView is working well, when I'm not returning layout-type elements. So there is my sample with 'sample linear layout', which is not working.. Is there any possibility, to show layouts in ListView?
Here is my code:
Creating part:
lv = (ListView) getView().findViewById(R.id.main_wall_ambajes_lv);
AmbajAdapter aa = new AmbajAdapter(getActivity().getApplicationContext(), StaticData.ambajes);
lv.setAdapter(aa);
My getView method from adapter:
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout ll = new LinearLayout(getActivity());
ll.setOrientation(LinearLayout.VERTICAL);
ImageView iv = new ImageView(getActivity());
iv.setImageBitmap(placeholderBitmap);
ll.addView(iv);
ll.addView(iv);
ll.addView(iv);
ll.addView(iv);
return ll;
}
I don't know why you don't have any error however I don't think you proceed the correct way.
Usually you create the layout in the xml file of the layout folder and only inflate it in the getView(), for example as follow :
private LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
#Override
public View getView(int position, View view, ViewGroup parent) {
if (view == null) {
view = mInflater.inflate(R.layout.your_custom_layout, parent, false);
}
//your code for setting the image or other things goes here
//for example if you have a textView
TextView textView = (TextView) view.findViewById(R.id.my_textview_id);
textView.setText("my custom text for this cell");
return (view);
}
and your_custom_layout is simply the xml file of your layout.
Note that for performance reason due to cell recycling I only inflate the view when it is null and I only read once the LayoutInflater context and put it in mInflater. However for the best performance you should use a ViewHolder, but it is out of the scope of your question.
I've written this code from a tutorial.
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.single_row, viewGroup,false);
TextView title = (TextView) row.findViewById(R.id.txtTitle);
TextView description = (TextView) row.findViewById(R.id.txtDescription);
ImageView image = (ImageView) row.findViewById(R.id.imgPic);
SingleRow temp = list.get(i);
title.setText(temp.title);
description.setText(temp.description);
image.setImageResource(temp.image);
return row;
}
In this line of code:
TextView title = (TextView) row.findViewById(R.id.txtTitle);
I think a TextView is copied to a variable of the same kind. and then in this line of code:
title.setText(temp.title);
we fill that variable with something. then the row variable which is a View and it's not related to 'title' variable is returned.
How it works? I thinks these variables have nothing to do here.
This code inflates a new view, settings it's contents. This means that you're creating a new view programatically. It's often used i.e. when populating a list, where you'll have number of rows, each identical in structure, but with different values.
Here is how it works:
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
// Get the inflater service
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Inflate view with ID = R.layout.single_row into the row variable
View row = inflater.inflate(R.layout.single_row, viewGroup,false);
// Get child views of row: title, description and image.
TextView title = (TextView) row.findViewById(R.id.txtTitle);
TextView description = (TextView) row.findViewById(R.id.txtDescription);
ImageView image = (ImageView) row.findViewById(R.id.imgPic);
// This get's some template view which will provide data: title, description and image
SingleRow temp = list.get(i);
// Here you're setting title, description and image by using values from `temp`.
title.setText(temp.title);
description.setText(temp.description);
image.setImageResource(temp.image);
// Return the view with all values set. This view will be later probably added somewhere as a child (maybe into a list?)
return row;
}
That's the method used to return the view for a row in the listview. row variable is actually related to title, as you can see here.-
TextView title = (TextView) row.findViewById(R.id.txtTitle);
in other words, title is a TextView inside row object, and that code retrieves it to set its text. To sum up, the whole getView method is inflating a single_row View, and setting properties for all relevant children of row.
View row = inflater.inflate(R.layout.single_row, viewGroup,false);
You are inflating a layout single_row
TextView title = (TextView) row.findViewById(R.id.txtTitle);
Initializing textview which is in singlerow.xml
title.setText(temp.title);
Setting title to textview.
You are infalting a layout for each row in listview.
Also it is better to use a viewHolder pattern.
http://developer.android.com/training/improving-layouts/smooth-scrolling.html
Also you can move the below to the constructor of adapter class and declare inflater as a class member
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
The below link may be of interest to you
How ListView's recycling mechanism works
http://developer.android.com/design/media/lists_main.png
As you can see above, I would like to create the 3-line list.
I have looked everywhere but I can't seem to find any documentation on how to do it.
How do I write my adapter for this kind of ListView?
Do I have to extend ListActivity, include a ListView in my .xml layout, or both?
Can somebody provide further insight into it? I'll be very grateful...
You create an XML-Layout for your list-item (row) with three TextViews in a vertical LinearLayout. Then you need to subclass the ArrayAdapter to fill the TextViews. In the getView you fill the lines.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (convertView == null) {
LayoutInflater vi = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.listitem, null);
}
TextView text1 = (TextView) convertView.findViewById(R.id.textfield1);
if (text1 != null) {
text1.setText(contentArray.get(position).valueForField1);
}
// same for the other fields
return v;
}