So I have a listview that has both text and images in it.
Everything about it works except when I am presented with the top row not having an image assigned to it.
rather than it using the placeholder image I have for rows that have no image assigned it takes the image of the current user.
The current user in this image is number 3, but his picture is also being shown for user 1.
here is my code for the CustomListAdapter, it grabs the PlayerItem which has players name and image url.
public class CustomListAdapter extends BaseAdapter {
private ArrayList<PlayerItem> listData;
private LayoutInflater layoutInflater;
public CustomListAdapter(Context context, ArrayList<PlayerItem> listData) {
this.listData = listData;
layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.rosterrow, null);
holder = new ViewHolder();
holder.playerNameView = (TextView) convertView.findViewById(R.id.title);
holder.imageView = (ImageView) convertView.findViewById(R.id.thumbImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
PlayerItem playerItem = (PlayerItem) listData.get(position);
holder.playerNameView.setText(playerItem.getplayerName());
if ((holder.imageView != null) && (playerItem.getUrl() != null)) {
Picasso.with(null).load(playerItem.getUrl()).into(holder.imageView);
}
return convertView;
}
static class ViewHolder {
TextView playerNameView;
ImageView imageView;
}
}
Fixed it by adding
else {
holder.imageView.setImageResource(R.drawable.list_placeholder);
}
Related
I am displaying a listview in which, the row item has two textview. The second textview is for the name of companies and the first textview is for the starting letter of the companies. How this can be achieved ? Need help !!
public class ExampleAdapter extends BaseAdapter {
Context context;
ArrayList<ExamplePojo> items = new ArrayList<>();
public ExampleAdapter(Context context, ArrayList<ExamplePojo> items) {
this.context = context;
this.items = items;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int position) {
return items.indexOf(items.get(position));
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null){
convertView = inflater.inflate(R.layout.example_row_item, null);
holder = new ViewHolder();
holder.txtSentence = (TextView) convertView.findViewById(R.id.txtSentence);
holder.txtInitialLetter = (TextView) convertView.findViewById(R.id.txtInitialLetter);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
final ExamplePojo pojo = items.get(position);
holder.txtSentence.setText(pojo.getSentence());
holder.txtInitialLetter.setText(pojo.getSentence().charAt(0));
return convertView;
}
public class ViewHolder{
TextView txtSentence, txtInitialLetter;
}
}
Here is code for showing first character in first textview and complete name in other textview.Also put below lines in if(convertView== null) block
final ExamplePojo pojo = items.get(position);
holder.txtSentence.setText(pojo.getSentence());
holder.txtInitialLetter.setText(pojo.getSentence().substring(0, 1));
i have a listview in which each list item contains an ImageView. Now in my adapter class i set a click listener on the ImageView which changes the image resource. I am using simple code and it works but i have unique problem that if i click on any image it changes but also the image of the subsequent 6th list item changes. this a very unique problem i am facing and i dont understand what is causing it.
My click listener in my adapter class:
public class CustomListAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<Movie> movieItems;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
public CustomListAdapter(Activity activity, List<Movie> movieItems) {
this.activity = activity;
this.movieItems = movieItems;
}
#Override
public int getCount() {
return movieItems.size();
}
#Override
public Object getItem(int location) {
return movieItems.get(location);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.list_item, null);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
NetworkImageView thumbNail = (NetworkImageView) convertView
.findViewById(R.id.thumbnail);
final ImageView favIcon = (ImageView) convertView.findViewById(R.id.favIcon);
TextView title = (TextView) convertView.findViewById(R.id.title);
TextView rating = (TextView) convertView.findViewById(R.id.rating);
TextView location = (TextView) convertView.findViewById(R.id.location);
// getting movie data for the row
Movie m = movieItems.get(position);
// thumbnail image
thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);
// title
title.setText(m.getTitle());
// rating
rating.setText("Rating: " + String.valueOf(m.getRating()));
// location
location.setText("Location:" + String.valueOf(m.getLocation()));
favIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((ImageView)v).setImageResource(R.drawable.batdroid);
}
});
return convertView;
}
}
I'm guessin' it's a recycle view issue . You should use the View Holder pattern , check this for a wider view.
Anyway you should try something like this :
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.your_layout, null);
holder = new ViewHolder();
holder.img= (ImageView) convertView.findViewById(R.id.img);
convertView.setTag(holder);
} else {
holder = convertView.getTag();
}
// set for each image in yourlist
holder.img.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
((ImageView) v).setImageResource(R.drawable.batdroid);
}
});
return convertView;
}
private static class ViewHolder {
public ImageView img;
}
I am adding multiple UI elements like SeekBar,ImageView,TextView dynamically to the ListView.But Whenever I try to get the reference to these elements,I am always getting reference to the last element only.
e.g I have multiple SeekBar.When i press play button that SeekBar should update.But the problem is when i press any number of play button only SeekBar at last position is getting updated.
I tried
seekbar.setTag(position);
But of no use.
Finally the solution is, I made my ViewHolder class's object local inside getView() method and assigned it to a global ViewHolder class's object on play button's OnClickListener.This change solved my problem like a miracle.
The tag you are setting should be instance of your ViewHolder class.
Your code can be like this -
public class YourTeamAdapter extends BaseAdapter {
private static Context context;
private ArrayList<TopDataModel> mList;
public YourTeamAdapter(Context c, ArrayList<TopDataModel> list) {
mList = list;
context = c;
}
#Override
public int getCount() {
return mList.size();
}
// get item at givin position
#Override
public TopDataModel getItem(int position) {
return mList.get(position);
}
// get itemID at givin position
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder = null;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.activity_team_status_list_item, null, true);
holder = new Holder(convertView);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
holder.tvName.setText(getItem(position).getName());
holder.tvRank.setText(getItem(position).getRank());
try {
if (getItem(position).getImage() != null &&
!getItem(position).getImage().equalsIgnoreCase("")) {
holder.imageView.setImageBitmap(SharedHelper.decodeBase64(getItem(position).getImage()));
}
} catch (Exception e) {
e.printStackTrace();
}
return convertView;
}
private static class Holder {
TextView tvName;
TextView tvRank;
CircularImageView imageView;
public Holder(View convertView) {
this.tvName = (TextView) convertView.findViewById(R.id.name);
this.tvRank = (TextView) convertView.findViewById(R.id.rank);
this.imageView = (CircularImageView) convertView.findViewById(R.id.image);
}
}
}
I am making a messaging android app, but my question is, how can I make the app choose either to pick the right hand layout or left hand layout? Like we see in messaging apps like WhatsApp, if I am the sender, my Message is wrapped in a right hand layout whilst the persons messages am chatting with are wrapped in a left handed layout, How can I achieve this type of Interface or layout I should say?
Below is my code, the app simple receives data from a remote database and puts it in a listview, using a custom adapter:
// the Data being set to the adapter
private ArrayList<ListItem> getListData() {
ArrayList<ListItem> listMockData = new ArrayList<ListItem>();
String[] username = mUsername.toArray(new String[mUsername.size()]);
String[] comments = Comment.toArray(new String[Comment.size()]);
for (int i = 0; i < username.length; i++) {
ListItem newsData = new ListItem();
newsData.setUsername(username[i]);
newsData.setmComment(comments[i]);
listMockData.add(newsData);
System.gc();
}
return listMockData;
}
And my custom adapter utilizing a single view:
public class CommentAdapter extends BaseAdapter{
private ArrayList<ListItem> listData;
private LayoutInflater layoutInflater;
ViewHolder holder;
public CommentAdapter(Context context, ArrayList<ListItem> listData) {
this.listData = listData;
notifyDataSetChanged();
layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.singlecomment, null);
holder = new ViewHolder();
holder.username = (TextView) convertView.findViewById(R.id.usernme);
holder.message = (TextView) convertView.findViewById(R.id.postCommentBox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
ListItem newsItem = listData.get(position);
holder.username.setText(newsItem.getUsername());
holder.message.setText(newsItem.getmComment());
return convertView;
}
static class ViewHolder {
TextView username;
TextView message;
}
}
Assuming that your ListItem object has a field named isSender to check whether he is the sender or not.
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.singlecomment, null);
holder = new ViewHolder();
holder.username = (TextView) convertView.findViewById(R.id.usernme);
holder.message = (TextView) convertView.findViewById(R.id.postCommentBox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
ListItem newsItem = listData.get(position);
if(newsItem.getIsSender()) {
holder.usernameRight.setText(newsItem.getUsername());
holder.messageRight.setText(newsItem.getmComment());
holder.usernameLeft.setVisibility(View.GONE); // or something like that to hide
holder.messageLeft.setText(View.GONE);
} else {
holder.usernameLeft.setText(newsItem.getUsername());
holder.messageLeft.setText(newsItem.getmComment());
holder.usernameRight.setVisibility(View.GONE);
holder.messageRight.setText(View.GONE);
}
return convertView;
}
I have a problem with my custom adapter. the method getView() is not called. I searched on my friends "google" and "stackoverflow" but anything fix my problem.
public class custom_adapter extends BaseAdapter {
private List<Activities> listData;
private LayoutInflater layoutInflater;
public custom_adapter(Context context,
List<Activities> listActivity) {
this.listData = listActivity;
layoutInflater = layoutInflater.from(context);
Log.v("BaseAdapter", "custom_adapter");
}
#Override
public int getCount() {
Log.v("BaseAdapter - getCount", String.valueOf(listData.size()));
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.v("BaseAdapter", "getView");
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.custom_adapter, null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.title);
holder.ratingBar = (RatingBar) convertView.findViewById(R.id.averageRatingBarActivitySearch);
holder.imageView = (ImageView) convertView.findViewById(R.id.thumbImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Activities newsItem = (Activities) listData.get(position);
holder.name.setText(newsItem.getName());
holder.ratingBar.setRating(newsItem.getAverageMark());
if (holder.imageView != null) {
new ImageDownloaderTask(holder.imageView).execute(newsItem.getPictureActivityString());
}
return convertView;
}
public static class ViewHolder {
TextView name;
RatingBar ratingBar;
ImageView imageView;
}
}
Furthermore, GetCount is not null !
I will be very glade if you can help me
Regards
K.L
For the purpose of handling List of some objects, extending generic ArrayAdapter may be better choice instead of just BaseAdapter. It will handle a lot of things for you. Your whole adapter class could look like.
public class ActivitiesAdapter extends ArrayAdapter<Activities>
{
private LayoutInflater layoutInflater;
public ActivitiesAdapter(Context context, List<Activities> objects)
{
super(context, 0, objects);
layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.v("BaseAdapter", "getView");
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.custom_adapter, null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.title);
holder.ratingBar = (RatingBar) convertView.findViewById(R.id.averageRatingBarActivitySearch);
holder.imageView = (ImageView) convertView.findViewById(R.id.thumbImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Activities newsItem = getItem(position);
holder.name.setText(newsItem.getName());
holder.ratingBar.setRating(newsItem.getAverageMark());
if (holder.imageView != null) {
new ImageDownloaderTask(holder.imageView).execute(newsItem.getPictureActivityString());
}
return convertView;
}
public static class ViewHolder {
TextView name;
RatingBar ratingBar;
ImageView imageView;
}
}
and of course you have to set this adapter to your ListView instance. Like
ActivitiesAdapter adapter = new ActivitiesAdapter(this, yourActivitiesList);
ListView listView = (ListView)findViewById(R.id.my_list_id);
listView.setAdapter(adapter);
or simply setListAdapter(adapter); if you are using ListActivity or ListFragment;
I had the same problem. Maybe, the problem is that you don't notify your adapter that you've changed data in the adapter. Try this code in your adapter:
#Override
public int getCount() {
return data.size();
}
And call notifyDataSetChanged(); when you change the data in Adapter.