Sorry for my english. I am using adapter, and I may be wrong somthing using it. I am trying to show image and textView as output. Textview is coming properly in the output, but image is not. Please help me, i try many many times fix it. Load image in DownloadImageTask. In DownloadImageTask i have class ImageLoader, i have used this tutorial. I don't have any error, i have nothing(
ArrayList<News> ArrayListNews;
int Resourse;
Context context;
LayoutInflater vi;
public NewsAdapter(Context context, int resource, ArrayList<News> objects) {
super(context, resource, objects);
ArrayListNews = objects;
Resourse = resource;
this.context = context;
vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
convertView = vi.inflate(Resourse, null);
holder = new ViewHolder();
holder.imageview = (ImageView) convertView.findViewById(R.id.imagenews);
holder.nameNews = (TextView) convertView.findViewById(R.id.namenews);
holder.dayNews = (TextView) convertView.findViewById(R.id.daynews);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
new DownloadImageTask(holder.imageview).execute(ArrayListNews.get(position).getImageNews());
holder.nameNews.setText(ArrayListNews.get(position).getNameNews());
holder.dayNews.setText(ArrayListNews.get(position).getDayNews());
return convertView;
}
static class ViewHolder {
public ImageView imageview;
public TextView nameNews;
public TextView dayNews;
}
//this is class set image
private class DownloadImageTask extends AsyncTask<String, Void, String> {
ImageView bmImage;
ImageLoader imgLoader;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
#Override
protected String doInBackground(String... urls) {
String urldisplay = urls[0];
return urldisplay;
}
protected void onPostExecute(String result) {
imgLoader = new ImageLoader(context.getApplicationContext());
imgLoader.DisplayImage(result, bmImage);
}
}
I will suggest you to use Picasso library. It is very easy to use. Just add dependency(Android Studio) or add .jar file into your library(in Eclipse).
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
That's it. Now you will not need AsyncTask to download images.
Your getView() will be
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
convertView = vi.inflate(Resourse, null);
holder = new ViewHolder();
holder.imageview = (ImageView) convertView.findViewById(R.id.imagenews);
holder.nameNews = (TextView) convertView.findViewById(R.id.namenews);
holder.dayNews = (TextView) convertView.findViewById(R.id.daynews);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// I am not sure about return value of ArrayListNews.get(position).getImageNews();
// It should be URL pointing to your image file
Picasso.with(context).load(ArrayListNews.get(position).getImageNews()).into(holder.imageview);
holder.nameNews.setText(ArrayListNews.get(position).getNameNews());
holder.dayNews.setText(ArrayListNews.get(position).getDayNews());
return convertView;
}
Related
Dose anyone know why setImageResource cannot get image from my getImage method?
It gives me and error message saying setImageResource cannot be applied to (jave.lang.string).
I've tried changing movieImage value into a Int but it then gives me another list of errors. Should I stick to setImageResource or is that another way I can set the image in my listview from my array?
#NonNull
#Override
public View getView(int position ,View convertView, ViewGroup parent) {
setupImageLoader();
//get the movie information
String movieName = getItem(position).getTitle();
String movieDuration = getItem(position).getMovieLength();
String movieRating = getItem(position).getMovieRating();
String movieImage = getItem(position).getCoverArt();
//Create the movie object with the information
objectMovieListView objectMovieListView = new objectMovieListView(movieName, movieDuration, movieRating, movieImage);
//create the view result for showing the animation
final View result;
//ViewHolder object
ViewHolder holder;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(mResource, parent, false);
holder = new ViewHolder();
holder.movieName = (TextView) convertView.findViewById(R.id.textViewMovieName);
holder.movieDuration = (TextView) convertView.findViewById(R.id.textViewMovieDuration);
holder.movieRating = (TextView) convertView.findViewById(R.id.textViewMovieRating);
holder.movieImage = (ImageButton) convertView.findViewById(R.id.movieListImageButton);
result = convertView;
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
result = convertView;
}
ImageLoader imageLoader = ImageLoader.getInstance();
int defaultImage = mContext.getResources().getIdentifier("#drawable/icons8_image_moviepicture", null,mContext.getPackageName());
DisplayImageOptions options = new DisplayImageOptions.Builder().cacheInMemory(true)
.cacheOnDisc(true).resetViewBeforeLoading(true)
.showImageForEmptyUri(defaultImage)
.showImageOnFail(defaultImage)
.showImageOnLoading(defaultImage).build();
imageLoader.displayImage(movieImage, holder.movieImage, options);
holder.movieName.setText(objectMovieListView.getMovieName());
holder.movieDuration.setText(objectMovieListView.getMovieDuration());
holder.movieRating.setText(objectMovieListView.getMovieRating());
//holder.movieImage.setImageResource(R.drawable.avengers_infinity_war_poster);
holder.movieImage.setImageResource(objectMovieListView.getMovieImage());
return convertView;
}
Here's the Class where I store all my get and set methods
public class objectMovieListView {
private String movieImage;
public objectMovieListView(String movieImage) {
this.movieImage = movieImage;
public String getMovieImage() {
return movieImage;
}
public void setMovieImage(String movieImage) {
this.movieImage = movieImage;
}
}
I have ListView with Adapter, and also use holder. but later I read about recyclerView.ViewHolder and now confused, Is it different with the one I've been using right now? I mean for the optimization purpose, I want to know if using holder only is not good enough without using recyclerView.
public class NewsAdapter extends ArrayAdapter<News> {
Context context;
List<News> myList;
public NewsAdapter(Context context, int resource, List<News> objects) {
super(context, resource, objects);
this.context = context;
this.myList = objects;
}
#Override
public News getItem(int position) {
if(myList != null)
return myList.get(position);
return null;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if (convertView == null){
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_news, null);
holder = new NewsAdapter.Holder();
holder.title = (TextView)convertView.findViewById(R.id.textViewTitle);
holder.datePosted = (TextView)convertView.findViewById(R.id.textViewDate);
holder.imageView = (ImageView)convertView.findViewById(R.id.imageViewThumbnailpic);
convertView.setTag(holder);
}else{
holder = (Holder)convertView.getTag();
}
News news = getItem(position);
holder.title.setText(news.getTitle());
holder.datePosted.setText(news.getDatePost());
Picasso.with(context)
.load(news.getImgUrl())
.placeholder(R.drawable.coin25)
.error(R.drawable.hnbspic)
.into(holder.imageView);
return convertView;
}
private class Holder{
ImageView imageView;
TextView title;
TextView datePosted;
}
}
It's better to use Recyclerview because it has been optimized for various scenarios and not just for View holder pattern like it give the option for determining how your item should be laid out or like what should be the animation or custom drawing in each item.You can read more this medium post
I am trying to create a custom adapter for a shop element in my Android app but every time I scroll down the list the images seem to change their position, I have had a look around on here already but suggestions that I have found and tried have been to no avail.
Each item has a title, an image (being loading via an AsyncTask or retrieved from the LRUCache) and a price of the item below is the code I use to generate the adapter.
public class ShopAdapter extends BaseAdapter {
public Context context;
public ArrayList<ShopItem> shopItemList;
public ImageCache imageCache;
String imageToLoad;
Bitmap shopImage;
public ShopAdapter(Context context, ArrayList<ShopItem> shopItemList) {
this.context = context;
this.shopItemList = shopItemList;
imageCache = new ImageCache(this.context);
}
#Override
public int getCount() {
return shopItemList.size();
}
#Override
public Object getItem(int position) {
return shopItemList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null){
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.shop_list, null);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.textView3);
holder.image =(ImageView) convertView.findViewById(R.id.imageView);
holder.price = (TextView) convertView.findViewById(R.id.textView4);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.title.setText(shopItemList.get(position).getTitle());
shopImage = imageCache.getBitmapFromMemoryCache(shopItemList.get(position).getImage());
if(shopImage != null) {
holder.image.setImageBitmap(shopImage);
} else {
new LoadImage(context, holder.image).execute(imageToLoad);
}
holder.price.setText(shopItemList.get(position).getPrice());
return convertView;
}
static class ViewHolder {
TextView title;
ImageView image;
TextView price;
}
}
Any help would be very much appreciated!
I have a custom adapter class for a listview and I want to be able to access the content of a specific row by clicking a button on it. I tried to create a ViewHolder, but I get a NPE error when I try to click it.
static class ViewHolder {
TextView camera;
TextView players;
TextView max_players;
ImageView privata;
Button Buton;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
String variabile[] = getItem(position).split("\\s+");
LayoutInflater linflater = LayoutInflater.from(getContext());
View customView = linflater.inflate(R.layout.custom_row, parent, false);
final ViewHolder holder = new ViewHolder();
holder.camera = (TextView) customView.findViewById(R.id.Nume);
holder.players = (TextView) customView.findViewById(R.id.players);
holder.max_players = (TextView) customView.findViewById(R.id.max_players);
holder.privata = (ImageView) customView.findViewById(R.id.privata);
holder.Buton = (Button) customView.findViewById(R.id.Buton);
holder.camera.setText(variabile[0]);
if (!variabile[1].equals("true")) {
parola = false;
holder.privata.setVisibility(View.INVISIBLE);
}
holder.players.setText(variabile[2]);
holder.max_players.setText(variabile[3]);
room_id = variabile[4];
nume = variabile[5];
holder.Buton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
hash = new HashMap<String, String>();
hash.put("name", nume);
hash.put("room", room_id);
if (intra) {
holder.Buton.setText("Iesi");
site = siteul + "/join";
intra = false;
} else {
holder.Buton.setText("Intra");
site = siteul + "/leave";
intra = true;
}
new ATask().execute(site);
}
});
return customView;
}
When using the ViewHolder pattern, you should check if the convertView in null or has been created before, in the getView method, and after that use setTag and getTag methods. like this :
if (convertView == null)
{
LayoutInflater linflater = LayoutInflater.from(getContext());
convertView = linflater.inflate(R.layout.your_list_item_view, parent, false);
viewHolder.textView = (TextView)convertView.findViewById([the id]);
.
.
.
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
You need to check if the convertView is null so it is already has been visited or not then store the holder in tag Like
ViewHolder holder;
if (convertView == null) {
LayoutInflater linflater = LayoutInflater.from(getContext());
holder = linflater.inflate(R.layout.custom_row, parent, false);....
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}//Common code
I have an android app where i want to display some messages.The messages are classified into two categories, images and text.Text messages have two types,sent and received.I have created a custom listview adapter to display the messages in a listview.When calling the adapter,i pass an arraylist of 13 objects.Problem is not all the messages in arraylist are displayed.Only the first five messages are displayed.The messages are displayed three times each.When a message item in the listview is clicked,more than one message is highlited.What could be the problem.
Here is the listview adapter:
public class CustomMessageListAdapter extends BaseAdapter {
private ArrayList<?> listData;
private LayoutInflater layoutInflater;
public CustomMessageListAdapter(Context context, ArrayList<?> 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;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.listview_message,
null);
viewHolder = new ViewHolder();
viewHolder.incoming_message = (RelativeLayout) convertView
.findViewById(R.id.received_layout);
viewHolder.outgoing_message = (RelativeLayout) convertView
.findViewById(R.id.sent_layout);
viewHolder.sent_message = (TextView) convertView
.findViewById(R.id.sent_messages_textView_message);
viewHolder.sent_time = (TextView) convertView
.findViewById(R.id.sent_messages_textview_time);
viewHolder.sent_image = (ImageView) convertView
.findViewById(R.id.sent_image_imageview);
viewHolder.received_image = (ImageView) convertView
.findViewById(R.id.received_image_imageview);
viewHolder.sent_image_layout = (RelativeLayout) convertView
.findViewById(R.id.sent_image_layout);
viewHolder.received_image_layout = (RelativeLayout) convertView
.findViewById(R.id.received_image_layout);
viewHolder.received_message = (TextView) convertView
.findViewById(R.id.messages_textView_message);
viewHolder.received_time = (TextView) convertView
.findViewById(R.id.messages_textview_time);
viewHolder.date = (TextView) convertView
.findViewById(R.id.messages_textView_date);
viewHolder.sent_hepasnap = (RelativeLayout) convertView
.findViewById(R.id.chat_layout_sent_hepasnap);
viewHolder.recieved_hepasnap = (RelativeLayout) convertView
.findViewById(R.id.chat_layout_received_hepasnap);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
MessageItem messageItem = (MessageItem) listData.get(position);
Log.i("msg", "" + position);
if (messageItem.getCategory().equalsIgnoreCase("text")) {
if (messageItem.getType().equalsIgnoreCase("sent")) {
viewHolder.outgoing_message.setVisibility(View.VISIBLE);
viewHolder.sent_message.setText(messageItem.getMessage());
viewHolder.sent_time.setText(messageItem.getTime());
} else {
viewHolder.incoming_message.setVisibility(View.VISIBLE);
viewHolder.received_message.setText(messageItem.getMessage());
viewHolder.received_time.setText(messageItem.getTime());
}
}
return convertView;
}
public class ViewHolder {
TextView sent_message;
TextView sent_time;
TextView received_message;
TextView received_time;
RelativeLayout outgoing_message;
RelativeLayout incoming_message;
RelativeLayout sent_hepasnap;
RelativeLayout recieved_hepasnap;
TextView date;
ImageView sent_image;
ImageView received_image;
RelativeLayout sent_image_layout;
RelativeLayout received_image_layout;
}
}
And when message is clicked:
add viewHolder.incoming_message.setVisibility(View.GONE); to if condition
(messageItem.getType().equalsIgnoreCase("sent"))
and viewHolder.outgoing_message.setVisibility(View.GONE); to else condition.
If your Problem not solved then let me know.
I think the messages are getting displayed multiple times because they carry older values whenever convert view is non-null.
And since your incoming and outgoing messages are both getting filled it is giving the illusion of multiple items getting selected.
So you should change visibility of unused views to View.GONE.