I have this problem with my InfoWindow in my Android app. When I run this code:
#Override
public View getInfoWindow(Marker marker) {
LayoutInflater inflater = getLayoutInflater();
View view = inflater.inflate(R.layout.lkonty, null);
TextView txtName= (TextView) findViewById(R.id.txtName);
txtName.setText(marker.getTitle());
return view;
The app crashes while running the setText method. I found a solution by adding this line of code:
setContentView(R.layout.lkonty);
The app is no longer crashing but now the InfoWindow fills the whole screen and I don't know how to change that.
Try this
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.lkonty,parent,false);
TextView txtName= (TextView) view.findViewById(R.id.txtName);
txtName.setText(marker.getTitle());
App crashes because your textview txtName is null.
You must find your txtName by view you inflated.
It will like this:
#Override
public View getInfoWindow(Marker marker) {
LayoutInflater inflater = getLayoutInflater();
View view = inflater.inflate(R.layout.lkonty, null);
TextView txtName= (TextView) view.findViewById(R.id.txtName);
txtName.setText(marker.getTitle());
return view;
}
i think you forgot to use you view while binding your textview.
TextView txtName= (TextView) view.findViewById(R.id.txtName);
you have to use view while use of inflater.
Related
In my onCreate I have a layout which i want to set Dynamically
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View coachLayout = inflater.inflate(R.layout.coach_content, null);
LinearLayout coachLinear = (LinearLayout) coachLayout.findViewById(R.id.coachLinear);
TextView titleView = (TextView) coachLayout.findViewById(R.id.coachTitle);
updateTitleView(activity, widget, titleView);
I wish to pass my View coachlayout, into setContentView(R.layout.activity_main)
However setContentView only accepts the Resource id or int. So is there anyway to pass my coachlayout into setContentView?
Thanks
I want to add textview dynamically for which I have added the below code.But I am do not see any textview on my activity. I cant add a listview as I am already using recycleview . Any one any error ?
{
LayoutInflater layoutInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout review_layout = (LinearLayout) rootMovieView.findViewById(R.id.review_comment);
for (ReviewsResult comment : review.getReviewsResults()) {
View view = layoutInflater.inflate(R.layout.layout_movie_comments, review_layout, false);
TextView tvCommentBy = (TextView) view.findViewById(R.id.tv_comment_by);
TextView tvCommentContent = (TextView) view.findViewById(R.id.tv_comment_content);
tvCommentContent.setText(comment.getContent());
tvCommentBy.setText(comment.getAuthor());
review_layout.addView(view);
}
}
You can also try something like this
View myLay; // view that contains you textView
LinearLayout rootlay; //root view in which you want to add
myLay = LayoutInflater.from(this).inflate(R.layout.layout_movie_comments,
null);
TextView tvCommentBy = (TextView) view.findViewById(R.id.tv_comment_by);
TextView tvCommentContent = (TextView) myLay.findViewById(R.id.tv_comment_content);
tvCommentContent.setText(comment.getContent());
tvCommentBy.setText(comment.getAuthor());
rootlay.addView(myLay);
Hope this helps :)
Do below two changes and check weather it is working or not, as nothing else seems to wrong in code.
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = layoutInflater.inflate(R.layout.layout_movie_comments, null);
rootMoviewView is not the rootView it was a recylceView in a rootView .This way the textview is generated in rootView not in recylceView.
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..
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
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.