i have an activity to show user contacts list. if contact exists in my app i want to show a follow button , else i want to show a whatsapp and telegram icon to invite them.
when i open the activity every thing is fine as i want , but when i scroll down and come back up follow buttons and whats app icons get mixed for different contacts ! the users who had follow button may see whatsapp icon or the others may see follow button !
and everytime i scroll down and up again positions will change !
i should say all contacts name and mobile number are fixed and correct ! just images get mixed !
i know the problem is from my getView function but dont know how to fix it :(
how can i fix it ? tnx :)
Here is all of my adapter code :
public class LazyAdapterContactsList extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
public ImageLoader profileImageLoader;
HashMap<String, String> song;
public LazyAdapterContactsList(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
profileImageLoader=new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
ViewHolder holder = null;
if(vi==null) {
vi = inflater.inflate(R.layout.contacts_list_row, null);
holder = new ViewHolder();
holder.listID = (TextView) vi.findViewById(R.id.MyContactslistIDPosition);
holder.name = (TextView) vi.findViewById(R.id.MyContactslistName);
holder.mobile = (TextView) vi.findViewById(R.id.MyContactslistMobileNumber);
holder.whatsAppIcon = (ImageView) vi.findViewById(R.id.MyContactsListWhatsApp);
holder.telegramIcon = (ImageView) vi.findViewById(R.id.MyContactsListTelegram);
holder.followBtn = (Button) vi.findViewById(R.id.MyContactsListFollowBtn);
holder.linearLayout = (LinearLayout) vi.findViewById(R.id.MyContactsthumbnail);
holder.profile_thumb_image = (ImageView) vi.findViewById(R.id.MyContactslist_image_profilephoto);
vi.setTag(holder);
}
else {
holder = (ViewHolder)vi.getTag();
}
song = data.get(position);
// Setting all values in listview
holder.listID.setText(song.get(MyContacts.KEY_ID));
holder.name.setText(song.get(MyContacts.KEY_NAME));
holder.mobile.setText(song.get(MyContacts.KEY_MOBILE));
if (song.get(MyContacts.KEY_USER_EXISTS).equals("1"))
{
if (song.get(MyContacts.KEY_THUMB_PROFILE_URL).equals("no")) {
} else {
profileImageLoader.DisplayImage(song.get(MyContacts.KEY_THUMB_PROFILE_URL), holder.profile_thumb_image);
}
}else {
holder.linearLayout.setVisibility(View.VISIBLE);
holder.followBtn.setVisibility(View.GONE);
}
return vi;
}
public static class ViewHolder {
public TextView textView ,listID ,name,mobile;
public ImageView whatsAppIcon ,telegramIcon;
public Button followBtn;
public LinearLayout linearLayout;
public ImageView profile_thumb_image;
}
}
Whatever action you do with any view of ListView like HIDE or VISIBLE in condition (if), you must have to set opposite HIDE or VISIBLE in opposite condition (else).
Try this solution just change code as per below:
if (song.get(MyContacts.KEY_USER_EXISTS).equals("1"))
{
holder.linearLayout.setVisibility(View.GONE);
holder.followBtn.setVisibility(View.VISIBLE);
if (song.get(MyContacts.KEY_THUMB_PROFILE_URL).equals("no")) {
} else {
profileImageLoader.DisplayImage(song.get(MyContacts.KEY_THUMB_PROFILE_URL), holder.profile_thumb_image);
}
}else {
holder.linearLayout.setVisibility(View.VISIBLE);
holder.followBtn.setVisibility(View.GONE);
}
Simple answer is, use floatingaction button. The position of the button will remain same, and you wouldn't feel annoyed
You view gets reused/recycled from system - so you have to (re)set profile_thumb_image every time in getView.
If not, there is a chance that you get a recycled view where the image was set in a previous call of getView.
First don't make this variable global
HashMap song;
Take this into ur getView() method if possible make it final.
As #coyer told
You view gets reused/recycled from system - so you have to (re)set profile_thumb_image every time in getView
Hope this help u...if any questions u can ask
Related
EDIT: I've solved this issue, if interested, please take a look at my answer to see how I did it!
I am currently working in Android Studio. I have a ListView that I populate with several items. Within each of these items is an ImageButton that has a "+" as the image. What I want to do is, whenever that image is clicked (not the entire ListView item, just the image), I want that image of "+" to become another image. Any help would be appreciated, as this has been an ongoing issue for a while!
Here is the current code that I attempt to use to achieve this:
final ImageButton movieSeen = (ImageButton convertView.findViewById(R.id.movieWatched);
movieSeen.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
movieSeen.setImageResource(R.drawable.ic_check_circle_black_24dp);
}
});
Currently this does update the image that I click correctly, BUT it also updates images that are not yet rendered on the screen, so when I scroll the list view down, other objects are also changed to ic_check_circle_black_24dp.
What I want is pretty straightforward, I just don't know how to achieve it. I just want to click an ImageButton, that's inside an item on a ListView, and have that ImageButton change its image resource.
Here is my custom array adapter as requested!
private class MovieScrollAdapter extends ArrayAdapter<Movie> {//custom array adapter
private Context context;
private List<Movie> movies;
public MovieScrollAdapter(Context context, List<Movie> movies){
super(context, -1, movies);
this.context = context;
this.movies = movies;
if(this.movies.isEmpty()){//if no results were returned after all processing, display a toast letting the user know
Toast.makeText(getApplicationContext(), R.string.no_matches, Toast.LENGTH_SHORT).show();
}
}
#Override
public View getView(final int position, View convertView, ViewGroup parent){
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.movie_layout, parent, false);
}
TextView title = (TextView) convertView.findViewById(R.id.title);
title.setText(movies.get(position).getTitle());
TextView plot = (TextView) convertView.findViewById(R.id.plot);
plot.setText(movies.get(position).getPlot());
TextView genre = (TextView) convertView.findViewById(R.id.genre);
genre.setText(movies.get(position).getGenre());
TextView metaScore = (TextView) convertView.findViewById(R.id.metascore);
if(movies.get(position).getMetaScore() == -1){//if the metaScore is set to -1, that means movie has not been rated, which by inference means it is not yet released
metaScore.setText(R.string.movie_not_released);
metaScore.setTextSize(TypedValue.COMPLEX_UNIT_SP, 9.5f);//smaller text so it fits without breaking anything
metaScore.setTextColor(getColor(R.color.colorAccent));
} else {
metaScore.setText(" " + Integer.valueOf(movies.get(position).getMetaScore()).toString() + " ");//using white space for minor formatting, instead of altering margins each time this is rendered
metaScore.setTextSize(TypedValue.COMPLEX_UNIT_SP, 25);
//setting up a "highlighted" background to achieve metacritic square effect
Spannable spanText = Spannable.Factory.getInstance().newSpannable(metaScore.getText());
spanText.setSpan(new BackgroundColorSpan(getColor(R.color.metaScore)), 3, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
metaScore.setText(spanText);
metaScore.setTextColor(getColor(android.R.color.primary_text_dark));
}
ImageView image = (ImageView) convertView.findViewById(R.id.imageView);
new ImageDownloadTask((ImageView)image).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, movies.get(position).getPosterURL());//because there are several images to load here, we let these threads run parallel
title.setOnClickListener(new View.OnClickListener() {//setting up a simple onClickListener that will open a link leading to more info about the movie in question!
#Override
public void onClick(View v) {
Uri uri = Uri.parse(movies.get(position).getMovieURL());
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
});
final ImageButton movieSeen = (ImageButton) convertView.findViewById(R.id.movieWatched);
movieSeen.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
movieSeen.setImageResource(R.drawable.ic_check_circle_black_24dp);
}
});
return convertView;
}
}
The problem is on a ListView, the views are being reused to save memory and avoid creating a lot of views, so when you change a view it keeps the state while it's being reused to show another item.
For example, you have 100 elements, you touch the first element ImageButton and that button is changed. Maybe on the screen there are 5 elements of the list showing, and you changed the first one. But if you scroll to the element number 15 the system is not creating 15 views, is taking the first one you clicked before and is changing the content.
So, you are expecting to have a view with a "+" ImageButton icon but you see another icon, that's because you must keep the view state inside a model object and set the state every time 'getView' is called.
Post your list adapter to see how is implemented.
UPDATE:
Now I see your adapter implementation I suggest you to add an int field inside Movie class to save the resource id you want to show on the ImageButton. Then inside the onClickListener you must set to this field the resource you want to show on the view when its clicked, and call notifyDataSetChanged(). After that you must do inside getView():
movieSeen.setImageResource(movies.get(position).getButtonImageResource());
Use RecyclerView and set the OnItemClickListener on your ImageButton within your view holder.
This already answered question should help.
The adapted code below is coming from this nice tutorial. Using ReciclerView with an adapter like this will solve your concern.
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private ArrayList<String> mDataset;
public class ViewHolder extends RecyclerView.ViewHolder {
public ImageView imageView;
public TextView txtHeader;
public ViewHolder(View v) {
super(v);
txtHeader = (TextView) v.findViewById(R.id.xxx);
imageView = (ImageView) v.findViewById(R.id.yyy);
}
}
public MyAdapter(ArrayList<String> myDataset) {
mDataset = myDataset;
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rowlayout, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final String name = mDataset.get(position);
holder.txtHeader.setText(mDataset.get(position));
holder.imageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Do here what you need to change the image content
}
});
holder.itemView.setBackground(....); // Initialize your image content here...
}
//...
}
Here is my suggestion to achieve what you want :
Create An Interface in your adapter :
public interface YourInterface{
void selectedImage(int position,ImageView iamgeView);
}
Create variable interface in your adapter that you just created :
private YourInterface yourInterface;
and make your adapter constructor like this :
public YourAdapterConstructor(YourInterface yourInterface){
this.yourInterface = yourInterface;
}
in your ImageView onClickListener :
final ImageButton movieSeen = (ImageButton) convertView.findViewById(R.id.movieWatched);
movieSeen.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
yourInterface.selectedImage(position, imageView);
}
});
and then finally in your class activity, Implements YourInterface and change you ImageView there :
#Override
public void selectedImage(final int position,final ImageView imageView) {
//change your image view here
}
I'd like to thank everyone for their support. Unfortunately, with the way my code is written (rather messily and without much regard for what my professors taught me), I was unable to get most of these solutions to work. I did however, find a solution that falls in line with my own framework that I've had going into this. Unfortunately I could not redo my entire adapter method, or implement various interfaces that would cause me to have to rewrite a huge chunk of code for something seemingly trivial.
So, if anyone finds themselves in this situation in the future, here is my solution:
In the Movie class, I add a boolean value that represents my values, along with some getters and setters:
private boolean watchedStatus;
public boolean hasSeen() {return watchedStatus;}
public void toggleWatchedStatus(){
watchedStatus = !watchedStatus;
}
In the getView method, I simply get a reference to the ImageButton, and then based on the boolean value returned by "hasSeen," I set the ImageResource to one of two states:
#Override
public View getView(final int position, View convertView, ViewGroup parent){
ImageButton movieSeen = (ImageButton) convertView.findViewById(R.id.movieSeen);
if(movies.get(position).hasSeen()){
movieSeen.setImageResource(R.drawable.ic_check_circle_black_24dp);
} else {
movieSeen.setImageResource(R.drawable.ic_add_circle_black_24dp);
}
}
Next, I override the OnClickListener, and make it so that whenever the button is clicked, the boolean value in the Movie.java class is toggled. The key here was using the ArrayAdapter's method "notifyDataSetChanged()" This completes the process, and lets the ListView know that it should update itself:
final ImageButton movieSeenForClick = (ImageButton) convertView.findViewById(R.id.movieSeen);
movieSeen.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//movieSeenForClick.setImageResource(R.drawable.ic_check_circle_black_24dp);
movies.get(position).toggleWatchedStatus();
System.out.println(movies.get(position).hasSeen() + " ------- position: " + position);
notifyDataSetChanged();
}
});
Thanks again for the time taken to provide information, a lot of it really did steer me int he right direction, I just had to use the information correctly with the way my code was structured.
Im trying to lock button after user click button on costume list.
the item of list fetched from hayoola and then i use viewholder to show data
to user in list.
if user click accept or refuse button. the result will be passed to hayoola and
the selected button will be disabled
Problem is after user click button wrong button getting disable. and after five click all remaining button getting disable too.
here is my adapter code :
static class myviewholder {
TextView textfromhayoola;
ImageButton buttonaccpet;
ImageButton buttonrefuse;
}
public View getView(int position, View convertView, ViewGroup parent) {
try {
final myviewholder viewHolder;
final int itemlocation = position;
if (convertView == null) {
convertView = inflater.inflate(R.layout.listforuser, null);
viewHolder = new myviewholder();
viewHolder.textfromhayoola = (TextView) convertView.findViewById(R.id.textfromhayoola);
viewHolder.buttonaccpet= (ImageButton) convertView.findViewById(R.id.buttonaccpet);
viewHolder.buttonrefuse= (ImageButton) convertView.findViewById(R.id.buttonrefuse);
convertView.setTag(viewHolder);
}else{
viewHolder = (myviewholder) convertView.getTag();
}
HashMap<String, String> myhayooladata= new HashMap<String, String>();
myhayooladata = data.get(position);
if (myhayooladata != null) {
viewHolder.textfromhayoola.setTag(myhayooladata.get("id_textfromhayoola"));
viewHolder.textfromhayoola.setText(myhayooladata.get("textfromhayoola"));
viewHolder.buttonaccpet.setTag(getItemId(position));
viewHolder.buttonrefuse.setTag(getItemId(position));
viewHolder.buttonaccpet.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
performOnBackgroundThread(new Runnable() {
public void run() {
passdatatohayoola(viewHolder.textfromhayoola.getTag().toString(),"accpet");
}
});
arg0.findViewWithTag(viewHolder.buttonaccpet.getTag()).setEnabled(false);
arg0.findViewWithTag(viewHolder.buttonrefuse.getTag()).setEnabled(false);
}
});
viewHolder.buttonrefuse.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
performOnBackgroundThread(new Runnable() {
public void run() {
passdatatohayoola(viewHolder.textfromhayoola.getTag().toString(),"refuse");
}
});
arg0.findViewWithTag(viewHolder.buttonaccpet.getTag()).setEnabled(false);
arg0.findViewWithTag(viewHolder.buttonrefuse.getTag()).setEnabled(false);
}
});
Hehe. Do you think that. Just "n/number of your records" view(s) will be created?
Assume that:
If you have 100 records and 10 rows will be draw.
And 10 rows won't re-draw.
Button accept of row 1 is disabled that mean Button accept of row 11 + n is the same. :D
May be that's your problem.
And Please read this:
Let I tell you something about ViewHolder pattern.
When you load data to ListView or GridView or something like these.
If your data has 1000 records, ... The ListView doesn't load 1000 records. It's just load "n records". "n" is number of record which compatible with your screen device.
Example: n = 10.
When you scroll down, The ListView will load more data. In this case, each row (view of row) will re-draw.
And with ListView which has large data, when use scroll up or down, you will see your app will be slow... because view is re-drawing.
And ViewHolder is the pattern which help you solve that problem.
When you use ViewHolder pattern, Just "n" (in this example n = 10) views will be created.
So, In your problem. I can tell you that:
May be you are implemented ViewHolder is incorrect.
OK. Let I tell you about the solution.
if (convertView == null) {
//You just findView and set for view
// viewHolder = new ViewHolder();
// viewHolder.yourBtn = convertView.findViewById(R.id.some_view_id);
// convertView.setTag(viewHolder);
} else {
//Right here, you will get viewHolder, because convertView is not null. It mean the viewHolder is existed.
}
And right here, It mean every time you will set data (You won't cache data, just cache VIEW)
Assume that Your data is an object and object has property which stand for status of button.
MyObject {
boolean objStatus;
}
and when you set data
viewHolder.yourBtn.setEnable(instanceOfMyObject.objStatus);
Im Writing An Application that reads XML file and Displays it as a ListView
cause each row has its own Image and Text i am using LayoutInflater, i can display the Texts but cant display Images! this is the code i use for ImageAdapter:
public class ImageAdaptertwo extends ArrayAdapter<String> {
private final Context context;
private final ArrayList<String> values;
private final ArrayList<String> values2;
public ImageAdaptertwo(Context context, ArrayList<String> values,ArrayList<String> values2) {
super(context, R.layout.trimester1_listview, values);
this.context = context;
this.values = values;
this.values2 = values2;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
String s = values.get(position);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.trimester1_main, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.label2);
ImageView imageView = (ImageView) rowView.findViewById(R.id.icon2);
textView.setText(values2.get(position));
// Change icon based on name
//String s = values.get(position);
System.out.println(s);
if (s.equals(" havingsuccessful-pregnancyS.png")) {
imageView.setImageResource(R.drawable.n1);
} else if (s.equals("urfoodguideduringpregnancyS.png")) {
imageView.setImageResource(R.drawable.n2);
} else if (s.equals("lovingurpregnantbodyS.png")) {
imageView.setImageResource(R.drawable.n3);
} else if (s.equals("gettinggoodbreastafterS.png")) {
imageView.setImageResource(R.drawable.n4);
} else if (s.equals("FoodGuidePyramidS.png")) {
imageView.setImageResource(R.drawable.n5);
} else if (s.equals("pregnancyS.png")) {
imageView.setImageResource(R.drawable.n6);
} else if (s.equals("nutritionfoS.png")) {
imageView.setImageResource(R.drawable.n7);
} else if (s.equals("Your-Growing-ChildS.png")) {
imageView.setImageResource(R.drawable.n8);
} else if (s.equals("Fatigue-in-first-trimesterS.png")) {
imageView.setImageResource(R.drawable.n9);
} else if (s.equals("T1S.png")) {
imageView.setImageResource(R.drawable.n10);
}
return rowView;
}
}
values and values2 are the ArrayList which are Coming from XML Parser! Actually no they are ok because i print the content of them and see them in LogCat!
in my Activit i use this for Adapting ImageAdapter
setListAdapter(new ImageAdaptertwo(this, imagelink,texts));
The result is a listview with texts but no Images!
can anybody tell me how i can fix this and display XML contents on ListView?
Solved the problem by changing if Statements to Switch Case . now for each row i have specific number
Well basically a problem in your if - else then. String comparisons are not happening as you expect. Make sure you check any code involving equals,equalsignorecase twice in JAVA. String comparisons are unnecessarily complicated. Also instead of if-else you can use switch and make your life just a little bit easier.
To get images from online you have to get the images on a background thread and then display on the main thread.
See this for help : http://android-developers.blogspot.in/2009/05/painless-threading.html
Similar question: unable to display url image (bitmap)
Solved the problem by changing if Statements to Switch Case . now for each row i have specific image
i want to build an application with a listview or whatever.. that looks very attractive and have some images and many more.But i cant find a good way to have that. I exactly want my application's UI like this images:
(source: coenraets.org)
(source: coenraets.org)
i want to display my app like this images please suggest me how can i do this? please if u know some tutorials then give the links.
Yes. Just place one ImageView and TextView in one xml layout. And, inflate this layout into one layout which is having the ListView And, do the process there for getting images from webservice or locally stored
Here i provide some example links that may very useful to you -
Lazy load of images in ListView
ListView with images
How to display a list of images in a ListView in Android?
You need to build the layout you want in a XML file, the same way you would do for an Activity. Then just inflate the XML layout for each row in your ListView and set its values and images.
Example of one ArrayAdapter that I've inflated with my own view (picture, text and checkbox):
private class FriendListAdapter extends ArrayAdapter<User> {
public FriendListAdapter(Activity a, int textViewResourceId, List<User> items) {
super(a, textViewResourceId, items);
}
public class ViewHolder{
public TextView username;
public ImageView image;
public CheckedTextView ctv;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder holder;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.invite_friend_row, null);
holder = new ViewHolder();
holder.username = (TextView) v.findViewById(R.id.username);
holder.username.setTypeface(tf);
holder.image = (ImageView) v.findViewById(R.id.image);
holder.ctv = (CheckedTextView) v.findViewById(R.id.checked);
v.setTag(holder);
}
else{
holder = (ViewHolder) v.getTag();
}
final User user = getItem(position);
if(user != null){
holder.username.setText(user.getName());
holder.ctv.setChecked(user.isChecked());
holder.image.setImageView(user.getImage());
}
return v;
}
}
You get the idea!
I'm having problems with some BaseAdapter code that I adapted from a book. I've been using variations of this code all over the place in my application, but only just realized when scrolling a long list the items in the ListView become jumbled and not all of the elements are displayed.
It's very hard to describe the exact behavior, but it's easy to see if you take a sorted list of 50 items and start scrolling up and down.
class ContactAdapter extends BaseAdapter {
ArrayList<Contact> mContacts;
public ContactAdapter(ArrayList<Contact> contacts) {
mContacts = contacts;
}
#Override
public int getCount() {
return mContacts.size();
}
#Override
public Object getItem(int position) {
return mContacts.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if(convertView == null){
LayoutInflater li = getLayoutInflater();
view = li.inflate(R.layout.groups_item, null);
TextView label = (TextView)view.findViewById(R.id.groups_item_title);
label.setText(mContacts.get(position).getName());
label = (TextView)view.findViewById(R.id.groups_item_subtitle);
label.setText(mContacts.get(position).getNumber());
}
else
{
view = convertView;
}
return view;
}
}
You are only putting data in the TextView widgets when they are first created. You need to move these four lines:
TextView label = (TextView)view.findViewById(R.id.groups_item_title);
label.setText(mContacts.get(position).getName());
label = (TextView)view.findViewById(R.id.groups_item_subtitle);
label.setText(mContacts.get(position).getNumber());
to be after the if/else block and before the method return, so you update the TextView widgets whether you are recycling the row or creating a fresh one.
To further clarify the answer of CommonsWare, here is some more info:
The li.inflate operation (needed here for parsing of the layout of a row from XML and creating the appropriate View object) is wrapped by an if (convertView == null) statement for efficiency, so the inflation of the same object will not happen again and again every time it pops into view.
HOWEVER, the other parts of the getView method are used to set other parameters and therefore should NOT be included within the if (convertView == null){ }... else{ } statement.
In many common implementation of this method, some textView label, ImageView or ImageButton elements need to be populated by values from the list[position], using findViewById and after that .setText or .setImageBitmap operations.
These operations must come after both creating a view from scratch by inflation and getting an existing view if not null (e.g. on a refresh).
Another good example where this solution is applied for a ListView ArrayAdapter appears in https://stackoverflow.com/a/3874639/978329