I am loading images from drawable but it is not effective now i want to load images from web but i am stucked. I realy search for solutions but i cant success.
There is my Custom Adapter class:
int[] imageId = {R.drawable.first, R.drawable.second, R.drawable.third, R.drawable.fourth, R.drawable.fifth};
public Object instantiateItem(ViewGroup container, int position) {
global_position=position;
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
View viewItem = inflater.inflate(R.layout.image_item, container, false);
imageView = (ImageView) viewItem.findViewById(R.id.imageView);
imageView.setImageResource(imageId[position]);
((ViewPager)container).addView(viewItem);
return viewItem;
}
How can a turn this it can download images from web and load view pager.
You can use an AsyncTask to do that job without crashing your app.
class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView myImage //your image url;
public DownloadImageTask(ImageView myImage) {
this.myImage = myImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon;
}
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
}
}
To use this class just instanciate it like the others.
new DownloadImageTask((ImageView) findViewById(R.id.your_image_viewer))
.execute(imageURL);
Related
Okay, so far my MainActivity for this simple app looks like this:
public class MainActivity extends AppCompatActivity {
ListView moviesListView;
ArrayList <Movie> moviesList;
MoviesAdapter moviesAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
moviesListView = (ListView) findViewById(R.id.moviesListView);
moviesList = new ArrayList<Movie>();
runProgram();
moviesAdapter = new MoviesAdapter(getApplicationContext(), R.layout.movies_layout, moviesList);
moviesListView.setAdapter(moviesAdapter);
}
private void runProgram() {
String url = "https://api.themoviedb.org/3/" +
"discover/movie?primary_release_date.gte=2016-02-01&primary_release_date.lte=2016-02-18" +
"&api_key=...............................";
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
getMovies(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
}
});
// Access the RequestQueue through your singleton class.
MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);
}
private void getMovies(JSONObject response) {
JSONArray jsonArray = null;
String imageBaseURL = "http://image.tmdb.org/t/p/w500";
try {
jsonArray = response.getJSONArray("results");
for (int i = 0; i < 5; i++){
Movie movie = new Movie(jsonArray.getJSONObject(i).getString("title"),
jsonArray.getJSONObject(i).getString("overview"),
imageBaseURL + jsonArray.getJSONObject(i).getString("poster_path")
+ "?&api_key=6b54bd769063ac68b99fac57aa334eae");
moviesList.add(movie);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
What I am trying to do here is request movies from TMDB, and display them in a ListView. But my problem is that the first time you run the app, it doesn't display anything, you would only see white screen.
Now, if you try running it again, it would display the movies in the ListView. But if you clear the cache of the application and try running it one more time, you would see the white screen again... . I am really confused of what is going on here.
I've tried debugging it, and it seems like it is getting the data really fast, so whatever is happening is happening after that.
Also, here is the code of my Adapter in case:
public class MoviesAdapter extends ArrayAdapter<Movie> {
ArrayList<Movie> moviesList;
int adapterResource;
Context adapterContext;
LayoutInflater layoutInflator;
public MoviesAdapter(Context context, int resource, ArrayList<Movie> objects) {
super(context, resource, objects);
moviesList = objects;
adapterResource = resource;
adapterContext = context;
layoutInflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null){
convertView = layoutInflator.inflate(adapterResource, null);
viewHolder = new ViewHolder();
viewHolder.movieImage = (ImageView) convertView.findViewById(R.id.movieImage);
viewHolder.movieName = (TextView) convertView.findViewById(R.id.movieName);
viewHolder.movieOverview = (TextView) convertView.findViewById(R.id.movieOverview);
convertView.setTag(viewHolder);
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
new DownloadImageTask(viewHolder.movieImage).execute(moviesList.get(position).getImageURL());
viewHolder.movieName.setText(moviesList.get(position).getName());
viewHolder.movieOverview.setText(moviesList.get(position).getOverview());
return convertView;
}
public static class ViewHolder{
public ImageView movieImage;
public TextView movieName;
public TextView movieOverview;
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception ex) {
Log.e("Error", ex.getMessage());
ex.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}
Any help would be much appreciated.
Each time your getView() is called, you would start a new DownloadTask. That is simply wrong because the same image may already be downloaded/in the process of being downloaded
Use Universal Image loader or Picasso :
Instead of this :
new DownloadImageTask(viewHolder.movieImage).execute(moviesList.get(position).getImageURL());
Use :
Picasso.with(context)
.load(moviesList.get(position).getImageURL())
.into(viewHolder.movieImage);
Also, it seems that your getMovies() function is executed on main thread. Since you are parsing a JSON here, move it to background thread by using an AsyncTask
Thirdly, after you do getMovies(response);, you need to call notifyDataSetChange() on your moviesAdapter
I have a listView where I put a Title and a description with a picture and the pictures reloads when I scroll up, how could I resolve this problem? I tried some solutions but they failed...
Here is my code:
GETVIEW
public class ViewHolder extends ArrayAdapter<ListViewModel> {
public ViewHolder(Context context, List<ListViewModel> model) {
super(context, 0, model);
}
#Override
public View getView(int position, View cView, ViewGroup parent) {
if(cView == null){
cView = LayoutInflater.from(getContext()).inflate(R.layout.view_list_holder,parent, false);
}
ListViewHolder viewHold = (ListViewHolder) cView.getTag();
if(viewHold == null){
viewHold = new ListViewHolder();
viewHold.title = (TextView) cView.findViewById(R.id.title);
viewHold.content = (TextView) cView.findViewById(R.id.content);
viewHold.picture = (ImageView) cView.findViewById(R.id.picture);
cView.setTag(viewHold);
}
ListViewModel model = getItem(position);
viewHold.title.setText(model.getTitle());
viewHold.content.setText(model.getContent());
if (viewHold.picture != null)
new DownloadImageTask(viewHold.picture).execute(model.getPicture());
return cView;
}
private class ListViewHolder{
public TextView title;
public TextView content;
public ImageView picture;
}
}
ImageDownloader
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap myImage = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
myImage = BitmapFactory.decodeStream(in);
} catch (Exception e) {
e.printStackTrace();
}
return myImage;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
Try using Volley instead of AsyncTask:
http://developer.android.com/training/volley/request.html
It has built in support for image caching as well as cancelling requests if a particular set of images are no longer needed if the user has scrolled away.
Could you not just save the images in a bitmap array in the activity? Then just display those. Therefore they never reload, they are just in activity to be used in the view?
Im trying to make a lisView with two textView and an imageView (that come as a url Sting) on each item at the list but, the list is not scrolling as good as I want, because its taking too long to load the image url.
Im using an AsyncTask class for loading the the image but still it dosent look so good.
here is my code at int the ArrayAdapter class:
public class MySimpleArrayAdapter extends ArrayAdapter<Movie> {
final private Context context;
final private Movie[] movies;
ImageView movieIcon;
TextView name, description;
Bitmap bitmap;
public MySimpleArrayAdapter(Context context, Movie[] movies) {
super(context,R.layout.item_in_movielist, movies);
this.context = context;
this.movies = movies;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.item_in_movielist, parent, false);
name = (TextView) rowView.findViewById(R.id.tvMovieName);
description = (TextView) rowView.findViewById(R.id.tvMovieDescription);
movieIcon = (ImageView) rowView.findViewById(R.id.ivMovieIcon);
GetImageAsync getImageAsync = new GetImageAsync();
getImageAsync.imageView = movieIcon;
name.setText(movies[position].getMovieName());
description.setText(movies[position].getMovieDescription());
getImageAsync.execute(position);
return rowView;
}
public class GetImageAsync extends AsyncTask<Integer, Void, Bitmap> {
public ImageView imageView;
#Override
protected void onPostExecute(Bitmap bitmap1) {
imageView.setImageBitmap(bitmap1);
}
#Override
protected Bitmap doInBackground(Integer... params) {
URL url = null;
try {
url = new URL(movies[params[0]].getMovieImgURL());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
return BitmapFactory.decodeStream(input);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}
I understood that this is not the way to do that, I`m looking for changing my code into "Paging" and I want to do it right.
any tips what can I do ?
P.S
If you can show me how to add Paging to this code it will be great.
Thanks!
Picasso.with(mContext)
.load(img.get(pos).replaceAll(" ", "%20"))
.placeholder(R.drawable.ic_launcher)
.error(R.drawable.ic_launcher)
.noFade().resize(70, 70)
.into(v.image);
In my program i am using local images, but now i want to use online images instead of Drawable
But i don't know what are the changes i have to implement in my code, to get my target done for me.
here is my code, which i am using for drawable images, see:
public int[] IMAGE_IDS = {
R.drawable.flower_01, R.drawable.flower_02,
R.drawable.flower_01, R.drawable.flower_02,
R.drawable.flower_01, R.drawable.flower_02,
R.drawable.flower_01, R.drawable.flower_02
};
And Adapter class, complete code looks like this:
public class AddImageAdapter extends BaseAdapter
{
Context mycontext = null;
int galitembg = 0;
public int[] IMAGE_IDS = {
R.drawable.flower_01, R.drawable.flower_02,
R.drawable.flower_01, R.drawable.flower_02,
R.drawable.flower_01, R.drawable.flower_02,
R.drawable.flower_01, R.drawable.flower_02
};
public AddImageAdapter(Context c)
{
mycontext = c;
TypedArray typArray = mycontext.obtainStyledAttributes(R.styleable.GalleryTheme);
galitembg = typArray.getResourceId(R.styleable.GalleryTheme_android_galleryItemBackground, 0);
typArray.recycle();
}
#Override
public int getCount()
{
return IMAGE_IDS.length;
}
#Override
public Object getItem(int position)
{
return position;
}
#Override
public long getItemId(int position)
{
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
ImageView imageview = new ImageView(mycontext);
imageview.setImageResource(IMAGE_IDS[position]);
imageview.setScaleType(ImageView.ScaleType.FIT_XY);
return imageview;
}
}
I wanna use these two live images URLs in place of drawable
URL-1: http://files.vividscreen.com/soft/4f9891a78a355e9c4d15fc469eb98625/Sunflowers-480x800.jpg
URL-2: http://www.hdiphonewallpapers.us/phone-wallpapers/freewallpaper/12960425OV940-3Q61.jpg
new DownloadImageTask((ImageView) findViewById(R.id.imageView1))
.execute("http://java.sogeti.nl/JavaBlog/wp-content/uploads/2009/04/android_icon_256.png");
}
public void onClick(View v) {
startActivity(new Intent(this, IndexActivity.class));
finish();
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
You can download images from url using this method and set it in imageview. you just need the internet permission to download the images
You can use this library Picasso. This library download images from a url and disk cached also many more options.
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
How to use:
How to use Picasso
I am getting a big response from the server with data and image url. I need to display them on the List View. Images should be like thumbnails. To make it proper i have customized my Adapter and getting the images using Async Task. Here is my Adapter and Asynctask Code:
public class TalkofTownAdapter extends BaseAdapter{
private LayoutInflater inflater = null;
private Context context = null;
ImageView thumb_image = null;
private ProgressDialog progressbar = null;
ArrayList<String> items;
ArrayList<String> thumb_url;
public TalkofTownAdapter(Context c, ArrayList<String> list, ArrayList<String> thumb)
{
this.context = c;
this.items = list;
this.thumb_url = thumb;
progressbar = new ProgressDialog(c);
Log.d("Testing", "talk of town adapter constructor "+items.size());
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return items.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.talkoftown, null);
Log.d("Testing", "before creating holder object");
holder = new ViewHolder();
holder.headlineView = (TextView) convertView.findViewById(R.id.list_title);
holder.duration = (TextView)convertView.findViewById(R.id.duration);
holder.imageView = (ImageView) convertView.findViewById(R.id.list_image_playlist);
Log.d("Testing", "image view created :::::::: ");
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Log.d("Testing", "text::: "+items.get(position));
holder.headlineView.setText(items.get(position));
Log.d("Testing", "settting the text ");
holder.duration.setText("22/09/1987");
if (holder.imageView != null) {
Log.d("Testing", "getting the image "+thumb_url.get(position));
new ImageDownloaderTask(holder.imageView).execute(thumb_url.get(position));
}
return convertView;
}
static class ViewHolder {
TextView headlineView;
TextView duration;
ImageView imageView;
}
public static Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
Log.d("Testing", "image loaded "+myBitmap);
// myBitmap = Bitmap.createBitmap(100, 50, Config.ARGB_8888);
myBitmap = Bitmap.createScaledBitmap(myBitmap,(int)(myBitmap.getWidth()), (int)(myBitmap.getHeight()), true);
return myBitmap;
} catch (IOException e) {
Log.d("Testing", "exception is getting the image "+e.toString());
e.printStackTrace();
return null;
}
}
public void startProgress()
{
progressbar.setMessage("Please wait");
progressbar.show();
}
public void stopProgress()
{
progressbar.dismiss();
}
class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
public ImageDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
#Override
// Actual download method, run in the task thread
protected Bitmap doInBackground(String... params) {
// params comes from the execute() call: params[0] is the url.
return getBitmapFromURL(params[0]);
}
#Override
// Once the image is downloaded, associates it to the imageView
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if (imageView != null) {
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
imageView.setImageDrawable(imageView.getContext().getResources()
.getDrawable(R.drawable.rihanna));
}
}
}
}
}
Now the thumbnails are showing with the default image and then changing with downloaded images. But if i am scrolling down the list view, images are keep on changing and coming duplicates of those that appeared in the rows above that were already scrolled up. So i mean to say here, the images are coming on proper order for the corresponding rows. I know there are lots of tutorials and QA here also. But i have tried lots of solutions and it did not work properly.
Can any one help me on this?
The problem is with you if condition. Just remove the if condition if (holder.imageView != null) { the problem is each and everytime getView will check for your view is null or not and based on that it will execute and inflate the image.
Change your if condition like
if(thumb_url.get(position) !=null)
{
Log.d("Testing", "getting the image "+thumb_url.get(position));
new ImageDownloaderTask(holder.imageView).execute(thumb_url.get(position));
}