I 'm having a problem with my gallery, it's to slow and it lags. I 'm loading images from server with Image Adapter:
package com.example.ocenitaksi;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import org.apache.http.client.utils.URLEncodedUtils;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class ImageAdapter extends BaseAdapter {
private Context context;
private final String[] mobileValues;
public ImageAdapter(Context context, String[] mobileValues) {
this.context = context;
this.mobileValues = mobileValues;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) {
gridView = new View(context);
// get layout from mobile.xml
gridView = inflater.inflate(R.layout.mobile, null);
// set image based on selected text
ImageView imageView = (ImageView) gridView
.findViewById(R.id.grid_item_image);
// ubacivanje slika za string
String mobile = mobileValues[position];
if (mobile.equals(MainActivity.imena[position])) {
//imageView.setImageURI("http://24.media.tumblr.com/avatar_a400b4dbb80e_64.png");
Bitmap bitmap=null;;
mobile = mobile.replace(" ", "_");
bitmap = DownloadImage("http://android.yunews.net/images/"+mobile+".png");
imageView.setImageBitmap(bitmap);
}
}
else {
gridView = (View) convertView;
}
return gridView;
}
#Override
public int getCount() {
return mobileValues.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
private InputStream OpenHttpConnection(String urlString) throws IOException {
InputStream in = null;
int response = -1;
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
throw new IOException("Not an HTTP connection");
try {
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
in = httpConn.getInputStream();
}
} catch (Exception ex) {
throw new IOException("Error connecting");
}
return in;
}
private Bitmap DownloadImage(String URL) {
Bitmap bitmap = null;
InputStream in = null;
try {
in = OpenHttpConnection(URL);
bitmap = BitmapFactory.decodeStream(in);
in.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return bitmap;
}
}
and this is part of my main activity.
private class LongOperation extends AsyncTask<String, Void, String>
{
protected void onPreExecute()
{
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setTitle("Molimo sacekajte...");
progressDialog.setMessage("Ucitavam taksi sluzbe...");
progressDialog.setCancelable(true);
progressDialog.show();
}
protected String doInBackground(String... params)
{
niz = new JSONFunkcije().ListaSluzbi();
imena= new String[niz.size()];
Iterator<String> it= niz.iterator();
for (int i=0;i<niz.size();i++)
imena[i]=it.next();
slicice = new ImageAdapter(MainActivity.this, imena);
return null;
}
protected void onPostExecute(String result)
{
progressDialog.dismiss();
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
//Button dugme1 = (Button) findViewById(R.id.dugme1);
///params.height = "50dpi";
//dugme1.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 100));
Gallery gridView = (Gallery) findViewById(R.id.gallery1);
gridView.setAdapter(slicice);
//kraj ucitvanja
//gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
// Sending image id to FullScreenActivity
Intent i = new Intent(getApplicationContext(), TaksiDetalji.class);
// passing array index
i.putExtra("id", imena[position]);
startActivity(i);
}
});
}
});
System.gc();
}
}
I 'm calling LongOperation from OnCrate:
mytask = new LongOperation();
mytask.execute();
Is something wrong with ImageAdapter? Too many calls, downloads? I tried to cache images but I failed.
From your code, I would say there are many reasons and because all these below reasons its running slow:
You haven't followed ViewHolder pattern. Read documentation also for Making ListView Scrolling Smooth
You haven't followed standard way of loading images (i.e. Cached images in local, load from local if its already cached)
Better you try any library available (Universal Image loader or any) on web to load images in your ListView.
Related
My code is showing an error and I don't know what is actually causing it, this line: HttpURLConnection con = client.open(new URL(imageUrl));
package www.com.easyrecepee;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.util.LruCache;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
/**
* Created by Joshua on 9/28/2016.
*/
public class PlacesListAdapter extends ArrayAdapter<Places> {
private Context context;
private List<Places> placesList;
private LruCache<String, Bitmap> imageCache;
// create a field of the RequestQueue to be used by volley
// so it persist through out the life time of the class
//private RequestQueue queue;
public OkHttpClient client = new OkHttpClient();
public PlacesListAdapter(Context context, int resources, List<Places> objects) {
super(context, resources, objects);
this.context = context;
this.placesList = objects;
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
imageCache = new LruCache<>(cacheSize);
// instantiate the queue field and passing current context
// so its associated with proper activity
//queue = Volley.newRequestQueue(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.item_vicinity, parent, false);
// Display places name in the TextView widget
final Places places = placesList.get(position);
TextView placeTitle = (TextView) view.findViewById(R.id.place_title);
TextView vicinity = (TextView) view.findViewById(R.id.vicinity);
//TextView openNow = (TextView)view.findViewById(R.id.openNow);
placeTitle.setText(places.getName());
vicinity.setText(places.getVicinity());
// if(places.isOpenNow()){
// openNow.setText("Open");
// } else {
// openNow.setText("Closed");
// }
//Display place photo in ImageView widget
Bitmap bitmap = imageCache.get(places.getId());
// for volley
final ImageView image = (ImageView) view.findViewById(R.id.place_image);
if (bitmap != null) {
//For the volley, this commented line of code is refactored so it can
// be called outside this block
//ImageView image = (ImageView) view.findViewById(R.id.place_image);
image.setImageBitmap(places.getBitmap());
} else {
// Retrieves image url
//String imageUrl = places.getIconUrl();
// declare instance of image request
/*ImageRequest request = new ImageRequest(imageUrl,
new Response.Listener<Bitmap>(){
#Override
public void onResponse(Bitmap arg0) {
image.setImageBitmap(arg0);
imageCache.put(places.getId(), arg0);
}
},
80, 80,
Bitmap.Config.ARGB_8888,
new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError arg0) {
Log.d("PlacesAdapter", arg0.getMessage());
}
}
);
//adding request to queue
queue.add(request);*/
/*
The line of code below is used by the ImageLoader AsyncTask
Uncomment if using AsyncTask
*/
PlaceAndView container = new PlaceAndView();
container.places = places;
container.view = view;
ImageLoader loader = new ImageLoader();
loader.execute(container);
}
return view;
}
// Used with AsyncTask, since am using Volley, no need
class PlaceAndView {
public Places places;
public View view;
public Bitmap bitmap;
}
// Using the Volley Method does what the AsyncTask do
// Uncomment to use
private class ImageLoader extends AsyncTask<PlaceAndView, Void, PlaceAndView> {
#Override
protected PlaceAndView doInBackground(PlaceAndView... params) {
PlaceAndView container = params[0];
Places places = container.places;
try {
String imageUrl = places.getIconUrl();
// Using OkHttpClient to fetch images
HttpURLConnection con = client.open(new URL(imageUrl));
//HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream in = con.getInputStream();
}
//InputStream in = (InputStream) new URL(imageUrl).getContent();
Bitmap bitmap = BitmapFactory.decodeStream(in);
places.setBitmap(bitmap);
in.close();
container.bitmap = bitmap;
return container;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(PlaceAndView result) {
ImageView image = (ImageView) result.view.findViewById(R.id.place_image);
image.setImageBitmap(result.bitmap);
// saves image for future use
//result.places.setBitmap(result.bitmap);
imageCache.put(result.places.getId(), result.bitmap);
}
}
}
How do I make the open() method stop showing error and that's the only method creating error in the code, so I feel there should be some other method or a newer way to handle the open method.
I suppose you copy the same code in here Fatal Exception: Exception in do in background method (AsyncTask)
So i guess you can adapt this code as need and see if your code runs.
#Override
protected FlowerAndView doInBackground(FlowerAndView... params) {
FlowerAndView container = params[0];
Flower flower = container.flower;
try {
String imageUrl = MainActivity.PHOTOS_BASE_URL + flower.getPhoto();
InputStream in = (InputStream) new URL(imageUrl).getContent();
Bitmap bitmap = BitmapFactory.decodeStream(in);
flower.setBitmap(bitmap);
in.close();
container.bitmap = bitmap;
return container;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
[EDITED]
But using OkHttpClient your code should be something like this.
#Override
protected PlaceAndView doInBackground(PlaceAndView... params) {
PlaceAndView container = params[0];
Places places = container.places;
try {
String imageUrl = places.getIconUrl();
// Using OkHttpClient to fetch images
// HttpURLConnection con = client.open(new URL(imageUrl));
//HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//InputStream in = con.getInputStream();
Request req = new Request.Build()
.url(imageUrl)
.build();
Response response = client.newCall(req).execute();
InputStream in = response.body().byteStream();
//InputStream in = (InputStream) new URL(imageUrl).getContent();
Bitmap bitmap = BitmapFactory.decodeStream(in);
places.setBitmap(bitmap);
in.close();
container.bitmap = bitmap;
return container;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
PS: Remember, there are a lot of libraries to download images glide, picasso, etc. you save time and code.
An example how to use Glide, note how less code you need.
public class PlacesListAdapter extends ArrayAdapter<Places> {
private LayoutInflater mInflater;
public PlacesListAdapter(Context context, int resources, List<Places> objects) {
super(context, resources, objects);
mInflater = LayoutInflater.from(context);
}
class Holder {
TextView placeTitle;
TextView vicinity;
ImageView placeImage;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
Holder holder;
if (view == null) {
view = mInflater.inflate(R.layout.item_vicinity, parent, false);
holder = new Holder();
holder.placeTitle = (TextView) view.findViewById(R.id.place_title);
holder.vicinity (TextView) view.findViewById(R.id.vicinity);
holder.placeImage = (ImageView) view.findViewById(R.id.place_image);
view.setTag(holder);
} else {
holder = view.getTag();
}
// Display places name in the TextView widget
final Places places = getItem(position);
holder.placeTitle.setText(places.getName());
holder.vicinity.setText(places.getVicinity());
Glide
.with(parent.getContext())
.load(places.getIconUrl())
.into(holder.placeImage);
return view;
}
}
I am trying to make an app where I want my app, on launch, to display a grid of popular movie posters. The movie posters are downloaded from TheMovieDataBase API. I then use Picasso to load the images. For the GridView I am also using a custom adapter. I am not able to understand how to do it. Here is what I have done up till now
MovieFragment.java
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import com.squareup.picasso.Picasso;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MovieFragment extends Fragment {
//ArrayAdapter<String> mMovieAdapter;
String[]movieId,movieTitle,movieOverview,
movieReleaseDate,
moviePosterPath,movieVoteAverage;
public MovieFragment() {
}
MovieAdapter mMovieAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
mMovieAdapter = new MovieAdapter(getActivity());
GridView listView = (GridView) rootView.findViewById(R.id.gridView);
listView.setAdapter(mMovieAdapter);
updateMovie();
return rootView;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Inflate the menu; this adds items to the action bar if it is present.
inflater.inflate(R.menu.menu_fragment, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_refresh) {
updateMovie();
return true;
}
return super.onOptionsItemSelected(item);
}
private void updateMovie() {
FetchMovieTask movieTask = new FetchMovieTask();
movieTask.execute();
}
class FetchMovieTask extends AsyncTask<Void, Void, List<String>> {
private final String LOG_TAG = FetchMovieTask.class.getSimpleName();
#Override
protected List<String> doInBackground(Void... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String movieJsonStr = null;
try {
URL url = new URL("http://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=c20129fdf73b5df3ab44548ad7f73586");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
movieJsonStr = buffer.toString();
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(LOG_TAG, "Error closing stream", e);
}
}
}
try {
return getMovieDataFromJson(movieJsonStr);
} catch (JSONException j) {
Log.e(LOG_TAG, "JSON Error", j);
}
return null;
}
private List<String> getMovieDataFromJson(String forecastJsonStr)
throws JSONException {
JSONObject movieJson = new JSONObject(forecastJsonStr);
JSONArray movieArray = movieJson.getJSONArray("results");
List<String> urls = new ArrayList<>();
for (int i = 0; i < movieArray.length(); i++) {
JSONObject movie = movieArray.getJSONObject(i);
urls.add("http://image.tmdb.org/t/p/w185" + movie.getString("poster_path"));
}
return urls;
}
#Override
protected void onPostExecute(List<String> strings) {
mMovieAdapter.replace(strings);
}
}
class MovieAdapter extends BaseAdapter {
private final String LOG_TAG = MovieAdapter.class.getSimpleName();
private final Context context;
private final List<String> urls = new ArrayList<String>();
public MovieAdapter(Context context) {
this.context = context;
Collections.addAll(urls, moviePosterPath);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = new ImageView(context);
}
ImageView imageView = (ImageView) convertView;
String url = getItem(position);
Log.e(LOG_TAG," URL "+url);
Picasso.with(context).load(url).into(imageView);
return convertView;
}
#Override
public int getCount() {
return urls.size();
}
#Override
public String getItem(int position) {
return urls.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public void replace(List<String> urls) {
this.urls.clear();
this.urls.addAll(urls);
notifyDataSetChanged();
}
}
}
When I run this code it shows a NullPointerException and a RuntimeException
java.lang.RuntimeException: Unable to start activity ComponentInfo
{com.codesetters.verader/com.codesetters.verader.MainActivity}: java.lang.NullPointerException atandroid.app.ActivityThreadperformLaunchActivity(ActivityThread.java:2404)
Caused by: java.lang.NullPointerException atjava.util.Collections.addAll(Collections.java:2582)
How can I resolve them?
Please Help
You're getting this error because you've used moviePosterPath here :
Collections.addAll(urls, moviePosterPath);
but you've not initialized it anywhere. Initialize it with some value and it should solve the error.
The null pointer could be because the String array moviePosterPath is not initialized. and you are ussing it in Collections.addAll
This is how to initialize an array. Anyway I recommend you to use ArrayList
String[] moviePosterPath = new String[N];
I am trying to create android app with image gallery created with grid view using image adapter which fetch data using picasso library.but no image is displayed.It may be a problem of context or in picasso library but i am not sure where is the problem as i get no error.everything works fine according to Logs
**package com.example.android.popmovies;
import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import com.squareup.picasso.Picasso;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
/**
* A placeholder fragment containing a simple view.
*/
public class PopMovieFragment extends Fragment {
ImageAdapter imageAdapter;
public PopMovieFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main,container,false);
GridView gridView = (GridView) view.findViewById(R.id.gridview);
imageAdapter = new ImageAdapter(getActivity(),new ArrayList<String>());
gridView.setAdapter(imageAdapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.v("check","ok");
}
});
return inflater.inflate(R.layout.fragment_main, container, false);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onStart() {
super.onStart();
updateMovies();
}
public void updateMovies() {
FetchMovieTask movieTask = new FetchMovieTask();
movieTask.execute();
}
public class FetchMovieTask extends AsyncTask<String, Void, String[]> {
final String LOG_TAG = FetchMovieTask.class.getSimpleName();
private String[] getMovieImageFromJson(String movieJsonStr)
throws JSONException {
ArrayList<String> movieResults = new ArrayList<>();
String posterUrl;
final String OWM_MOVIE_RESULTS = "results";
JSONObject jsonObject = new JSONObject(movieJsonStr);
if (jsonObject.has(OWM_MOVIE_RESULTS)) {
JSONArray movieArray = jsonObject.getJSONArray(OWM_MOVIE_RESULTS);
//JSONArray movieArray = jsonObject.getJSONArray(OWM_MOVIE_RESULTS);
for (int i = 0; i < movieArray.length(); i++) {
JSONObject movieObject = movieArray.getJSONObject(i);
posterUrl = movieObject.getString("poster_path");
movieResults.add(posterUrl);
Log.v(LOG_TAG, posterUrl);
}
for (String items : movieResults){
Log.v(LOG_TAG,items);
}
// return null;
}
return movieResults.toArray(new String[0]);
// Log.v(LOG_TAG,posterUrl);
}
#Override
protected String[] doInBackground(String... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String movieJsonStr = null;
//parameters for api link will be here
try {
final String MOVIE_BASE_URL = "https://api.themoviedb.org/3/movie";
final String APPID_PARAM = "api_key";
final String CRITERIA_FOR_MOVIE_SELECTION_TOP = "top_rated";
final String CRITERIA_FOR_MOVIE_SELECTION_POPULAR = "popular";
Uri builtUri = Uri.parse(MOVIE_BASE_URL).buildUpon()
.appendPath(CRITERIA_FOR_MOVIE_SELECTION_TOP)
.appendQueryParameter(APPID_PARAM, BuildConfig.OPEN_MOVIEDB_API_KEY)
.build();
Log.v("TAG","BuiltURI" + builtUri.toString());
URL url = new URL(builtUri.toString());
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read input stream into a String
InputStream inputstream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputstream == null) {
movieJsonStr = null;
}
reader = new BufferedReader(new InputStreamReader(inputstream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
movieJsonStr = null;
}
movieJsonStr = buffer.toString();
Log.v(LOG_TAG, "Movie Json String" + movieJsonStr);
} catch (IOException e) {
Log.e(LOG_TAG, "error here" + e);
movieJsonStr = null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(LOG_TAG, "ErrorClosingStream", e);
}
}
}
try {
// here will be method call for JSon parsing.
String [] check_items = getMovieImageFromJson(movieJsonStr);
for (String items : check_items){
Log.v(LOG_TAG,items+"new");
}
return check_items;
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String[] result) {
if (result != null) {
for (String resultItems : result){
Log.v(LOG_TAG,resultItems+"GoodLuck");
final String PICTURE_BASE_URL = "http://image.tmdb.org/t/p/w185/";
final String PICTURE_URL_END = resultItems;
Uri builtUri = Uri.parse(PICTURE_BASE_URL).buildUpon()
.appendPath(PICTURE_URL_END.replace("/",""))
.build();
Log.v(LOG_TAG,resultItems+"GoodLuck"+builtUri.toString());
imageAdapter.setmresultItems(builtUri.toString());
}
}
}
}
}
class ImageAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<String> mresultItems;
public ImageAdapter(Context c,ArrayList<String> resultItems){
mContext = c;
mresultItems = resultItems;
}
public int getCount(){
// return mThumbsIds.length;
return 0;
}
public Object getItem(int position){
return null;
}
public long getItemId(int position){
return 0;
}
public void setmresultItems(String resultItems){
mresultItems.add(resultItems);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null){
// if it is not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85,85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8,8,8,8);
}else{
imageView = (ImageView) convertView;
}
//imageView.setImageResource(mThumbsIds[position]);
for(String picResultUrl : mresultItems){
Picasso.with(mContext).load(picResultUrl).into(imageView);
}
return imageView;
}
//references to our Images
//private Integer[] mThumbsIds ;
}**
You shouldn't have a for loop in the getView() method, it already gets called for each item in the list.
Be sure to return the correct count:
public int getCount(){
return mresultItems.size();
}
Then, use just the current position of the data source in getView():
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null){
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85,85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8,8,8,8);
}else{
imageView = (ImageView) convertView;
}
//modified:
String picUrl = mresultItems.get(position);
Picasso.with(mContext).load(picUrl).into(imageView);
}
return imageView;
}
Also, call notifyDataSetChanged() on the adapter in onPostExecute() after the data source of the adapter has been updated:
#Override
protected void onPostExecute(String[] result) {
if (result != null) {
for (String resultItems : result){
Log.v(LOG_TAG,resultItems+"GoodLuck");
final String PICTURE_BASE_URL = "http://image.tmdb.org/t/p/w185/";
final String PICTURE_URL_END = resultItems;
Uri builtUri = Uri.parse(PICTURE_BASE_URL).buildUpon()
.appendPath(PICTURE_URL_END.replace("/",""))
.build();
Log.v(LOG_TAG,resultItems+"GoodLuck"+builtUri.toString());
imageAdapter.setmresultItems(builtUri.toString());
}
//Add this here:
imageAdapter.notifyDataSetChanged();
}
}
I found that i was not returning view in onCreate method which was the root cause of blank screen.
I want to show downloaded images in a ListView. Images are downloaded with a function DownloadImage and are bitmaps.
How do I show this in a ListView?
Images stored in folder htdocs in xampp and name images with book_id in a table book are equal(book_id=100 and name image=100.png).I want each book to have its own image.
I can show in the ListView book_name and book_price. The problem is with the image book.
class:
package bookstore.category;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.http.NameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.squareup.picasso.Picasso;
import android.R.drawable;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import bookstore.pack.JSONParser;
import bookstore.pack.R;
import android.app.Activity;
import android.app.ProgressDialog;
public class Computer extends Activity {
//Bitmap bm = null;
// progress dialog
private ProgressDialog pDialog;
// Creating JSON Parser object
JSONParser jParser = new JSONParser();
ArrayList<HashMap<String, String>> computerBookList;
private static String url_books = "http://10.0.2.2/project/computer.php";
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_BOOK = "book";
private static final String TAG_BOOK_NAME = "book_name";
private static final String TAG_BOOK_PRICE = "book_price";
private static final String TAG_BOOK_ID = "book_id";
private static final String TAG_MESSAGE = "massage";
// category JSONArray
JSONArray book = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.category);
Typeface font1 = Typeface.createFromAsset(getAssets(),
"font/bnazanin.TTF");
// Hashmap for ListView
computerBookList = new ArrayList<HashMap<String, String>>();
new LoadBook().execute();
}
class LoadBook extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Computer.this);
pDialog.setMessage("Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
protected String doInBackground(String... args) {
List<Book> books=new ArrayList<Book>();
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_books, "GET", params);
// Check your log cat for JSON reponse
Log.d("book:", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// books found
book = json.getJSONArray(TAG_BOOK);
for (int i = 0; i < book.length(); i++) {
JSONObject c = book.getJSONObject(i);
// Storing each json item in variable
String book_name = c.getString(TAG_BOOK_NAME);
String book_price = c.getString(TAG_BOOK_PRICE);
String book_id = c.getString(TAG_BOOK_ID);
DownloadImage("10.0.2.2/project/images
/"+book_id+".png");
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_BOOK_NAME, book_name);
map.put(TAG_BOOK_PRICE, book_price);
// map.put(TAG_AUTHOR_NAME, author_name);
// adding HashList to ArrayList
computerBookList.add(map);
}
return json.getString(TAG_MESSAGE);
} else {
System.out.println("no book found");
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
ListView view1 = (ListView) findViewById(R.id.list_view);
public void run() {
ImageView iv = (ImageView) findViewById(R.id.list_image);
ListAdapter adapter = new SimpleAdapter(Computer.this,
computerBookList, R.layout.search_item,
new String[] { TAG_BOOK_NAME, TAG_BOOK_PRICE },
new int[] { R.id.book_name, R.id.book_price });
view1.setAdapter(adapter);
view1.setAdapter(adapter);
}
});
}
}
private Bitmap DownloadImage(String URL) {
Bitmap bitmap = null;
InputStream in = null;
try {
in = OpenHttpConnection(URL);
bitmap = BitmapFactory.decodeStream(in);
in.close();
} catch (IOException e1) {
e1.printStackTrace();
}
return bitmap;
}
private InputStream OpenHttpConnection(String urlString) throws IOException {
InputStream in = null;
int response = -1;
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
throw new IOException("Not an HTTP connection");
try {
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
in = httpConn.getInputStream();
}
} catch (Exception ex) {
throw new IOException("Error connecting");
}
return in;
}
}
For experience better modularity, first of all define a Book class with its properties and methods, For example here is an option:
public class Book {
String mName;
long mPrice;
Bitmap mPhoto;
}
Then collect all of your book information into a list of Book(i.e List<Book>).
Now it's time to declare a custom adapter for the ListView. For example you can try:
public class CustomAdapter extends ArrayAdapter<Book> {
public CustomAdapter(Context context, List<Book> books) {
super(context, 0, books);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if(row == null) {
// inflate row layout and assign to 'row'
}
final thisBook = getItem(position);
final ImageView photo = row.findViewById(R.id.photo);
photo.setImageBitmap(thisBook.mPhoto);
return row;
}
}
Use any library for this.
I recommend to use picasso library
just download the latest jar file from here
and use this code in your getView() method of your adapter
Picasso.with(context)
.load(url)
.placeholder(R.drawable.img_loading)
.error(R.drawable.img_error)
.into(imageView);
First store the bitmaps (from AsyncTask) to an Arraylist or any data structure. Then you have make a Custom adapter extending the "BaseAdapter" class and set it on your Listview so that you can show those bitmaps in your list.
Implementing custom adapters can be found here
I've three values which I extract them from mysql database using JSON and displayed them in a ListView. What I want is I wanna add a click listener. I've a global string variable called urlPageNumHolder to hold the ID from the clicked ListView, so when the list is clicked I want loadPage() function to be called to display Toast of the item ID clicked in the ListVew. I tried it, but whenever I clicked the item in the list, it only toasts ID of the last item in the ListView. Please F1? Below is the full code.
MainActivity.java
package com.myapp;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class MainActivity extends Activity {
private ListView lstView;
private ImageAdapter imageAdapter;
public int currentPage = 1;
public int TotalPage = 0;
public Button btnNext;
public Button btnPre;
public String urlPageNumHolder;
public ProgressDialog dialog;
ArrayList<HashMap<String, Object>> MyArrList = new ArrayList<HashMap<String, Object>>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ListView and imageAdapter
lstView = (ListView) findViewById(R.id.listView1);
lstView.setClipToPadding(false);
imageAdapter = new ImageAdapter(getApplicationContext());
lstView.setAdapter(imageAdapter);
// Next
btnNext = (Button) findViewById(R.id.btnNext);
// Perform action on click
btnNext.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
currentPage = currentPage + 1;
ShowData();
}
});
// Previous
btnPre = (Button) findViewById(R.id.btnPre);
// Perform action on click
btnPre.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
currentPage = currentPage - 1;
ShowData();
}
});
// Show first load
ShowData();
// OnClick
lstView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
loadPage();
}
});
}
public void ShowData() {
btnNext.setEnabled(false);
btnPre.setEnabled(false);
new LoadContentFromServer().execute();
dialog = ProgressDialog.show(this, "News", "Loading...", true, false);
}
public void loadPage() {
Toast.makeText(this, urlPageNumHolder, Toast.LENGTH_LONG).show();
}
class LoadContentFromServer extends AsyncTask<Object, Integer, Object> {
#Override
protected Object doInBackground(Object... params) {
String url = "http://10.0.2.2/android/Pagination/getAllData.php";
JSONArray data;
try {
data = new JSONArray(getJSONUrl(url));
MyArrList = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> map;
int displayPerPage = 7; // Per Page
int TotalRows = data.length();
int indexRowStart = ((displayPerPage * currentPage) - displayPerPage);
if (TotalRows <= displayPerPage) {
TotalPage = 1;
} else if ((TotalRows % displayPerPage) == 0) {
TotalPage = (TotalRows / displayPerPage);
} else {
TotalPage = (TotalRows / displayPerPage) + 1;
TotalPage = (int) TotalPage;
}
int indexRowEnd = displayPerPage * currentPage;
if (indexRowEnd > TotalRows) {
indexRowEnd = TotalRows;
}
for (int i = indexRowStart; i < indexRowEnd; i++) {
JSONObject c = data.getJSONObject(i);
map = new HashMap<String, Object>();
map.put("ImageID", (String) c.getString("ImageID"));
map.put("ItemID", (String) c.getString("ItemID"));
// Thumbnail Get ImageBitmap To Object
map.put("ImagePath", (String) c.getString("ImagePath"));
Bitmap newBitmap = loadBitmap(c.getString("ImagePath"));
map.put("ImagePathBitmap", newBitmap);
MyArrList.add(map);
publishProgress(i);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
public void onProgressUpdate(Integer... progress) {
imageAdapter.notifyDataSetChanged();
}
#Override
protected void onPostExecute(Object result) {
// Disabled Button Next
if (currentPage >= TotalPage) {
btnNext.setEnabled(false);
} else {
btnNext.setEnabled(true);
}
// Disabled Button Previos
if (currentPage <= 1) {
btnPre.setEnabled(false);
} else {
btnPre.setEnabled(true);
}
// dismiss the progress dialog
if(dialog != null) dialog.dismiss();
}
}
class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context context) {
mContext = context;
}
public int getCount() {
return MyArrList.size();
}
public Object getItem(int position) {
return MyArrList.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.activity_column, null);
}
// ColImagePath
ImageView imageView = (ImageView) convertView.findViewById(R.id.ColImagePath);
imageView.getLayoutParams().height = 100;
imageView.getLayoutParams().width = 100;
imageView.setPadding(5, 5, 5, 5);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
try {
imageView.setImageBitmap((Bitmap) MyArrList.get(position).get("ImagePathBitmap"));
} catch (Exception e) {
// When Error
imageView.setImageResource(android.R.drawable.ic_menu_report_image);
}
// ColImageID
TextView txtImgID = (TextView) convertView.findViewById(R.id.ColImageID);
txtImgID.setPadding(10, 0, 0, 0);
txtImgID.setText(MyArrList.get(position).get("ImageID").toString());
// ColItemID
TextView txtItemID = (TextView) convertView.findViewById(R.id.ColItemID);
txtItemID.setPadding(10, 0, 0, 0);
txtItemID.setText(MyArrList.get(position).get("ItemID").toString());
//Hold Detail's URL
urlPageNumHolder = MyArrList.get(position).get("ImageID").toString();
return convertView;
}
}
/*** Get JSON Code from URL ***/
public String getJSONUrl(String url) {
StringBuilder str = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse response = client.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) { // Download OK
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = reader.readLine()) != null) {
str.append(line);
}
} else {
Log.e("Log", "Failed to download file..");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return str.toString();
}
/***** Get Image Resource from URL (Start) *****/
private static final String TAG = "Image";
private static final int IO_BUFFER_SIZE = 4 * 1024;
public static Bitmap loadBitmap(String url) {
Bitmap bitmap = null;
InputStream in = null;
BufferedOutputStream out = null;
try {
in = new BufferedInputStream(new URL(url).openStream(), IO_BUFFER_SIZE);
final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
copy(in, out);
out.flush();
final byte[] data = dataStream.toByteArray();
BitmapFactory.Options options = new BitmapFactory.Options();
// options.inSampleSize = 1;
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,
options);
} catch (IOException e) {
Log.e(TAG, "Could not load Bitmap from: " + url);
} finally {
closeStream(in);
closeStream(out);
}
return bitmap;
}
private static void closeStream(Closeable stream) {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
android.util.Log.e(TAG, "Could not close stream", e);
}
}
}
private static void copy(InputStream in, OutputStream out) throws IOException {
byte[] b = new byte[IO_BUFFER_SIZE];
int read;
while ((read = in.read(b)) != -1) {
out.write(b, 0, read);
}
}
/***** Get Image Resource from URL (End) *****/
}
urlPageNumHolder is only being set in one line urlPageNumHolder = MyArrList.get(position).get("ImageID").toString(), which has nothing to with the item being clicked.
Modify public void loadPage() {...} to
public void loadPage(long id) {
Toast.makeText(this, String.valueOf(id), Toast.LENGTH_LONG).show();
}
and invoke it as :
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
loadPage(id);
}
});
Basically, onItemClickListener tells you which item was clicked with the id parameter that you were originally ignoring. This parameter should be used to identify the item that was clicked.
EDIT:
The id may not be enough to identify the data for you case. In that case, loadPage can be modified as shown below.
public void loadPage(long id) {
Toast.makeText(this, MyArrList.get(position).get("ImageID").toString(), Toast.LENGTH_LONG).show();
}
NOTE: my code may not work as is, you might have to do some int to long conversions (or vice versa)
it looks like you're calling loadPage on click, you need to pass in the index clicked to the loadPage method, then call MyArrList.get(position); to get the location you clicked, then do whatever you want with it.
I see you found onitemclicklistner which is great but with a listview of buttons the buttons consume the click.the easy solution is replace buttons with textview or image icon.the other solution would be,and you can't use findviewbyid because you have to create an array of buttons and onitemclick listeners on each button in the array. So it would be done programaticly not in xml (the buttons anyway)
Also I am not sure about your list adapter so YouTube slidenerd 89 custombaseadapterhttp://m.youtube.com/watch?v=ka5Tk7J9rG0