I have a ListView of elements composed with ImageView. I get a new image using an AsyncTask and in the onPostExecute(Object result) method I set the image using setImageUri(Uri uri) but it doesn't gets updated.
If I change of activity or between apps, image is shown perfectly, but I want to show the image immediately.
I tried calling invalidate() with all the combinations of the ImageView, the extended BaseAdapter, the parent ListView, but nothing worked. I tried many other techniques like calling setImageResource(0), setImageUri(null), but no results...
EDITED:
Here, part of the code:
public class ThingItemAdapter extends BaseAdapter {
protected List<Thing> things;
LayoutInflater inflater;
public ThingItemAdapter(Context context, List<Thing> things) {
this.things = things;
this.inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return things.size();
}
#Override
public Thing getItem(int position) {
return things.get(position);
}
#Override
public long getItemId(int position) {
return things.get(position).getId();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final int pos = position;
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = this.inflater.inflate(R.layout.thing_list_item, parent, false);
holder.thingImageView = (ImageView) convertView.findViewById(R.id.thing_preview);
holder.button = (ImageButton) convertView.findViewById(R.id.apply_button);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final Thing thing = things.get(position);
final long thingId = thing.getId();
final Uri thingUri = thing.getPicture();
holder.thingImageView.setImageURI(thingUri);
holder.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// generate new file
final TypedFile typedFile = new TypedFile("multipart/form-data", new File(thingUri.getPath()));
new ReadAndStorePictureTask()
.execute(new Object[] { typedFile, holder.thingImageView, thing });
}
});
// item detailed view listener
holder.thingImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent((ThingApplication) ThingApplication.getContext(), ThingActivity.class);
intent.putExtra(ThingActivity.EXTRA_THING_ID, thingId);
context.startActivity(intent);
}
});
return convertView;
}
private class ViewHolder {
ImageView thingImageView;
ImageButton button;
}
private class ReadAndStorePictureTask extends AsyncTask<Object, Void, Void> {
ImageView imageView;
Thing thing;
ViewGroup parent;
protected Void doInBackground(Object... params) {
final TypedFile typedFile = (TypedFile) params[0];
imageView = (ImageView) params[1];
thing = (Thing) params[2];
((ThingApplication) ThingApplication.getContext()).getClient().apply(typedFile,
new Callback<Response>() {
#Override
public void failure(RetrofitError error) {
...
}
#Override
public void success(Response nothing, Response response) {
try {
byte[] bytes = ThingApplication.getBytesFromStream(response.getBody().in());
Uri newImageURI = Uri.parse("uri://valid_uri"); // whatever, it exists in real code
thing.setPicture(newImageURI);
File file = ((ThingApplication) ThingApplication.getContext())
.getFileFromURI(newImageURI); // this method works
ThingApplication.saveBytesToFile(bytes, file.getAbsolutePath());
thingService.storeThing(thing);
} catch (Exception e) {
...
}
}
});
return null;
}
#Override
protected void onPostExecute(Void result) {
imageView.setImageURI(thing.getPicture());
// force redraw. FIXME not working
/*
* ANSWER HERE, PLEASE
*/
}
}
}
How can I show the updated URI immediately inside onPostExecute(Object result) method?
onPostExecute you update the list of images that it's linked to the ListView adapter and after that you notify the adapter that you changed the items in the list by calling:
adapter.notifyDataSetChanged();
You can do something like this:
-Change third parameter in asynctask call.
new ReadAndStorePictureTask().execute(
new Object[] { typedFile, holder.thingImageView, pos });
-Then, modify the list items inside asynctask and refresh.
private class ReadAndStorePictureTask extends AsyncTask<Object, Void, Void> {
ImageView imageView;
int position;
ViewGroup parent;
protected Void doInBackground(Object... params) {
final TypedFile typedFile = (TypedFile) params[0];
imageView = (ImageView) params[1];
position = (Integer) params[2];
((ThingApplication) ThingApplication.getContext()).getClient().apply(typedFile,
new Callback<Response>() {
#Override
public void failure(RetrofitError error) {
...
}
#Override
public void success(Response nothing, Response response) {
try {
byte[] bytes = ThingApplication.getBytesFromStream(response.getBody().in());
Uri newImageURI = Uri.parse("uri://valid_uri"); // whatever, it exists in real code
things.get(position).setPicture(newImageURI);
File file = ((ThingApplication) ThingApplication.getContext())
.getFileFromURI(newImageURI); // this method works
ThingApplication.saveBytesToFile(bytes, file.getAbsolutePath());
thingService.storeThing(things.get(position));
} catch (Exception e) {
...
}
}
});
return null;
}
#Override
protected void onPostExecute(Void result) {
notifyDataSetChanged();
}
}
Good luck!
Related
currently i had come out a screen that using tab fragment and RecyclerView like below. I want to know how i going to handle the button click that circle in red. Every time i click, i have get the details of the product that i want to add into the cart. Since the screen that i come out is using RecyclerView , so i'm confusing how to get all the details of the product that i want.
enter image description here
Adapter code
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView row_image;
TextView title;
TextView description;
public ViewHolder(View v, Context c) {
super(v);
mContext = c;
row_image = (ImageView) v.findViewById(R.id.row_image);
title = (TextView) v.findViewById(R.id.row_title);
description = (TextView) itemView.findViewById(R.id.row_description);
}
}
public CatalogPageAdapter(List<CatalogViewData> dataset) {
mDataset = dataset;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int i) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.catalog_layout, parent, false);
return new ViewHolder(v,parent.getContext());
}
#Override
public void onBindViewHolder(final ViewHolder viewHolder, int i) {
final CatalogViewData fakePageVH = mDataset.get(i);
String points = Double.toString(Double.parseDouble(fakePageVH.getDescription()));
viewHolder.title.setText(fakePageVH.getTitle());
viewHolder.description.setText(points);
String var = fakePageVH.getImage();
new getImage(var, viewHolder).execute();
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "Title: " + fakePageVH.getTitle(), Toast.LENGTH_SHORT).show();
}
});
}
public class getImage extends AsyncTask<String, String, String> {
String imageUrl;
ViewHolder holder;
Bitmap downloadedBitmap;
Bitmap scaled;
public getImage(String url, ViewHolder h){
imageUrl = url;
holder = h;
}
#Override
protected String doInBackground(String... args) {
try {
URL url = new URL(imageUrl);
downloadedBitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
scaled = Bitmap.createScaledBitmap(downloadedBitmap, 150, 100, true);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "done";
}
#Override
protected void onPostExecute(String result) {
holder.row_image.setImageBitmap(scaled);
}
}
#Override
public int getItemCount() {
return mDataset == null ? 0 : mDataset.size();
}
}
I guess the green icon isn't an ImageView otherwise would be a silly question. Add an empty ImageView, place it exactly on your circle. Then add it into your viewholder and use viewHolder.dummyImageView.setOnClickListener.
EDIT
xml:
<ImageView
android:id="#+id/dummyImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"/>
VievHolder:
public ViewHolder(View v, Context c) {
super(v);
dummyImage = (ImageView) v.findViewById(R.id.dummyImageView);
}
OnClickListener:
ImageView dummyImage;
viewHolder.dummyImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "Click!", Toast.LENGTH_SHORT).show();
}
});
I am using listview to populate data coming from the server. This listview will show that data in a fragmentTab. Now the data is parsing fine and logcat is also showing the data. But the data is not being populated by listview. I tried to see the error through debugging but there is no problem. Even the Holder in adapter catches the data but it's not displayed. I don't know what the problem is. I tried the following questions but didn't got the answer.
Android - ListView in Fragment does not showing up
Android - ListView in Fragment does not show
ListView in Fragment Not Displayed
Below is my fragment and the adapter.
Tastemaker Fragment:
public class TasteMakersFragment extends Fragment
{
CommonClass commonTasteMakers;
String tasteMaker_url = CommonClass.url+ URLConstants.Host.URL_ALL_SUGGESTED_TASTEMAKERS;
String user_token = "8aa0dcd5aaf54c8a5aaef1aa242f342f";
ListView suggested_list;
List<SuggestedUserModel> suggestedUsers_list = new ArrayList<>();
SuggestedUsersAdapter mAdapter;
int selectedPosition = 0;
public TasteMakersFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View v = inflater.from(getActivity()).inflate(R.layout.suggested_users_tastemakers, null);
commonTasteMakers = new CommonClass(getActivity().getApplicationContext());
suggested_list = (ListView)v.findViewById(R.id.lst_suggestedUsers);
new GetSuggestedUsers().execute(tasteMaker_url);
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
}
private class GetSuggestedUsers extends AsyncTask< String, Void, Void>
{
private ProgressDialog Dialog = new ProgressDialog(getActivity());
protected void onPreExecute() {
if (suggestedUsers_list.isEmpty())
{
Dialog = ProgressDialog.show(getActivity(),"Please be patient!","Fetching for first time...");
}
}
#Override
protected Void doInBackground(String... params)
{
if (suggestedUsers_list.isEmpty())
{
getSuggestedUsers();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
else{
Log.d("---- Already Fetched --", "---- Already Fetched ----");
return null;
}
}
protected void onPostExecute(Void unused)
{
Dialog.dismiss();
mAdapter = new SuggestedUsersAdapter(getActivity(), suggestedUsers_list);
suggested_list.setAdapter(mAdapter);
suggested_list.setSelection(selectedPosition);
mAdapter.notifyDataSetChanged();
//startMainActivity();
}
}
private List<SuggestedUserModel> getSuggestedUsers()
{
StringRequest postRequest = new StringRequest(Request.Method.POST, tasteMaker_url, new Response.Listener<String>()
{
#Override
public void onResponse(String response)
{
try {
//JSONObject jsonResponse = new JSONObject(response).getJSONObject("form");
JSONObject jsonResponse = new JSONObject(response);
if (jsonResponse.has("data"))
{
JSONObject data = jsonResponse.getJSONObject("data");
String code = jsonResponse.getString("code");
if(code.equals("200"))
{
if(data.has("tasteMakers"))
{
JSONArray tastemakers = data.getJSONArray("tasteMakers");
for (int i =0; i<tastemakers.length(); i++)
{
JSONObject jsnObj = tastemakers.getJSONObject(i);
String id = jsnObj.getString("userId");
String name = jsnObj.getString("name");
String profilePic = jsnObj.getString("imgUrl");
Boolean isFollowed = jsnObj.getBoolean("isFollowed");
suggestedUsers_list.add(new SuggestedUserModel(id,
name,
profilePic,
isFollowed));
Log.d("Names are ----", "size is=" + name +" and their id are: "+id);
}
// Log.d("Adapter list ----", "size is=" + suggestedUsers_list.size());
}
}
else {
Log.d("Error0 Error Error", "response------:" + jsonResponse);
}
}
// Log.d("response222---------","response22222------:"+jsonResponse);
} catch (JSONException e) {
Log.d("-----Stop------", "!!!");
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
}
) {
#Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<>();
// the POST parameters:
params.put("sessionToken", user_token);
return params;
} };
postRequest.setRetryPolicy(new DefaultRetryPolicy(20000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Volley.newRequestQueue(getActivity().getApplicationContext()).add(postRequest);
return suggestedUsers_list;
}
}
Adapter Class:
public class SuggestedUsersAdapter extends BaseAdapter {
Context context;
int count = 1;
private List<SuggestedUserModel> allUsers;
public SuggestedUsersAdapter(FragmentActivity activity, List<SuggestedUserModel> suggestUserModel)
{
Log.d("Custom Adapter called", "" + suggestUserModel.size());
context = activity;
allUsers = suggestUserModel;
//FragmentActivity mActivity = activity;
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return allUsers.size();
// return imageId.length;
}
#Override
public Object getItem(int position) {
return allUsers.get(position);
// return position;
}
#Override
public long getItemId(int position) {
return position;
}
#SuppressLint({"ViewHolder", "InflateParams", "CutPasteId"})
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final mHolder holder;
// int type = getItemViewType(position);
LayoutInflater layoutInflater;
getItemViewType(position);
if (convertView == null)
{
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.suggested_users_tastemaker_cell, null);
holder = new mHolder();
// convertView.setTag(mFeedsListItemViewHolder);
holder.txt_suggestUserName = (TextView) convertView.findViewById(R.id.tv_tasteMakerName);
holder.imgV_userProfile = (ImageView) convertView.findViewById(R.id.imgBtn_tasteMaker_pic);
holder.btnFollow = (Button) convertView.findViewById(R.id.btnFollow_tasteMaker);
holder.btnFollowing = (Button) convertView.findViewById(R.id.btnFollowing);
convertView.setTag(holder);
} else {
holder = (mHolder) convertView.getTag();
}
final SuggestedUserModel suggestUser = allUsers.get(position);
holder.txt_suggestUserName.setText(allUsers.get(position).getSuggested_UserName());
/*if(suggestUser.getSuggested_UserImage().equals(""))
{
Picasso
.with(context)
.load(R.mipmap.ic_launcher)
.transform(new CropSquareTransformationHomePage())
.into(holder.imgV_userProfile);
}
else {
Picasso
.with(context)
.load(suggestUser.getSuggested_UserImage())
.transform(new CropSquareTransformationHomePage())
.into(holder.imgV_userProfile);
}*/
holder.pos = position;
//mFeedsListItemViewHolder.setData(allPersons.get(position));
return convertView;
}
private class mHolder {
TextView txt_suggestUserName;
ImageView imgV_userProfile;
Button btnFollow;
Button btnFollowing;
int pos;
}
}
Note: I already tried declaring listview and assigning adapter in onActivityCreated() method of fragment but no effect.
Any Help will be appreciated.
I am using Listview with ViewHolder, and setText in Textview then display error. How to setText in Textview in Listview? Whenever I click on Like Button then I get the total count for Like but I am not able to setText on TextView for every item. whenever click on selected item then Its TextView Increment by 1 Its Successfully. get strCount is Successfully but how to setText for Selected TextView when Click on Selected Image and My code is,
My Screenshot is which is Listview and set Multiple Items in Listview Like,
My Adapter Class,
public class Adapter1 extends BaseAdapter {
public ArrayList<HashMap<String, String>> arr = null;
Context context = null;
LayoutInflater layoutInflater = null;
HashMap<String, String> getData = new HashMap<String, String>();
String url = null, urlCount = null;
String strId = null, strCount = null;
ViewHolder viewHolder = null;
public Adapter1(Context context, ArrayList<HashMap<String, String>> arr) {
this.context = context;
this.arr = arr;
layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return arr.size();
}
#Override
public Object getItem(int position) {
return arr.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_item, null);
/** initialize ViewHolder */
viewHolder = new ViewHolder();
/** Initialize Widgets */
/** Imageview */
viewHolder.img = (ImageView) convertView.findViewById(R.id.img);
/** TextView */
viewHolder.txtId = (TextView) convertView.findViewById(R.id.txtId);
viewHolder.txt = (TextView) convertView.findViewById(R.id.txt);
getData = arr.get(position);
viewHolder.txtId.setText(getData.get(Fragment1.TAG_ID));
viewHolder.img.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
strId = arr.get(position).get(Fragment1.TAG_ID);
System.out.println("!!!!!!!!!! strId======"+ strId);
url = "http://example.com/createpost.php?id="+ strId + "&user_id="+ myDetail.getUserId();
new sendData().execute();
}
});
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
return convertView;
}
/** ViewHolder Class */
#SuppressLint("NewApi")
public class ViewHolder {
ImageView img = null,
TextView txtId = null
txt = null;
}
public class sendData extends AsyncTask<Void, Void, Void> {
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
ServiceHandler sh = new ServiceHandler();
String jsonStr = sh.makeServiceCall(urlLike, ServiceHandler.GET);
System.out.println("!!!!!!!!!!!!!!!jsonStr in Do in===" + jsonStr);
Log.d("Response : Like", ">" + jsonStr);
return null;
}
protected void onPostExecute(Void result) {
super.onPostExecute(result);
urlCount = "http://example.com/getalldata.php?id="+ strId;
new getCountData().execute();
};
}
/** Count the Total Like for Selected Items. */
private class getCountData extends AsyncTask<Void, Void, Void> {
JSONObject jsonobject;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
jsonobject = JSONFunctions.getJSONfromURL(urlCount);
try {
strCount = jsonobject.getString("countdata");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
System.out.println("!!!!!!!!strCount====" + strCount);
viewHolder.txt.setText(String.valueOf(strCount));
}
}
}
Thanks in advance.
In onClick() function you have to get instance of textview and pass it to AsyncTask
// if text and img have same parent the you can find textview like this is
TextView tv =(TextView)v.getParent().findViewById(R.id.txt);
// if not then apply call getParent() function multiple time as per your layout
new sendData(tv).execute();
//Create constructor in sendData
public class sendData extends AsyncTask {
private TextView tv;
public sendData(TextView v){
tv=v;
}
...
protected void onPostExecute(Void result) {
super.onPostExecute(result);
urlCount = "http://example.com/getalldata.php?id="
+ strId;
new getCountData(tv).execute();
};
}
private class getCountData extends AsyncTask {
private TextView v;
public sendData(TextView v){
tv=v;
}
....
// in onPostExecute use
tv.setText(String.valueOf(strCount));
}
Edit: you can get correct position by tag position to view and get it inside onClick
// add this line before return
viewHolder.img.setTag(position);
// get position inside onClick()
int position =(Integer)v.getTag();
Hello stackoverflow I'm trying to develop an application like Gallery for a particular directory of SD Card. For example I have took WhatsApp Images directory, here is my code
public class WhatsAppInboxImagesActivity extends Activity {
private ImageAdapter imageAdapter;
private ProgressDialog pd;
ArrayList<String> f = null;
File[] listFile;
Button btnDelete;
HashSet<String> selectedFile = null;
GridView imagegrid;
AlertDialog alertDialog = null;
static
{
File noFile = new File(Environment.getExternalStorageDirectory().getPath(), "/WhatsApp/Media/WhatsApp Images/Sent/.nomedia");
if(noFile.exists())
{
noFile.delete();
}
}//End of static block
private void initialize()
{
imagegrid = (GridView) findViewById(R.id.PhoneImageGrid);
btnDelete = (Button) findViewById(R.id.btnDeleteImg);
selectedFile = new HashSet<String>();// list of file paths boolean checked
f = new ArrayList<String>();// list of file paths
}//End of initialize method
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_whats_app_images_inbox);
this.initialize();
getFromSdcard();
imageAdapter = new ImageAdapter();
/*
* Performing time consuming actions
*/
new AsyncTask<Void, Void, Void>()
{
#Override
protected void onPreExecute()
{
pd = ProgressDialog.show(WhatsAppInboxImagesActivity.this,
"Loading..", "Please Wait", true, false);
}// End of onPreExecute method
#Override
protected Void doInBackground(Void... params)
{
return null;
}// End of doInBackground method
#Override
protected void onPostExecute(Void result)
{
imagegrid.setAdapter(imageAdapter);
imageAdapter.notifyDataSetChanged();
pd.dismiss();
}
}.execute((Void[]) null);
btnDelete.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
new AsyncTask<Void, Void, Void>()
{
#Override
protected void onPreExecute()
{
pd = ProgressDialog.show(WhatsAppInboxImagesActivity.this,
"Loading..", "Please Wait", true, false);
}// End of onPreExecute method
#Override
protected Void doInBackground(Void... params)
{
#SuppressWarnings("rawtypes")
Iterator iterator = selectedFile.iterator();
while (iterator.hasNext())
{
new File(iterator.next().toString()).delete();
}//End of while loop
return null;
}// End of doInBackground method
#Override
protected void onPostExecute(Void result)
{
pd.dismiss();
}//End of onPostExecute method
}.execute((Void[]) null);
finish();
startActivity(getIntent());
}//End of onClick method
});//End of btnDelete anonymous class
}//End of onCreate method
public void getFromSdcard()
{
File file = new File( Environment.getExternalStorageDirectory().getPath(), "/WhatsApp/Media/WhatsApp Images");
if (file.isDirectory())
{
listFile = file.listFiles();
for (int i = 0; i < listFile.length; i++)
{
if(listFile[i].isDirectory())
{
continue;
}
f.add(listFile[i].getAbsolutePath());
}//End of for loop
}//End of if condition
}//End of getFromSdcard method
public class ImageAdapter extends BaseAdapter
{
private LayoutInflater mInflater;
public ImageAdapter()
{
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}//End of ImageAdapter constructor
public int getCount()
{
return f.size();
}//End of getCount method
public Object getItem(int position)
{
return position;
}//End of getItem method
public long getItemId(int position)
{
return position;
}//End of getItemId method
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
if (convertView == null)
{
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.galleryitem, null);
holder.imageview = (ImageView) convertView.findViewById(R.id.thumbImage);
holder.checkbox = (CheckBox) convertView.findViewById(R.id.itemCheckBox);
convertView.setTag(holder);
}//End of if condition
else
{
holder = (ViewHolder) convertView.getTag();
}//End of else
BitmapFactory.Options options = new BitmapFactory.Options();
// will results in a much smaller image than the original
options.inSampleSize = 4;
// don't ever use a path to /sdcard like this, but I'm sure you have a sane way to do that
// in this case nebulae.jpg is a 19MB 8000x3874px image
final Bitmap b = BitmapFactory.decodeFile(f.get(position), options);
holder.imageview.setImageBitmap(b);
return convertView;
}//End of getView method
}//End of ImageAdapter instance inner class
class ViewHolder
{
ImageView imageview;
CheckBox checkbox;
int id;
}//End of ViewHolder instance inner class
}//End of WhatsAppImagesActivity
So far every thing is good, but the problem is images gets loaded all at one shot, so scrolling is very slow and some times OutOfMemoryException occurs though decoded file with BitMapFactory, can any one help me to solve this puzzle please.
Edit:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.list_layout, null);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.text = (TextView) view.findViewById(R.id.label);
viewHolder.text.setTextColor(Color.BLACK);
viewHolder.image = (ImageView) view.findViewById(R.id.image);
viewHolder.image.setVisibility(View.GONE);
viewHolder.cb = (CheckBox) view.findViewById(R.id.item_check_box);
viewHolder.pb = (ProgressBar) view.findViewById(R.id.progressBar);
view.setTag(viewHolder);
} else {
view = convertView;
}
final int pos = position;
ViewHolder holder = (ViewHolder) view.getTag();
holder.text.setText(list.get(position).getName());
holder.image.setTag(list.get(position).getURL());
holder.image.setId(position);
PbAndImage pb_and_image = new PbAndImage();
pb_and_image.setImg(holder.image);
pb_and_image.setPb(holder.pb);
new DownloadImageTask().execute(pb_and_image);
return view;
}
Thanks.
You should use Lazy loading
visit this tutorial for lazy loading here Its very easy.
Let me know if you have any issue on it.
Edit
public class MainActivity extends ListActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String path = Environment.getExternalStorageDirectory()+"/WhatsApp/Media/WhatsApp Images";
final List<Model> list = new ArrayList<Model>();
final File file = new File(path);
final ProgressDialog dialog = ProgressDialog.show(MainActivity.this, "",
"Please Wait...", true);
new Thread(new Runnable() {
public void run() {
dismissDialog(dialog);
for(File fileChild : file.listFiles()){
list.add(get(fileChild.getName(), fileChild.getAbsolutePath()));
}
}
}).start();
ArrayAdapter<Model> adapter = new MyCustomArrayAdapter(this, list);
setListAdapter(adapter);
}
public void dismissDialog(final ProgressDialog dialog) {
runOnUiThread(new Runnable() {
public void run() {
dialog.dismiss();
}
});
}
private Model get(String s, String url) {
return new Model(s, url);
}
}
This could help: UniversalImageLoader
And that's what I did:
/**
* UniversalImageLoader載入遠端圖片,僅使用RAM做圖片快取 (Load pic & use RAM as cache)
* #param android.content.Context
* #author https://github.com/nostra13/Android-Universal-Image-Loader
* #param android.widget.ImageView - 顯示圖片的元件 (your image container)
* #param int - 載入失敗的預設圖片Resource ID (default pic if load fail, I put default pic in resources folder)
* #param java.lang.String - 檔案URL (pic URL or path)
*/
public static void imageLoaderMemoryCache(Context context, final ImageView img, final int failImgID, String url)
{
ImageLoader imageLoader=ImageLoader.getInstance();
ImageLoaderConfiguration config=new ImageLoaderConfiguration.Builder(context)
.memoryCacheExtraOptions(100, 100) // max width, max height
.threadPoolSize(5)
.threadPriority(Thread.NORM_PRIORITY+1)
.denyCacheImageMultipleSizesInMemory()
.tasksProcessingOrder(QueueProcessingType.FIFO)
.defaultDisplayImageOptions(DisplayImageOptions.createSimple())
.enableLogging()
.build();
imageLoader.init(config);
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.cover_sample)
.cacheInMemory(true)
.imageScaleType(ImageScaleType.IN_SAMPLE_INT)
.bitmapConfig(Bitmap.Config.RGB_565)
.delayBeforeLoading(1)
.displayer(new FadeInBitmapDisplayer(500))
.build();
imageLoader.displayImage(url, img, options, new ImageLoadingListener()
{
#Override
public void onLoadingStarted(String url, View view)
{img.setImageResource(failImgID);} //一開始先顯示預設圖 (display default pic at first)
#Override
public void onLoadingFailed(String url, View view, FailReason failReason)
{img.setImageResource(failImgID);}
#Override
public void onLoadingComplete(String url, View view, Bitmap loadedImage)
{}
#Override
public void onLoadingCancelled(String url, View view)
{}
});
}
Usage (ListView)
public View getView(...)
{
vh.imgCover=(ImageView)convertView.findViewById(R.id.imgCover);
//...
// some stuff
//...
Util.imageLoaderDiskCache(getActivity(), vh.imgCover, R.drawable.cover_sample, "(pic file path)");
}
Hope it helps~
I am making a sectional listview in which to section first is pending request list and second is already friend there are two button accept and reject in first section of list view.
When I click on accept hit server and change stautus and now my List should be update and first section accepted list should showing in friendlist in second section of listview.
I am using following code:-
public class EntryAdapter extends ArrayAdapter<Item> {
private Context context;
private List<Item> items;
private LayoutInflater objlayoutinflator;
private PostJobImageLoader objimageLoader;
private ConnectionFriendListModle objmodle=null;
public EntryAdapter(Context context,List<Item> items) {
super(context, 0, items);
this.context = context;
this.items = items;
objlayoutinflator = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
objimageLoader = new PostJobImageLoader(context.getApplicationContext());
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View myview = convertView;
final Item objitem = items.get(position);
if (objitem != null) {
if (objitem.isSection()) {
SectionItem objsection = (SectionItem) objitem;
myview = objlayoutinflator.inflate(R.layout.listviewsection,
null);
myview.setOnClickListener(null);
myview.setOnLongClickListener(null);
myview.setLongClickable(false);
final TextView sectionView = (TextView) myview
.findViewById(R.id.txtsection);
sectionView.setText(objsection.getTitle());
} else {
objmodle = (ConnectionFriendListModle) objitem;
myview = objlayoutinflator.inflate(R.layout.connectionlistrow,
null);
final TextView title = (TextView) myview
.findViewById(R.id.jobtitleinjobbidalert);
final TextView subtitle = (TextView) myview
.findViewById(R.id.jobsubtitle);
final ImageView objimageview = (ImageView) myview
.findViewById(R.id.user_image);
final Button objaccept = (Button) myview
.findViewById(R.id.btnaccept);
final Button objreject = (Button) myview
.findViewById(R.id.btnreject);
if (objmodle.getStatus().equalsIgnoreCase("pending")) {
objaccept.setVisibility(View.VISIBLE);
objreject.setVisibility(View.VISIBLE);
title.setText(objmodle.getUsername());
subtitle.setText(objmodle.getName());
String url = objmodle.getPicture();
objimageLoader.DisplayImage(AppConstants.IMAGE_BASE_URL
+ url, objimageview);
} else {
objaccept.setVisibility(View.INVISIBLE);
objreject.setVisibility(View.INVISIBLE);
title.setText(objmodle.getUsername());
subtitle.setText(objmodle.getName());
String url = objmodle.getPicture();
objimageLoader.DisplayImage(AppConstants.IMAGE_BASE_URL+url, objimageview);
}
objaccept.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new AcceptFriendRequest().execute(objmodle.getId(),"accepted");
}
});
objreject.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
}
});
}
}
return myview;
}
private class AcceptFriendRequest extends AsyncTask<String,Void,String>
{
ProgressDialog objprogress = new ProgressDialog(EntryAdapter.this.context);
AppRequestHandler objApprequest = new AppRequestHandler();
String objresponce="";
#Override
protected void onPreExecute() {
objprogress.setMessage("Please Wait While Loading...");
objprogress.show();
}
#Override
protected String doInBackground(String... params) {
objresponce = objApprequest.acceptRequest(params[0],params[1]);
return objresponce;
}
#Override
protected void onPostExecute(String result) {
if(objprogress.isShowing())
{
objprogress.dismiss();
}
if(result.equals("0"))
{
SharedPreferences myPrefs = EntryAdapter.this.context.getSharedPreferences(
AppConstants.MYPREF, EntryAdapter.this.context.MODE_WORLD_READABLE);
String userid = myPrefs.getString(AppConstants.USER_ID, "");
//but when controll reach this line not execute this asynctask and niether update listview
new GetAllConnectionDetail().equals("86");
}
}
}
private class GetAllConnectionDetail extends AsyncTask<String,Void,List<Item>>
{
ProgressDialog objprogress = new ProgressDialog(EntryAdapter.this.context);
AppRequestHandler objApprequest = new AppRequestHandler();
List<Item> objlistitem=null;
#Override
protected void onPreExecute() {
objprogress.setMessage("Please Wait While Loading...");
objprogress.show();
}
#Override
protected List<Item> doInBackground(String... params) {
objlistitem = objApprequest.connectionDetails(params[0]);
return objlistitem;
}
#Override
protected void onPostExecute(List<Item> result) {
if(objprogress.isShowing())
{
objprogress.dismiss();
}
items.clear();
items.addAll(result);
notifyDataSetChanged();
}
}
}
Is am going right way or wrong please any one help me why it is not working...
You have to start your GetAllConnectionDetail task by calling its execute method, seems you don't do that.