I have a horizontal scroll view with array list of images and the text field below the scroll view,how could i change the text on changing image in horizontal scrollview.
For Example: The image will show Mountain the text will also texted with mountain
Here The image will only scroll, the text view will remain fix, it will change the name with images only
I have used the code below for scrolling image ,it is working fine, images are changing but the textview didn't change !!
could anybody help me !! #Thanks in advance
public View getView(int position, View convertView, ViewGroup parent) {
vi=convertView;
if(convertView==null){
vi = LayoutInflater.from(parent.getContext()).inflate(R.layout.screen, null);
position_pin = position;
Holder.images=(ImageView) vi.findViewById(R.id.image);
Holder.textview=(TextView) vi.findViewById(R.id.name);
Holder.images.setImageResource(imageIds[position]);
Holder.text.setText(name);
vi.setTag(Holder);
}
return vi;
}
If you have any better option or code then help me.
I guess problem is in about your way to get correspond name.But you have an option(however it is strange!):
You can merge each image and it's description to another image and only show the result.If you want to do this,you can use your R.layout.screen or directly use a canvas and add your image and desired description to it.
Your code suggests that you set the text only when the convertView is null. Generally adapter views are re-cycled so the update should happen even when a new view isn't formed.
Arraylist<String> nameList = new ArrayList<String>();
// add your names the same way you add your images to your images array
...
name = nameList.get(position);
textView.setText(name);
I would think something like that should work
It looks like you are using a ViewHolder so you should add to your if statement
else
{
Holder = (ViewHolder) vi.getTag();
}
To reuse your Views
Related
I try to add dynamic number of cell inside listview using custom cell layout and ArrayAdapter and it done well. But i face a problem when i want each cell may different follow type of data.
Example i have 3 categories inside a listview :
Video (video_custom_cell.xml)
Photo (photo_custom_cell.xml)
Audio (audio_custom_cell.xml)
if data is video then i use cell number one, else if data is photo i use photo_custom_cell and else i use audio_custom_cell.
What i have tried only can reuse a custom cell for dynamic number of row, but i still not find how to use custom cell follow by type of data inside cell.
Can anyone help me to explain an example for my problem?
Thank you.
You can use a custom adapter for this and inside the getView function you do for example:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView;
if (convertView == null) {
if(items.get(position).type.equals("video")) {
rowView = getActivity().getLayoutInflater().inflate(
R.layout.video_custom_cell, null);
}else if(items.get(position).type.equals("photo")) {
rowView = getActivity().getLayoutInflater().inflate(
R.layout.photo_custom_cell, null);
}
} else {
rowView = convertView;
}
}
In my listview I have a custom Adapter, which I build using a TreeMap, I defined the getView method which is as follows. I am trying to strike out the text in a certian textview of the listview on click, only those textviews will be striken off which contain a certain pattern of characters (y#y). However on clicking one row in the listview I am getting strike out effect on some other row.
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.chklistlayout, parent, false);
}
TextView textView = ((TextView) convertView.findViewById(R.id.textView1));
TextView imageview = ((TextView) convertView.findViewById(R.id.textView2));
textView.setText(values[position]);
imageview.setText(mValues[position]);
String s = mValues[position];
if (s.contains("y#y")) {
System.out.println("In if of getview");
System.out.println(s);
imageview.setPaintFlags(imageview.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
} else {
}
return convertView;
}
}
I tried using a holder pattern too, using a static holder class, but the problem seems to persist. Any pointers?
this answer is half mine and half from Muhammad Babar that we both commented on the question making together a quite nice answer:
use else block to handle this, imageview.setPaintFlags() not to strike
that happens
Because of the convertView. When you scroll the list the same view
that was used before is give back to getView method. So the same
imageView that you painted with StrikeThrough before is still painted
with it. So you have to revert that action.
more over, because of this recycling, usually dealing with Adapters you must ALWAYS undo/revert/repaint/change text/change image to all the elements to make sure it will be on screen the way you want.
ps.: now you should apply a Holder pattern to get better performance.
I'm trying to do a List that shows an image and a simple text describing the image.
In my search on internet I found many ways to do this. Some people using ArrayAdapter, others using SimpleCursorAdapter. One thing I notice, many people are creating classes inheriting from ListActivity and in the setListAdapter method they are inserting other classes derived from Array or SimpleCursor adapter.
First question: is this the best way to do this?
I created a LinearLayout with a ListView inside. And to insert rows, another layout was created with an ImageView and a TextView.
Second question: is this correct?
I'm confusing about creation of this type of component. Is this the correct way to do this?
Yes, this is correct, although you will need to use a CursorAdapter instead of a SimpleCursorAdapter, since the point of a SimpleCursorAdapter is to populate a row with only a TextView in it.
You will have a getView method on your CursorAdapter that expands your row layout:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) { // we don't have a recycled view
convertView = LayoutInflator.from(getContext()).inflate(
R.layout.row, parent, false);
}
// setup our row
TextView text = (TextView) convertView.findViewById(R.id.text_view);
text.setText( ... );
ImageView image = (ImageView) convertView.findViewById(R.id.image_view);
image.setImageBitmap( ... );
return convertView;
}
When you're setting the text and image of your views, you can use adapter methods like getItem to access the underlying data you need.
I am working on customize (inflated) list view. In which I have used the text and background image for text (as per the condition).
Now I am facing problem in scrolling the list view that background of text view is overlapping to the other text views.
Here is the sample code:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View icontextlayout=convertView;
icontextlayout= inflater.inflate(R.layout.layout_complex_list, null);
TextView Txt1=(TextView)icontextlayout.findViewById(R.id.txt1);
if(disp1==true)
{
Txt1.setBackgroundResource(R.drawable.pic)
}
else
Txt1.setText("Text1 "+strUser);//
TextView Txt2=(TextView)icontextlayout.findViewById(R.id.txt2);
if(disp2==true)
{
Txt2.setBackgroundResource(R.drawable.pic);
}
else Txt2.setText("Text2: "+strIndus);
return icontextlayout;
}
Could you please help me out that background image pic do not overlap the others background.
Thanking you...
The problem is that you must set a default background when you don't need a background. For instance:
if(disp1==true){
Txt1.setBackgroundResource(R.drawable.pic);
Txt1.setText("");
}
else{
Txt1.setText("Text1 "+strUser);//
Txt1.setBackgroundDrawable(null);
}
Also, if you don't mind, I like to give you my opinion about your code:
That's not they way in which list are usually populated. Take a look at this answer: How to load the Listview "smoothly" in android
convertView is used to reuse rows. In your case you are doing something like:
View icontextlayout=convertView;
icontextlayout= inflater.inflate(R.layout.layout_complex_list, null);
Which is bad, because you are not actually using the convertView (when you call inflater.inflate) it will create a new row, thus your list will be really slow.
if(disp2==true) is redundant. You should consider using just: if(disp2).
I have a ListView with custom ArrayAdapter. Each of the row in this ListView has an icon and some text. These icons are downloaded in background,cached and then using a callback, substituted in their respective ImageViews. The logic to get a thumbnail from cache or download is triggered every time getView() runs.
Now, according to Romain Guy:
"there is absolutely no guarantee on
the order in which getView() will be
called nor how many times."
I have seen this happen, for a row of size two getView() was being called six times!
How do I change my code to avoid duplicate thumbnail-fetch-requests and also handle view recycling?
Thanks.
Exactly, that could happen for example when you have
android:layout_height="wrap_content"
in your ListView definition. Changing it to fill_parent/match_parent would avoid it.
From api.
public abstract View getView (int position, View convertView,
ViewGroup parent)
convertView - The old view to reuse, if possible. Note: You should check that this view is non-null and of an appropriate type before using. If it is not possible to convert this view to display the correct data, this method can create a new view.
So if getView has already been called for this specific index then convertView will be the View object that was returned from that first call.
You can do something like.
if(!(convertView instanceof ImageView)){
convertView = new ImageView();
//get image from whereever
} else {} // ImageView already created
I m experiancing the same issue i change the layout_height of listView to match_parent resolve my issue.
My understanding is that you need to use the ViewHolder design pattern here. Just using a returned convertView can lead to reuse of a previous view (with some other image assigned in this case).
public class ImageAdapter extends ArrayAdapter<String> {
// Image adapter code goes here.
private ViewHolder {
public ImageView imageView;
public String url;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;
ViewHolder viewHolder;
String url = getUrl(position);
if (convertView == null) {
// There was no view to recycle. Create a new view.
view = inflator.inflate(R.layout.image_layout, parent, false);
viewHolder = new ViewHolder();
viewHolder.imageView = (ImageView) view.findViewById(R.id.image_view);
viewHolder.url = url;
view.setTag(viewHolder);
} else {
// We got a view that can be recycled.
view = convertView;
viewHolder = ((ViewHolder) view.getTag());
if (viewHolder.url.equals(url)) {
// Nothing to do, we have the view with the correct info already.
return view;
}
}
// Do work to set your imageView which can be accessed by viewHolder.imageView
return view;
}
}
The better would be to create a object with Thumbnail(bitmap) and the text. And read the thumbnail if its not available in the object.
Create an array of ImageView objects in your adapter and cache them as you retrive them (whether from cache or web). For example, in getView, before you fetch the ImageView, check if it's already in your local array, if so, use it, if not fetch, once received store in your local ImageView array for future use.
My Fragment.xml has a ListView, the layout setting of this ListView was android:layout_height="wrap_content", and this ListView will bind to SimpleCursorAdapter later. Then I have the same issue in ViewBinder be called 3 times. The issue resolved after I change the layout_height="wrap_content" to "95p". I do consider that the "wrap_content" height cause this issue.
Trying to modify your Fragment.xml and I guess the 3 times called issue will no longer exist.