I want that this 200 Pictures are in every row of the ListView.
Where I have to copy this code which collect the pictures from the internet in my CustomAdapter?
for(int i = 1; i <= 200; i++){
final int ii = i;
final ImageView imageView = new ImageView(CustomListView.this);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
//linearLayout.addView(imageView,lp);
Thread thread = new Thread(){
#Override
public void run(){
final Bitmap bm = getBitmapFromURL("http://ruthe.de/cartoons/strip_"+getPictureName(ii)+".jpg");
runOnUiThread(new Runnable() {
#Override
public void run() {
if(bm !=null){
imageView.setImageBitmap(bm);
}
else {
//linearLayout.removeView(imageView);
}
}
});
}
};thread.start ();
}
This is my CustomAdapter:
public class CustomAdapter extends BaseAdapter implements View.OnClickListener {
/*********** Declare Used Variables *********/
private Activity activity;
private ArrayList data;
private static LayoutInflater inflater=null;
public Resources res;
ListModel tempValues=null;
int i=0;
/************* CustomAdapter Constructor *****************/
public CustomAdapter(Activity a, ArrayList d,Resources resLocal) {
/********** Take passed values **********/
activity = a;
data=d;
res = resLocal;
/*********** Layout inflator to call external xml layout () ***********/
inflater = ( LayoutInflater )activity.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/******** What is the size of Passed Arraylist Size ************/
public int getCount() {
if(data.size()<=0)
return 1;
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
/********* Create a holder Class to contain inflated xml file elements *********/
public static class ViewHolder{
public TextView text;
public TextView text1;
public TextView textWide;
public ImageView image;
}
/****** Depends upon data size called for each row , Create each ListView row *****/
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
ViewHolder holder;
if(convertView==null){
/****** Inflate tabitem.xml file for each row ( Defined below ) *******/
vi = inflater.inflate(R.layout.tabitem, null);
/****** View Holder Object to contain tabitem.xml file elements ******/
holder = new ViewHolder();
holder.text = (TextView) vi.findViewById(R.id.text);
holder.text1=(TextView)vi.findViewById(R.id.text1);
holder.image=(ImageView)vi.findViewById(R.id.image);
/************ Set holder with LayoutInflater ************/
vi.setTag( holder );
}
else
holder=(ViewHolder)vi.getTag();
if(data.size()<=0)
{
holder.text.setText("No Data");
}
else
{
/***** Get each Model object from Arraylist ********/
tempValues=null;
tempValues = ( ListModel ) data.get(position);
/************ Set Model values in Holder elements ***********/
holder.text.setText(tempValues.getCompanyName());
holder.text1.setText( tempValues.getUrl() );
holder.image.setImageResource(
res.getIdentifier(
"com.androidexample.customlistview:drawable/"+tempValues.getImage(),null,null));
/******** Set Item Click Listner for LayoutInflater for each row *******/
vi.setOnClickListener(new OnItemClickListener( position ));
}
return vi;
}
#Override
public void onClick(View v) {
Log.v("CustomAdapter", "=====Row button clicked=====");
}
/********* Called when Item click in ListView ************/
private class OnItemClickListener implements View.OnClickListener{
private int mPosition;
OnItemClickListener(int position){
mPosition = position;
}
#Override
public void onClick(View arg0) {
CustomListView sct = (CustomListView)activity;
/**** Call onItemClick Method inside CustomListViewAndroidExample Class ( See Below )****/
sct.onItemClick(mPosition);
}
}
//My own code
public static Bitmap getBitmapFromURL(String src) {
try {URL url = new URL(src);
return BitmapFactory.decodeStream(url.openConnection().getInputStream());
}
catch(Exception e){
e.printStackTrace();
}
return null;
} //PICTURE BITMAP
public String getPictureName (int i){
String in = ""+i+"";
if(in.length() == 1){
return "000"+in;
}
else if(in.length() == 2){
return "00"+in;
}
else if(in.length() == 3){
return "0"+in;
}
else{
return in;
}
}
I searched on the whole internet but I dont found something which explains how to get pictures from the Internet into every row of a ListView...
PICASsO allows for hassle-free image loading in your application—often in one line of code!
for the library check this link http://square.github.io/picasso/
and at the bottom of page you can download jar file and just paste it in the libs folder
Picasso.with(context).load("YOUR IMAGE URL").into(imageView);
int your getView method
do it like
holder.image=(ImageView)vi.findViewById(R.id.image);
and then
Picasso.with(context).load("YOUR IMAGE URL").into(holder.image);
Take a look at the Picasso library. It makes it extremely easy.
http://square.github.io/picasso/
To use it, simply find your ImageView with the standard findViewById, then use the following code:
Picasso.with(context).load("www.google.com/images/1").into(imageView);
Simply input the URL and the ImageView, and Picasso will async load the image and put it in the imageview.
Im currently using it to show a list of over 400 images in a listview, works perfectly.
Except for the thread you can use the bitmap object inside the adapter itself and initialize the image view with the bitmap object, using position integer instead of (ii).
Hi i have found a workaround for my app: i have create a class type:
public class myClass {
....
...
private Bitmap imguser;
.. and into costructor i have added objects for async task like Future and i send image name
received from server side....
public myClass(..., ..,..,String userid, ...){
Future<Bitmap> futureimguser;
ExecutorService executor = Executors.newCachedThreadPool();
getImgFromSite getimguserfromsite = new getImgFromSite(userid,"imguser");
futureico = executor.submit(geticofromsite);
futureimguser = executor.submit(getimguserfromsite)
.......
this.imguser = futureimguser.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
this.icopoi = futureico.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
executor.shutdown();
next i have a method like below which loads images from my site.
private final class getImgFromSite implements Callable<Bitmap> {
String imgsrc = new String();
String imgtipo = new String();
public getImgFromSite(String srcimg,String imgtipo) {
this.imgsrc = srcimg;
this.imgtipo = imgtipo;
}
#Override
public Bitmap call() throws Exception {
String imgpath;
if(imgtipo.compareTo("imguser") == 0){
imgpath = "http://mysite/assets/imgcomics/"+imgsrc+".jpg";
}
else{
imgpath = "http://mysite/"+imgsrc;
}
Bitmap myBitmap;
URL url = new URL(imgpath);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
myBitmap= BitmapFactory.decodeStream(input);
return myBitmap;
}
}
Hope that i have help you!
Related
This is my code:
public class GetAllCategoriesListViewAdapter extends BaseAdapter{
private JSONArray dataArray;
private Activity activity;
private static final String baseUrlForCategoryImage = "link here";
private static LayoutInflater inflater = null;
public GetAllCategoriesListViewAdapter(JSONArray jsonArray, Activity a){
this.dataArray = jsonArray;
this.activity = a;
inflater = (LayoutInflater) this.activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return this.dataArray.length();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ListCell cell;
if(convertView == null){
convertView = inflater.inflate(R.layout.get_all_categories_list_view_cell, null);
cell = new ListCell();
cell.category_name = (TextView) convertView.findViewById(R.id.category_name);
cell.category_image = (ImageView) convertView.findViewById(R.id.category_image);
cell.category_image.setTag(cell);
convertView.setTag(cell);
}else{
cell = (ListCell) convertView.getTag();
}
try{
JSONObject jsonObject = this.dataArray.getJSONObject(position);
cell.category_name.setText(jsonObject.getString("category_name"));
String nameOfImage = jsonObject.getString("category_image");
String urlForImageInServer = baseUrlForCategoryImage + nameOfImage;
new AsyncTask<String, Void, Bitmap>(){
protected Bitmap doInBackground(String... params){
String url = params[0];
Bitmap icon = null;
try{
InputStream in = new java.net.URL(url).openStream();
icon = BitmapFactory.decodeStream(in);
}catch (MalformedURLException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
return icon;
}
#Override
protected void onPostExecute(Bitmap result) {
cell.category_image.setImageBitmap(result);
}
}.execute(urlForImageInServer);
}catch (JSONException e){
e.printStackTrace();
}
return convertView;
}
private class ListCell{
private ImageView category_image;
private TextView category_name;
}
}
The code gets the images from my webhost and place it in every cell in my listvew. The problem is everytime I scroll, the images are shuffled and returns in few seconds. How to stop the images from changing when I scroll? I tried to use the solution on other post but it won't work. Please help.
Looks like you are new to android. So you are fetching the images in the getView method. The getView method is called every time a new list item is drawn. So For every image, a new request is made to internet. SO that will be a lot of requests . You should firstly get your images and get them in some ArryayList . Then pass that Arraylist to your adapter. Here is tutorial for you
Using AsyncTask
http://www.devexchanges.info/2015/04/android-custom-listview-with-image-and.html
Using Volley
https://www.androidhive.info/2014/07/android-custom-listview-with-image-and-text-using-volley/
Go for Volley for better performance. Cheers!
I have pictures from my online database in my GridView and I want it in reverse order.
So I want when I add a new picture to my database to be the first in the GridView.
I tried to find an answer but there is nothing about it at stackoverflow.
This is my ListViewAdapter:
public class GetMovieImagesListViewAdapter extends BaseAdapter {
private JSONArray dataArray;
private Activity activity;
private static final String baseUrlForImage = "http://google.com";
private static LayoutInflater inflater = null;
public GetMovieImagesListViewAdapter(JSONArray jsonArray, Activity a){
this.dataArray = jsonArray;
this.activity = a;
inflater = (LayoutInflater) this.activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return this.dataArray.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) {
final ListCell cell;
if (convertView == null) {
convertView = inflater.inflate(R.layout.get_images_from_movies_list_cell, null);
cell = new ListCell();
cell.MovieImages = (ImageView) convertView.findViewById(R.id.movie_images_id);
convertView.setTag(cell);
} else {
cell = (ListCell) convertView.getTag();
}
try {
JSONObject jsonObject = this.dataArray.getJSONObject(position);
String nameOfImage = jsonObject.getString("image");
String urlForImageInServer = baseUrlForImage + nameOfImage;
new AsyncTask<String, Void, Bitmap>(){
#Override
protected Bitmap doInBackground(String... params)
{
String url = params[0];
Bitmap icon = null;
try
{
InputStream in = new URL(url).openStream();
icon = BitmapFactory.decodeStream(in);
} catch (IOException e) {
e.printStackTrace();
}
return icon;
}
#Override
protected void onPostExecute(Bitmap result)
{
cell.MovieImages.setImageBitmap(result);
}
}.execute(urlForImageInServer);
} catch (JSONException e) {
e.printStackTrace();
}
return convertView;
}
private class ListCell{
private ImageView MovieImages;
}}
You could fetch each JSONObject by starting from the end of the array and working backwards to the start:
JSONObject jsonObject = this.dataArray.getJSONObject(getCount() - position - 1);
The result that you have received try to iterate through it in the reverse order.
Your Bitmap result data seems to be a single data that you get. I am expecting an array, or arraylist of data that you get in onPostExecute() method parameter while you query your online database.
Say for example, if you get the data in the form of onPostExecute(ArrayList result), then you can simply iterate the 'result' data in reverse order in order to populate your grid view in reverse order.
Check out Iterate arraylist in reverse order
In one of my app, I need to use AsyncTask. I need to get an image URL from an HTTP site. I have done this in the doInBackground method. I am getting the URL of that image as a string.
publishProgress(thumb);//thumb is string
then in
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
sample = new ArrayList<String>();
System.out.println("this is on progress..."+values[0]);
sample.add(values[0]);
GridviewAdapter_old go=new GridviewAdapter_old(getActivity(), sample);
gv.setAdapter(go);
// gv.setAdapter(ga);
}
public class GridviewAdapter_old extends BaseAdapter
{
private ArrayList<String> listCountry;
private Activity activity;
public GridviewAdapter_old(Activity activity, ArrayList<String> listCountry) {
super();
// this.listCountry = listCountry;
this.listCountry = new ArrayList<String>();
this.listCountry = listCountry;
// this.listFlag = listFlag;
this.activity = activity;
System.out.println("this is contry name " + this.listCountry);
// System.out.println("this is img name " + this.listFlag);
// System.out.println();
}
#Override
public int getCount() {
// TODO Auto-generated method stub
System.out.println("len " + listCountry.size());
// return listCountry.size();
return listCountry.size();
}
#Override
public String getItem(int position) {
// TODO Auto-generated method stub
return listCountry.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
public static class ViewHolder {
public ImageView imgViewFlag;
// public TextView txtViewTitle;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder view;
LayoutInflater inflator = activity.getLayoutInflater();
if (convertView == null) {
view = new ViewHolder();
convertView = inflator.inflate(R.layout.test, null);
view.imgViewFlag = (ImageView) convertView
.findViewById(R.id.grid_item_image);
// view.imgViewFlag.setBackgroundResource(R.drawable.view_default);
convertView.setTag(view);
}
else {
view = (ViewHolder) convertView.getTag();
}
try {
URL myUrl = new URL(listCountry.get(0));
InputStream inputStream = (InputStream) myUrl.getContent();
Drawable drawable = Drawable.createFromStream(inputStream, null);
view.imgViewFlag.setImageDrawable(drawable);
} catch (Exception e) {
System.out.println(e.getMessage());
}
/*
* Bitmap imageBitmap = null; //System.gc(); try { URL imageURL = new
* URL(listCountry.get(0));
* System.out.println("this is in last portion..."
* +listCountry.get(position)); imageBitmap =
* BitmapFactory.decodeStream(imageURL.openStream());
* view.imgViewFlag.setImageBitmap(imageBitmap); //
* view.txtViewTitle.setText(listCountry.get(position)); //
* view.imgViewFlag.setImageResource(listFlag.get(position));
*
* } catch (Exception e) { System.out.println("this is error " +
* e.getMessage()); }
*/
return convertView;
}
}
The problem is:
I am not getting an image from the URL (that is getting from thumb (publishProgress(thumb);)
I am not getting the multiple images.
you are only getting one in your list because every time you call onProgressUpdate you create a new list.
You dont want to use onProgressUpdate to populate your list, that would be an insane amount of overhead. Instead you want to create your list inside your doInBackground then pass that list to your onPostExecute then put the new list to the adapter and call notifyDatasetChanged on the adapter to refresh the list.
in short, create the adapter (class wide variable), create an ArrayList (class wide variable) and everytime a change is made the the list all you have to do is call notifyDatasetCHanged on the adapter
ArrayList<String> list = new ArrayList<String();
ArrayAdapter adapter;
public class AsyncTask.....
#Override
protected Void doInBackground(Void... params){
...
list.add(stuff);
}
#Override
protected Void onPostExecute(Void params){
adapter.notifyDatasetChanged();
}
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));
}
I have coded to display few images in gridview. The images are getting displayed from urls.
The problem i am facing is that the images get replaced when i scroll.. and the order of images keeps on changing once started.. this leads to delay in display of full image if i click on any image in grid..
Please help !
code :
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private TextView txtUrl;
private String response;
public ImageView imageView;
public static String[] mThumbIds;
public ImageAdapter(Context c,String resp) {
mContext = c;
response = resp.trim();
mThumbIds = resp.split(",");
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) { // if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(95, 95));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(6, 6, 6, 6);
} else {
imageView = (ImageView) convertView;
}
try {
new LoadImageGrid(imageView).execute(mThumbIds[position]);
} catch(Exception e) {
txtUrl.setText("Error: Exception");
}
return imageView;
}
class LoadImageGrid extends AsyncTask<String, Void, Drawable>
{
ImageView imageView;
public LoadImageGrid(ImageView im){
imageView = im;
}
#Override
protected Drawable doInBackground(String... args) {
String url = args[0];
Drawable d = null;
try {
d = Drawable.createFromStream((InputStream) new URL(url).getContent(), "src");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return d;
}
#Override
protected void onPostExecute(Drawable d) {
imageView.setImageDrawable(d);
}
When you scroll your grid view, image views that are not visible returns to getView() as convertView parameter. But your asyncTask doesn't stop, and call
imageView.setImageDrawable(d);
leads to applying downloaded image to the view on wrong position. Because now you reuse the same imageView. Quick fix is not to use convertView. But it'll slow down your app a bit.
This seems to be related to convert view. When you reuse the space for an image using convert view then you should use the Imageview within that scope. I would suggest to find the imageview by its id within your current class code and then popultae it.