I am new to android development,I am parsing my data using JSON Parsing method,I extend my class with List Fragment and I want my data in list view but the problem is i am getting all the data perfectly except the images,i don't know how to solve it,my response looks like this
{"matching":[{"name":"Monic Dano","profile_id":"GM335695","image":"http://mywebsitename.com/images/Girlnoimage.jpg","cast":"","age":"24","location":"Ivory Coast"}]}
public class HomeFragment extends ListFragment {
//CustomAdapter adapter;
//private List<RowItem> rowItems;
private ProgressDialog pDialog;
//JSON parser class
JSONParser jsonParser = new JSONParser();
JSONArray matching=null;
ArrayList<HashMap<String,String>> aList;
private static String MATCH_URL = null;
private static final String TAG_MATCH="matching";
private static final String TAG_NAME="name";
private static final String TAG_PROFILE="profile_id";
private static final String TAG_IMAGE="image";
private static final String TAG_CAST="cast";
private static final String TAG_AGE="age";
private static final String TAG_LOCATION="location";
private ListView listview;
public HomeFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strtext = getArguments().getString("user_login_id");
MATCH_URL = "http://mywebsitename.com/webservice/matching?version=apps&user_login_id="+strtext;
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
aList = new ArrayList<HashMap<String,String>>();
// rowItems = new ArrayList<RowItem>();
listview=(ListView)rootView.findViewById(android.R.id.list);
new LoadAlbums().execute();
return rootView;
}
class LoadAlbums extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(HomeFragment.this.getActivity());
pDialog.setMessage("Loading...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
protected String doInBackground(String... args) {
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(MATCH_URL, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
matching = jsonObj.getJSONArray(TAG_MATCH);
// looping through All Contacts
for (int i = 0; i < matching.length(); i++) {
JSONObject c = matching.getJSONObject(i);
// Storing each json item values in variable
String user_name = c.getString(TAG_NAME);
String user_profile=c.getString(TAG_PROFILE);
String user_image=c.getString(TAG_IMAGE);
String user_cast=c.getString(TAG_CAST);
String user_age=c.getString(TAG_AGE);
String user_location=c.getString(TAG_LOCATION);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_NAME,user_name);
map.put(TAG_PROFILE, user_profile);
map.put(TAG_IMAGE, user_image);
map.put(TAG_CAST, user_cast);
map.put(TAG_AGE, user_age+" years");
map.put(TAG_LOCATION, user_location);
// adding HashList to ArrayList
aList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
protected void onPostExecute(String file_url) {
super.onPostExecute(file_url);
// dismiss the dialog after getting all albums
if (pDialog.isShowing())
pDialog.dismiss();
// updating UI from Background Thread
/**
* Updating parsed JSON data into ListView
* */
// updating listview
CustomAdapter adapter = new CustomAdapter(getActivity(),aList);
setListAdapter(adapter);
}
}
}
Try to AndroidQuery with custom adapter :
public class CustomAdapter extends BaseAdapter {
private Context context;
private ArrayList<HashMap<String,String>> listData;
private AQuery aQuery;
private static final String TAG_NAME="name";
private static final String TAG_PROFILE="profile_id";
private static final String TAG_IMAGE="image";
private static final String TAG_CAST="cast";
private static final String TAG_AGE="age";
private static final String TAG_LOCATION="location";
public CustomAdapter(Context context,ArrayList<HashMap<String,String>> listData) {
this.context = context;
this.listData=listData;
aQuery = new AQuery(this.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(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.list_item, null);
holder.propic = (ImageView) convertView.findViewById(R.id.propic);
holder.txtproname = (TextView) convertView.findViewById(R.id.txtproname);
holder.txtproid = (TextView) convertView.findViewById(R.id.txtproid);
holder.txtprofilecast = (TextView) convertView.findViewById(R.id.txtprofilecast);
holder.txtprofileage = (TextView) convertView.findViewById(R.id.txtprofileage);
holder.txtprofileplace = (TextView) convertView.findViewById(R.id.txtprofileplace);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.txtproname.setText(listData.get(position).get(TAG_NAME));
holder.txtproid.setText(listData.get(position).get(TAG_PROFILE));
holder.txtprofilecast.setText(listData.get(position).get(TAG_CAST));
holder.txtprofileage.setText(listData.get(position).get(TAG_AGE));
holder.txtprofileplace.setText(listData.get(position).get(TAG_LOCATION));
aQuery.id(holder.propic).image(listData.get(position).get(TAG_IMAGE),true,true,0,R.drawable.ic_launcher);
// image parameter : 1 : memory cache,2:file cache,3:target width,4:fallback image
return convertView;
}
class ViewHolder{
ImageView propic;
TextView txtproname;
TextView txtproid;
TextView txtprofilecast;
TextView txtprofileage;
TextView txtprofileplace;
}
}
How to set adapter to ListView :
CustomAdapter adapter = new CustomAdapter(getActivity(),aList);
setListAdapter(adapter);
You can use universal image loader for viewing images from your server.Z
Just pass the image url and your view and you are good to go.
For your reference here is the link to Universal Image loader with all its documentation.
https://github.com/nostra13/Android-Universal-Image-Loader
Hop it helps you.
I am hardly suggest you to use Android Query for this. Its mind blowing api given by Android itself. You can download image, download bitmap or whatever you wanna do you can.
You can download the jar file from here :here Download the jar file and set jar to your Build Path.
AQuery androidAQuery=new AQuery(this);
As an example to load image directly from url:
androidAQuery.id(YOUR IMAGEVIEW).image(YOUR IMAGE TO LOAD, true, true, getDeviceWidth(), ANY DEFAULT IMAGE YOU WANT TO SHOW);
As an example to get Bitmap from url:
androidAQuery.ajax(YOUR IMAGE URL,Bitmap.class,0,new AjaxCallback<Bitmap>(){
#Override
public void callback(String url, Bitmap object, AjaxStatus status) {
super.callback(url, object, status);
//You will get Bitmap from object.
}
});
It's very fast and accurate, and using this you can find many more features like Animation when loading; getting a bitmap, if needed; etc.
//Declare adapter globally.
private EfficientAdapter adapter;
//Initialize it in onCreate() method
adapter = new EfficientAdapter(this);
//Set your adapter like
listview.setAdapter(adapter);
//Adapter class code
private class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private Context context;
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
this.context = context;
}
#Override
public int getCount() {
return aList.size();
}
#Override
public Object getItem(int arg0) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.YOUR ITEM LAYOUT, null);
holder = new ViewHolder();
holder.txtName = (TextView) convertView.findViewById(R.id.txtName);
holder.txtProfile = (TextView) convertView.findViewById(R.id.txtProfile);
holder.txtCast = (TextView) convertView.findViewById(R.id.txtCast);
holder.txtAge = (ImageView) convertView.findViewById(R.id.txtAge);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtName.setText(aList.get(position).get(TAG_NAME));
holder.txtProfile.setText(aList.get(position).get(TAG_PROFILE));
holder.txtCast.setText(aList.get(position).get(TAG_CAST));
holder.txtAge.setText(aList.get(position).get(TAG_AGE));
aQuery.id(holder.imgUser).image(data.get(position).get(TAG_IMAGE), true, true);
return convertView;
}
class ViewHolder {
TextView txtName;
TextView txtProfile;
TextView txtCast;
TextView txtAge;
ImageView imgUser;
}
}
In source code of SimpleAdapter:
private void bindView(int position, View view) {
final Map dataSet = mData.get(position);
if (dataSet == null) {
return;
}
final ViewBinder binder = mViewBinder;
final String[] from = mFrom;
final int[] to = mTo;
final int count = to.length;
for (int i = 0; i < count; i++) {
final View v = view.findViewById(to[i]);
if (v != null) {
final Object data = dataSet.get(from[i]);
String text = data == null ? "" : data.toString();
if (text == null) {
text = "";
}
boolean bound = false;
if (binder != null) {
bound = binder.setViewValue(v, data, text);
}
if (!bound) {
if (v instanceof Checkable) {
if (data instanceof Boolean) {
((Checkable) v).setChecked((Boolean) data);
} else if (v instanceof TextView) {
// Note: keep the instanceof TextView check at the bottom of these
// ifs since a lot of views are TextViews (e.g. CheckBoxes).
setViewText((TextView) v, text);
} else {
throw new IllegalStateException(v.getClass().getName() +
" should be bound to a Boolean, not a " +
(data == null ? "<unknown type>" : data.getClass()));
}
} else if (v instanceof TextView) {
// Note: keep the instanceof TextView check at the bottom of these
// ifs since a lot of views are TextViews (e.g. CheckBoxes).
setViewText((TextView) v, text);
} else if (v instanceof ImageView) {
if (data instanceof Integer) {
setViewImage((ImageView) v, (Integer) data);
} else {
setViewImage((ImageView) v, text);
}
} else {
throw new IllegalStateException(v.getClass().getName() + " is not a " +
" view that can be bounds by this SimpleAdapter");
}
}
}
}
}
You can see if your view is ImageView , the code will use the url String be the resId in
/**
* Called by bindView() to set the image for an ImageView but only if
* there is no existing ViewBinder or if the existing ViewBinder cannot
* handle binding to an ImageView.
*
* By default, the value will be treated as an image resource. If the
* value cannot be used as an image resource, the value is used as an
* image Uri.
*
* This method is called instead of {#link #setViewImage(ImageView, int)}
* if the supplied data is not an int or Integer.
*
* #param v ImageView to receive an image
* #param value the value retrieved from the data set
*
* #see #setViewImage(ImageView, int)
*/
public void setViewImage(ImageView v, String value) {
try {
v.setImageResource(Integer.parseInt(value));
} catch (NumberFormatException nfe) {
v.setImageURI(Uri.parse(value));
}
}
And your error is here , so you need Override the getView function of SimpleAdapter.Here is code:
Uri uri = Uri.parse("http://gujjumatch.com/images/Girlnoimage.jpg");
image.setImageURI(uri);
You need to create adapter and extend it to BaseAdapter and add all your items and call it in your AsyncTask's method and it will return your output as said by Haresh Chellana.
Related
I am able to show images (set by default) in the gridview properly using a custom adapter.
However when I try to change the string[] in ForecastFragment (snippets below), the updateList function is not getting called. I would like the all the views in the grid to be recreated.
ImageAdapter.java :
public class ImageAdapter extends BaseAdapter {
public Context mContext; ImageAdapter(Context c) {
mContext = c;
String LOG_TAG = ImageAdapter.class.getSimpleName();
Log.e(LOG_TAG,"Constructor Context : "+mContext);
}
public int getCount() {
return this.eatFoodyImages.length;
}
public int size1;
public int size2;
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
public void updateList(String[] string)
{
this.eatFoodyImages=string;
this.notifyDataSetChanged();
String LOG_TAG = ImageAdapter.class.getSimpleName();
Log.e(LOG_TAG, "\n\nupdatelist : " + this.eatFoodyImages);
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
size1 = (int) this.mContext.getResources().getDimension(R.dimen.image_size1);
size2 = (int) this.mContext.getResources().getDimension(R.dimen.image_size2);
imageView.setLayoutParams(new GridView.LayoutParams(size1,size2));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(0, 0, 0, 0);
} else {
imageView = (ImageView) convertView;
}
String LOG_TAG = ImageAdapter.class.getSimpleName();
Log.e(LOG_TAG, "\n\n\nPosition : " + position + " Strings Array : \n\n" + eatFoodyImages[position].toString());
//System.out.println();
Picasso.with(mContext)
.
load(eatFoodyImages[position])
.
into(imageView);
return imageView;
}
// references to our images
public String[] eatFoodyImages = {
"http://i.imgur.com/rFLNqWI.jpg", //Default Random Data!!!
"http://i.imgur.com/C9pBVt7.jpg",
"http://i.imgur.com/rT5vXE1.jpg",
"http://i.imgur.com/aIy5R2k.jpg",
"http://i.imgur.com/MoJs9pT.jpg",
"http://i.imgur.com/S963yEM.jpg",
"http://i.imgur.com/rLR2cyc.jpg",
"http://i.imgur.com/SEPdUIx.jpg",
"http://i.imgur.com/aC9OjaM.jpg",
"http://i.imgur.com/76Jfv9b.jpg",
"http://i.imgur.com/fUX7EIB.jpg",
"http://i.imgur.com/syELajx.jpg",
"http://i.imgur.com/COzBnru.jpg",
"http://i.imgur.com/Z3QjilA.jpg",
};
}
ForecastFragment.java :
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
GridView gridview = (GridView) rootView.findViewById(R.id.gridview);
movieadapter = new ImageAdapter(this.getActivity());
gridview.setAdapter(movieadapter);
});
return rootView;
}
Calling updateList :
public class FetchWeatherTask extends AsyncTask<String, Void, String[]>
{//Showing only relevant code
IA.updateList(eatFoodyImages); //Here eatFoodyImages contains the new String[] to be used for image loading.
Here it goes, i have a adapter like below
public View getView(int position, View convertView, ViewGroup parent) {
Movie movie = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(
R.layout.movie_tile, parent, false);
}
ImageView imageView = (ImageView) convertView.findViewById(R.id.movie_image);
Picasso.with(this.getContext()).load(Constants.MOVIE_POSTER_PATH_SMALL + movie.getPosterPath()).placeholder(ContextCompat.getDrawable(this.getContext(), R.drawable.movie)).error(ContextCompat.getDrawable(this.getContext(), R.drawable.movie)).into(imageView);
return convertView;
}
which sets a tile in a gridview.
I trigger a asynctask and get the movies from API then notify the dataset which loads the movies and refreshes the view.
So essentially your notifyDataSet() should be in onPostExecute() of AsyncTask.
Here is my Async task code for better understanding.
public class CallMovieDBAPI extends AsyncTask<String, Void, List<Movie>> {
ProgressDialog dialog;
private Activity activity;
private GridView gridView;
public CallMovieDBAPI(Activity activity, GridView gridView) {
this.activity = activity;
this.gridView = gridView;
}
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(getActivity());
dialog.setMessage(activity.getString(R.string.progressDialogText));
dialog.show();
}
#Override
protected List<Movie> doInBackground(String... params) {
InputStream in = null;
String jsonResponse = null;
String apiURL = params[0];
try {
URL url = new URL(apiURL);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream());
jsonResponse = getJsonObject(in);
movieList = JsonParser.parse(jsonResponse);
} catch (Exception e) {
Log.e("CallMovieDBAPI", "Exception occurred in AsyncTask - CallMovieDBAPI", e);
}
return movieList;
}
#Override
protected void onPostExecute(List<Movie> movies) {
Log.d("Popular Movies", "Got data successfully");
if (dialog.isShowing()) {
dialog.dismiss();
}
movieAdapter = new MovieAdapter(activity, movieList);
gridView.setAdapter(movieAdapter);
movieAdapter.notifyDataSetChanged();
if (isTablet) {
((MovieClickedCallback) getActivity()).onMovieClicked(0, movieAdapter);
}
}
Let me know if this solves.
I'm using ListView that retrieves data from external URL with JSON.
When I run my app, it shows only maximum of 10 results since my api query returns maximum of 10 results PER page.
What i'm trying to do is, that when the user scrolls down to the end of this 10 results, it will load more results (one by one would be even greater) from my JSON external URL (API).
This is how I'm using my ListView & JSONAdapter:
TabFragment1.java
ListView mainListView = (ListView) v.findViewById(R.id.main_listview);
mJSONAdapter = new JSONAdapter(getActivity(), inflater);
mainListView.setAdapter(mJSONAdapter);
getUpdates();
getUpdates()
private void queryUpdates(double lat, double lon, int distance) {
// Create a client to perform networking
AsyncHttpClient client = new AsyncHttpClient();
// Show ProgressBar to inform user that a task in the background is occurring
mProgress.setVisibility(View.VISIBLE);
// Have the client get a JSONArray of data
// and define how to respond
client.get(API_URL + "?lat=" + lat + "&lon=" + lon + "&distance=" + distance,
new JsonHttpResponseHandler() {
#Override
public void onSuccess(JSONObject jsonObject) {
// 11. Dismiss the ProgressDialog
mProgress.setVisibility(View.GONE);
// update the data in your custom method.
mJSONAdapter.updateData(jsonObject.optJSONArray("docs"));
}
#Override
public void onFailure(int statusCode, Throwable throwable, JSONObject error) {
// 11. Dismiss the ProgressDialog
mProgress.setVisibility(View.GONE);
getActivity().setContentView(R.layout.bad_connection);
}
});
}
My JSONAdapter.java
public class JSONAdapter extends BaseAdapter implements StickyListHeadersAdapter {
Context mContext;
LayoutInflater mInflater;
JSONArray mJsonArray;
public JSONAdapter(Context context, LayoutInflater inflater) {
mContext = context;
mInflater = inflater;
mJsonArray = new JSONArray();
}
#Override
public int getCount() {
return mJsonArray.length();
}
#Override
public Object getItem(int position) {
return mJsonArray.optJSONObject(position);
}
#Override
public long getItemId(int position) {
// your particular dataset uses String IDs
// but you have to put something in this method
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
// check if the view already exists
// if so, no need to inflate and findViewById again!
if (convertView == null) {
// Inflate the custom row layout from your XML.
convertView = mInflater.inflate(R.layout.row_place_update, null);
// create a new "Holder" with subviews
holder = new ViewHolder();
holder.myImageView = (ImageView) convertView.findViewById(R.id.myImage);
holder.myTextView = (TextView) convertView.findViewById(R.id.myText);
// hang onto this holder for future recyclage
convertView.setTag(holder);
} else {
// skip all the expensive inflation/findViewById
// and just get the holder you already made
holder = (ViewHolder) convertView.getTag();
}
// More code after this
// Get the current book's data in JSON form
JSONObject jsonObject = (JSONObject) getItem(position);
// Grab the title and author from the JSON
if (jsonObject != null) {
//Get from JSON
String myImage = jsonObject.optString("myImage");
String myText = jsonObject.optString("myText");
//Replace Them
Picasso.with(mContext).load(myImage).placeholder(R.drawable.loading).into(holder.myImageView);
holder.myTextView.setText(myText);
}
return convertView;
}
// this is used so you only ever have to do
// inflation and finding by ID once ever per View
private static class ViewHolder {
public ImageView myImageView;
public TextView myTextView;
}
public void updateData(JSONArray jsonArray) {
// update the adapter's dataset
mJsonArray = jsonArray;
notifyDataSetChanged();
}
}
how I can show more results by adding &page=2, &page=3 to the API_URL and load these results in my ListVIew, in addition to the old results?
I'm stuck creating an Adapter for my Griview that accepts an ArrayList. I think the bad line in the Adapter class is: viewHldr.wcbc_image_iv.setImageResource(urlStrArrList.get(position)); and it appears that the call .setImageResource is the problem.
public class JGrid66 extends Activity {
JSONObject jsonOb;
JSONArray JSArrGallery = null;;
GridView grid65_gv;
JGrid66Adapter2 jGr7Adap;
ProgressDialog mProgressDialog;
ArrayList<String> idStrArrList = new ArrayList<String>();
ArrayList<String> urlStrArrList = new ArrayList<String>();
ArrayList<String> descrStrArrList = new ArrayList<String>();
// JSON Node names
private static final String TAG_GALLERY = "gallery";
private static final String TAG_GALLERYURL = "galleryurl";
private static final String TAG_ID = "id";
private static final String TAG_GALLERYDESCR = "gallerydescr";
static String FLAG = "flag";
private String jsonUrl = "http://www.mysite.com/apps/wcbc/galleryuil.txt";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.jgrid66);
grid65_gv = (GridView) findViewById(R.id.jgrid66_gv);
}//--- END onCreate
//--- DownloadJSON Class
private class DownloadJSON extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
JGrid4Adapter jParser = new JGrid4Adapter();
// getting JSON string from URL
JSONObject jsonOb = jParser.getJSONFromUrl(jsonUrl);
try {
JSArrGallery = jsonOb.getJSONArray(TAG_GALLERY);
// looping through All gallery images
for (int i = 0; i < JSArrGallery.length(); i++) {
JSONObject galleryJO = JSArrGallery.getJSONObject(i);
String idStr = galleryJO.getString(TAG_ID);
String urlStr = galleryJO.getString(TAG_GALLERYURL);
String descrStr = galleryJO.getString(TAG_GALLERYDESCR);
idStrArrList.add(idStr);
urlStrArrList.add(urlStr);
descrStrArrList.add(descrStr);
}// -- END for loop
} catch (JSONException e) {
e.printStackTrace();
}// --- END Try
return null;
}
#Override
protected void onPostExecute(Void args) {
jGr7Adap = new JGrid66Adapter2(JGrid66.this, urlStrArrList);
grid65_gv.setAdapter(jGr7Adap);
jGr7Adap.notifyDataSetChanged();
}
}
//--- END DownloadJSON Class
}
Here;s the Adapter:
public class JGrid66Adapter2 extends BaseAdapter {
private ArrayList<String> urlStrArrList;
Context context;
public JGrid66Adapter2(Context context,ArrayList<String> urlStrArrList) {
super();
this.urlStrArrList = urlStrArrList;
}
#Override
public int getCount() {
return urlStrArrList.size();
}
#Override
public String getItem(int position) {
return urlStrArrList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
public static class ViewHolder
{
public ImageView wcbc_image_iv;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHldr;
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
if(convertView==null){
viewHldr = new ViewHolder();
convertView = inflater.inflate(R.layout.jgrid66_item, null);
viewHldr.wcbc_image_iv = (ImageView) convertView.findViewById (R.id.jgrid66_iv);
convertView.setTag(viewHldr);
}
else
{
viewHldr = (ViewHolder) convertView.getTag();
}
//--- I commented this out because this is where it breaks.
//viewHldr.wcbc_image_iv.setImageResource(urlStrArrList.get(position));
return convertView;
}
}
Any help would be great!
private ArrayList<String> urlStrArrList;
is arraylist of strings. If you have the url you need to download the images and then set it to imageview.
setImageResource takes a resource id as a param which is an int value.
public void setImageResource (int resId)
Added in API level 1
Sets a drawable as the content of this ImageView.
You may consider using Lazy Loading Universal Image Loader or using picasso
Caching images and displaying
I am using json parser to pass image url and description into my listview. now i managed to load the images but how do i change the text for my list view? currently it just shows item 0, item 1 and so on.. how do i pass the description into the lazyadapter?
Main activity:
public class MainActivity extends Activity {
// CREATING JSON PARSER OBJECT
JSONParser jParser = new JSONParser();
JSONArray guide = null;
ListView list;
LazyAdapter adapter;
String[] mImageIds;
ArrayList<String> guideList =new ArrayList<String>();
ArrayList<String> descriptionList =new ArrayList<String>();
// GUIDE URL
private static String url_guide = "http://58.185.41.178/magazine_android/get_guide.txt";
private static final String TAG_GUIDES = "guides"; //the parent node of my JSON
private static final String TAG_DESCRIPTION = "description";
private static final String TAG_IMAGE = "image";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// LOADING Guide IN BACKGROUND THREAD
new LoadGuide().execute();
list=(ListView)findViewById(R.id.list);
adapter=new LazyAdapter(this,guideList);
list.setAdapter(adapter);
Button b=(Button)findViewById(R.id.button1);
b.setOnClickListener(listener);
}
#Override
public void onDestroy()
{
list.setAdapter(null);
super.onDestroy();
}
public OnClickListener listener=new OnClickListener(){
#Override
public void onClick(View arg0) {
adapter.imageLoader.clearCache();
adapter.notifyDataSetChanged();
}
};
/**
* Background Async Task to Load all product by making HTTP Request
* */
class LoadGuide extends AsyncTask<String, String, String> {
/**
* getting All videos from url
* */
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_guide, "GET", params);
// CHECKING OF JSON RESPONSE
Log.d("All guide: ", json.toString());
try {
guide = json.getJSONArray(TAG_GUIDES);
for (int i = 0; i < guide.length(); i++) {
JSONObject c = guide.getJSONObject(i);
//String title = c.getString(TAG_DESCRIPTION);
String image = c.getString(TAG_IMAGE);
String description = c.getString(TAG_DESCRIPTION);
guideList.add(image);
descriptionList.add(description);
System.out.println(guideList);
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// UPDATING UI FROM BACKGROUND THREAD
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
adapter.notifyDataSetChanged();
}
});
}
}
}
Image adapter:
public class LazyAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<String> data;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;
public LazyAdapter(Activity a, ArrayList<String> guideList) {
activity = a;
data=guideList;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.item, null);
TextView text=(TextView)vi.findViewById(R.id.text);;
ImageView image=(ImageView)vi.findViewById(R.id.image);
text.setText("item "+position);
imageLoader.DisplayImage(data.get(position), image);
return vi;
}
}
In your adapter, you are making the TextView say "item 1", "item 2" etc specifically. What you need to do is add in the Adapter constructor your descriptionList
public LazyAdapter(Activity a, ArrayList<String> guideList, ArrayList<String> descriptionList) {
and then do
text.setText(descriptionList.get(position));
When your activity calls adapter.notifyDataSetChanged(), that forces a re-draw of every item in the list. That will trigger a call into the getView() method your adapter. So your logic belongs in the getView() method:
text.setText(descriptionList.get(position));
Use a single Hashmap for guidelist and descriptionlist and then pass that to the lazyadapter constructor. use the description part of the hashmap in the getview() method to the set the text.
#user1933630
descriptionList.add(description.subString(1,description.length()-1);
I want to load images from a server, AFTER loading the data in a list view.
I know that a lot of topics existing for this problem but I haven't found the solution...
So this is my code :
//asyncTackClass for loadingpictures
public class LoadImagesThread extends AsyncTask<Bundle, Void, Bitmap> {
private ImageView view;
private Bitmap bm;
private Context context;
private final WeakReference<ImageView> imageViewReference;
private final String BUNDLE_URL = "url";
private final String BUNDLE_NAME = "name";
private final String BUNDLE_BM = "bm";
public LoadImagesThread(Context context, ImageView view) {
this.context=context;
imageViewReference = new WeakReference<ImageView>(view);
}
#Override
protected Bitmap doInBackground(Bundle... b) {
Bitmap bm =null;
if (StorageHelper.getBitmap(b[0].getString(BUNDLE_NAME)) != null) { // Check the sdcard
bm = StorageHelper.getBitmap(b[0].getString(BUNDLE_NAME));
Log.w("LoadImagesThread", "Get image from sdcard : "+b[0].getString(BUNDLE_NAME));
} else { // Check the server
bm = ServiceHelper.getBitmapFromURL(b[0].getString(BUNDLE_URL));
StorageHelper.saveBitmap(bm, b[0].getString(BUNDLE_NAME)); // Save image on sdcard
Log.w("LoadImagesThread", "Get image from server : "+b[0].getString(BUNDLE_NAME));
}
return bm;
}
#Override
protected void onPostExecute(final Bitmap bm) {
super.onPostExecute(bm);
if (bm != null){ //if bitmap exists...
view = imageViewReference.get();
// Fade out
Animation fadeOutAnimation = AnimationUtils.loadAnimation(context, R.anim.fadeoutimage);
fadeOutAnimation.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
// Fade in
view.setImageBitmap(bm);
Animation fadeInAnimation = AnimationUtils.loadAnimation(context, R.anim.fadeinimage);
view.startAnimation(fadeInAnimation);
}
});
// Launch the fadeout
view.startAnimation(fadeOutAnimation);
}else{ //if not picture, display the default ressource
view.setImageResource(R.drawable.productcarre);
}
}
}
The code is used to display a Bitmap in a ImageView
And this is the adapter:
public class ListViewShoplistStoresAdapter extends BaseAdapter {
private ArrayList<Shop> shopList;
private Activity activity;
private HashMap<Integer, ImageView> views;
private final String BUNDLE_URL = "url";
private final String BUNDLE_NAME = "name";
private final String BUNDLE_POS = "pos";
private final String BUNDLE_ID = "id";
public ListViewShoplistStoresAdapter(Activity activity, ArrayList<Shop> shopList) {
super();
this.activity = activity;
this.shopList = shopList;
this.views = new HashMap<Integer, ImageView>();
}
public int getCount() {
return shopList.size();
}
public Object getItem(int position) {
return shopList.get(position);
}
public long getItemId(int position) {
return shopList.get(position).getId();
}
private class ViewHolder {
public TextView store;
public TextView name;
public ImageView ImageStore;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder view;
LayoutInflater inflator = activity.getLayoutInflater();
if(convertView == null) {
view = new ViewHolder();
convertView = inflator.inflate(R.layout.listviewshops, null);
view.store = (TextView) convertView.findViewById(R.id.store);
view.name = (TextView) convertView.findViewById(R.id.name);
view.ImageStore = (ImageView) convertView.findViewById(R.id.imgstore);
convertView.setTag(view);
}else {
view = (ViewHolder) convertView.getTag();
}
Typeface regular=Typeface.createFromAsset(activity.getAssets(), "fonts/RobotoRegular.ttf");
view.store.setTypeface(regular);
Typeface light=Typeface.createFromAsset(activity.getAssets(), "fonts/RobotoLight.ttf");
view.store.setTypeface(light);
Brand brand = StorageHelper.getBrand(activity, shopList.get(position).getBrandId());
if (brand == null) {
Log.e("SetShopInAdapter","Brand null");
Toast.makeText(activity, "Impossible d'afficher la liste de magasins", Toast.LENGTH_LONG).show();
} else {
view.store.setText(brand.getName());
view.name.setText(shopList.get(position).getName());
view.ImageStore.setImageResource(R.drawable.productcarre);
}
Bundle b = new Bundle();
//url of the pict
b.putString(BUNDLE_URL, ServiceHelper.getImageUrl("brand", brand.getName()));
// name of image
b.putString(BUNDLE_NAME, ServiceHelper.getCleanImageName(brand.getName()));
//position in the listView
b.putInt(BUNDLE_POS, position);
//id of the current object
b.putInt(BUNDLE_ID, brand.getId());
//put info in the map in order to display in the onPostExecute
if(views.get(position)==null){
views.put(position, view.ImageStore);
// launch thread
new LoadImagesThread(activity.getApplicationContext(), view.ImageStore).execute(b);
}
return convertView;
}
}
So, when I used a GridView, there were no problems, but when I use a ListView the image is changed only in the first item !
Example:
I want to display product images for "car", "house" and "apple" items.
The code will launch the thread and all images (car then house and finally apple) will be displayed in the first item (the car item)...
And the house and the apple while not have images !!
Do you know what I should do ?
Thanks
There is a lot about this here on SO..
asynchrnous loading like that is called "Lazy Loading"
https://github.com/thest1/LazyList
for full implementation of such a process with list
For loading images in general i recomend this :
https://github.com/nostra13/Android-Universal-Image-Loader
You can use volley to improve in listview performance.
Take a look at this simple example: Android Custom ListView with Image and Text using Volley