Adapter does not update the NetworkImage in Recycler View - android

I am using recycler view and in the recycler view I have networkImage. I am trying to load image from gallery as follows, but it does not load it, it still uses the default image. I have tested and validated url is valid. I wonder what I am missing. Initially, I have an image is loaded, and now I am trying to update it.
ItemData Class
public class ItemData {
private String url;
public ItemData(String url){
this.url = url;
}
String getUrl(){return url;}
void setUrl(String t){url = t;}
}
In the Activity
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == Activity.RESULT_OK && data != null && data.getData() != null) {
Uri filePath = data.getData();
Update(getRealPathFromURI(filePath));
}
}
private void Update(String path)
{
// update the existing view
listImages.set(0, new ItemData(path));
mAdapter.notifyDataSetChanged();
}
Adapter
public void onBindViewHolder(ViewHolder viewHolder, int pos) {
int position = pos;
ImageUtil.setPic(viewHolder.imgViewIcon, itemsData.get(position).getUrl());
}
ImageUtil Class
public static void setPic(NetworkImageView imageView, String picturePath) {
// Get the dimensions of the View
int targetW = imageView.getWidth();
int targetH = imageView.getHeight();
if(targetW != 0 || targetH != 0)
{
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(picturePath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW / targetW, photoH / targetH); // zero division olasiligi...
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
//bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(picturePath, bmOptions);
Matrix matrix = new Matrix();
matrix.postRotate(getImageOrientation(picturePath));
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), matrix, true);
imageView.setImageBitmap(rotatedBitmap);
}
}
Here is the bitmap screenshot, as seen below, it is not null.

Here on GitHub I put code with the entire flow implemented.
Main problem is the usage of NetworkImageView for rendering local images.
You can extend NetworkImageView as follows and use method setLocalImageBitmap in case you need to load local images into your view.
public class MyImageView extends NetworkImageView {
private Bitmap mLocalBitmap;
private boolean mShowLocal;
public MyImageView(Context context) {
this(context, null);
}
public MyImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setLocalImageBitmap(Bitmap bitmap) {
if (bitmap != null) {
mShowLocal = true;
}
this.mLocalBitmap = bitmap;
requestLayout();
}
#Override
public void setImageUrl(String url, ImageLoader imageLoader) {
mShowLocal = false;
super.setImageUrl(url, imageLoader);
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (mShowLocal) {
setImageBitmap(mLocalBitmap);
}
}
}

You should set the new ArrayList in the adapter.
Make a method in BaseAdapter
In Activity,
listImages.add(new ItemData(path));
adapter.setNewList(your arraylist);
adapter.notifyDataSetChanged();
And In Adapter,
public void setNewList(Arraylist<String> newlist)
{
this.list=newlist.
}
It will do your all work.

Related

Universal Image Loader: Get Original height and width onClick

I use Universal Image Loader to load images in a Jsoup parsed html. The <img> tags doesn't have a static position, they can appear anywhere in the Html element. And since I want them to appear in the positions where the <img> are, I can't give them an image view.
This is the class that I'm using to load the images
public class UILImageGetter implements Html.ImageGetter, View.OnClickListener{
Context c;
TextView conatiner;
UrlImageDownloader urlDrawable;
public UILImageGetter(View textView, Context context) {
this.c = context;
this.conatiner = (TextView) textView;
}
#Override
public Drawable getDrawable(String source) {
urlDrawable = new UrlImageDownloader(c.getResources(), source);
if (Build.VERSION.SDK_INT >= 21) {
urlDrawable.mDrawable = c.getResources().getDrawable(R.drawable.default_thumb,null);
} else {
urlDrawable.mDrawable = c.getResources().getDrawable(R.drawable.default_thumb);
}
ImageLoader.getInstance().loadImage(source, new SimpleListener(urlDrawable));
return urlDrawable;
}
#Override
public void onClick(View v) {
}
private class SimpleListener extends SimpleImageLoadingListener {
UrlImageDownloader mUrlImageDownloader;
public SimpleListener(UrlImageDownloader downloader) {
super();
mUrlImageDownloader= downloader;
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
int width = loadedImage.getWidth();
int height = loadedImage.getHeight();
int newWidth = width;
int newHeight = height;
if (width > conatiner.getWidth()) {
newWidth = conatiner.getWidth();
newHeight = (newWidth * height) / width;
}
if (view != null) {
view.getLayoutParams().width = newWidth;
view.getLayoutParams().height = newHeight;
}
Drawable result = new BitmapDrawable(c.getResources(), loadedImage);
result.setBounds(0, 0, newWidth, newHeight);
mUrlImageDownloader.setBounds(0, 0, newWidth, newHeight);
mUrlImageDownloader.mDrawable = result;
conatiner.setHeight((conatiner.getHeight() + result.getIntrinsicHeight()));
//conatiner.invalidate();
}
}
private class UrlImageDownloader extends BitmapDrawable {
public Drawable mDrawable;
public UrlImageDownloader(Resources resources, String filepath) {
super(resources, filepath);
mDrawable = new BitmapDrawable(resources, filepath);
}
#Override
public void draw(Canvas canvas) {
if (mDrawable != null) {
mDrawable.draw(canvas);
}
}
}
}
My problem is how to set OnclickListener on the images and get them to display (in a dialog) the original height and width when clicked.

Swipe large images with no delay

I developed a gallery app with swipe images function (drag to the left/right and a new full screen image is appear).
The problem is that I did not succeed to overcome the small delay of large images until they appear (whatsapp images - no problem, with camera images it is not smooth like in the build-in gallery app).
I tried several method to re size/decode the image but still there is a delay.
My code:
FullScreenImageAdapter.java
public class FullScreenImageAdapter extends PagerAdapter {
private Activity _activity;
private ArrayList<String> _imagePaths;
private LayoutInflater inflater;
private final int IMAGE_MAX_SIZE = 800;
// constructor
public FullScreenImageAdapter(Activity activity,
ArrayList<String> imagePaths) {
this._activity = activity;
this._imagePaths = imagePaths;
}
#Override
public int getCount() {
return this._imagePaths.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((RelativeLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView imgDisplay;
inflater = (LayoutInflater) _activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View viewLayout = inflater.inflate(R.layout.layout_fullscreen_image, container,
false);
imgDisplay = (ImageView) viewLayout.findViewById(R.id.imgDisplay);
Bitmap bitmap = decodeSampledBitmapFromPath(_imagePaths.get(position),1000,1000);
imgDisplay.setImageBitmap(bitmap);
((ViewPager) container).addView(viewLayout);
return viewLayout;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((RelativeLayout) object);
}
public static Bitmap decodeSampledBitmapFromPath(String path, int reqWidth,
int reqHeight) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
Bitmap bmp = BitmapFactory.decodeFile(path, options);
return bmp;
}
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
}
return inSampleSize;
}
}
FullScreenViewActivity.java
public class FullScreenViewActivity extends Activity{
private FullScreenImageAdapter adapter;
private ViewPager viewPager;
int selectedFilePosition;
String imageFolder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_full_screen_view);
//geting the selected image from the intent
/* Getting ImageURI from Gallery from Main Activity */
Uri selectedImgUri = getIntent().getData();
if (selectedImgUri!=null) {
imageFolder = getRealPathFromURI(this, selectedImgUri);
}
viewPager = (ViewPager) findViewById(R.id.pager);
adapter = new FullScreenImageAdapter(FullScreenViewActivity.this, getFilePaths(imageFolder));
viewPager.setAdapter(adapter);
// displaying selected image first
viewPager.setCurrentItem(selectedFilePosition);
}
// Reading file paths from SDCard
public ArrayList<String> getFilePaths(String selectedFilePath) {
ArrayList<String> filePaths = new ArrayList<String>();
File file = new File(selectedFilePath);
File directory = file.getParentFile();
// check for directory
if (directory.isDirectory()) {
// getting list of file paths
File[] listFiles = directory.listFiles();
// Check for count
if (listFiles.length > 0) {
// loop through all files
for (int i = 0; i < listFiles.length; i++) {
// get file path
String filePath = listFiles[i].getAbsolutePath();
//set position if this is the required image to show
if (filePath.equals(selectedFilePath)) {
selectedFilePosition = i;
// Add image path to array list
filePaths.add(filePath);
}
}
}
}
return filePaths;
}
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
}
To improve performance you need another thread to load it async. Here are the third party libraries (Picasso, Glide) that you can use when working with large images.
I also would use Picasso for loading Images into the ImageView. Picasso caches the Image if it is Loaded once. To preload some elements you can use the Consumner/Producer Pattern! Example here.

Xamarin Android drawn bitmaps in grid view causes slow and choppy scrolling

I am building an Android application, using the Xamarin framework, that displays profile photos for users. The photos may either be drawn within an oval, like you'd see on any social network, or in a rectangle based on what screen the user is on. The images I am drawing are downloaded from a web service and may be any size. Thus I must scale the photos, fix any rotation issues, and then draw them either in a rectangle or an oval.
The entire process I have works fine, but the problem I have is when I load several of the profile views into a grid view, then the performance of the scroll event becomes very choppy and slow. I also get warnings in the console saying that 30 frames have been skipped, and that I may be doing to much on the main thread.
To try and fix the issue I've pushed the loading of the images to a background task, and that is also working great. However, the actual onDraw event is drawn on the main thread as it's drawn by the OS.
I've tracked down the issue to the canvas.drawBitmap() function call. When I comment out this command then the slow scrolling issues goes away, and I no longer get the warnings in the logs. This tells me that my process is efficient enough without the draw command, but when I add the draw command I start to get performance issues.
Does anyone know how I can optimize the drawing process so that I can achieve smooth scrolling? My code is below.
This is my grid view adapter class that loads the profile photo views...
namespace AndroidApp
{
public class GridViewAdapter : ArrayAdapter<UserContact>
{
private Activity ParentActivity;
#region Interface
public interface GridViewAdapterCallback
{
void DidSelectRow(Conversation conversation);
}
#endregion
#region Initialization
private int LayoutResourceId;
private List<UserContact> Data = null;
public GridViewAdapterCallback callback;
public GridViewAdapter (Context context, int layoutResourceId, List<UserContact> data, Activity parentActivity) : base (context, layoutResourceId, data)
{
this.LayoutResourceId = layoutResourceId;
this.Data = data;
this.ParentActivity = parentActivity;
}
public void SetData (List<UserContact> data)
{
this.Data = data;
}
#endregion
#region List Delegates
public override Android.Views.View GetView (int position, Android.Views.View convertView, Android.Views.ViewGroup parent)
{
if (convertView == null)
{
LayoutInflater inflater = LayoutInflater.From (this.Context);
convertView = inflater.Inflate(this.LayoutResourceId, parent, false);
}
UserContact row = this.Data[position];
this.SetContactToGridItem (convertView, row);
return convertView;
}
#endregion
#region Setters
private void SetContactToGridItem (Android.Views.View view, UserContact contact)
{
// get view references
ProfileImageView imageView = view.FindViewById(Resource.Id.profileImageView).JavaCast<ProfileImageView>();
imageView.ProfileImageViewStyle = ProfileImageViewStyle.Square;
imageView.ResetImage ();
imageView.SetContact (contact, this.ParentActivity);
TextView textView = (TextView)view.FindViewById(Resource.Id.textView);
textView.SetText (contact.GetFullName (), TextView.BufferType.Normal);
}
#endregion
}
}
This is my main profile view class...
namespace AndroidApp
{
public enum ProfileImageViewColor
{
Default = 0,
White = 1
};
public enum ProfileImageViewStyle
{
Default = 0,
Square = 1
};
public class ProfileImageView : ImageView
{
public ProfileImageViewColor ProfileImageViewColor { get; set; }
public ProfileImageViewStyle ProfileImageViewStyle { get; set; }
private User User { get; set; }
private UserContact Contact { get; set; }
Bitmap Bitmap;
private Activity Activity { get; set; }
public ProfileImageView (System.IntPtr intPtr, Android.Runtime.JniHandleOwnership owner) : base (intPtr, owner)
{
Initialize ();
}
public ProfileImageView (Context context) : base (context)
{
Initialize ();
}
public ProfileImageView (Context context, IAttributeSet attrs) : base (context, attrs)
{
Initialize ();
}
public ProfileImageView (Context context, IAttributeSet attrs, int defStyle) : base (context, attrs, defStyle)
{
Initialize ();
}
void Initialize ()
{
this.ProfileImageViewColor = ProfileImageViewColor.Default;
this.ProfileImageViewStyle = ProfileImageViewStyle.Default;
this.SetScaleType (ScaleType.FitCenter);
this.CropToPadding = true;
}
#region Setters
public void SetUser (User user, Activity activity)
{
this.User = user;
this.Activity = activity;
if (this.User != null)
{
byte[] imageData = this.User.GetProfilePhoto ();
if (imageData != null)
{
this.SetImageData (this.User.GetProfilePhotoPath (), imageData);
}
else
{
UserBusiness.GetUserPhoto (this.User, (Shared.Error error, User usr) => {
activity.RunOnUiThread (() => {
this.SetImageData (this.User.GetProfilePhotoPath (), this.User.GetProfilePhoto ());
});
});
}
}
}
public void SetContact (UserContact contact, Activity activity)
{
this.Contact = contact;
this.Activity = activity;
if (this.Contact != null)
{
byte[] imageData = this.Contact.GetProfilePhoto();
if (imageData != null)
{
this.SetImageData (this.Contact.GetProfilePhotoPath (), imageData);
}
else
{
UserContactPhotoDownloadManager.CreateManager ().DownloadProfilePhoto (contact, (Shared.Error error, UserContact userContact) => {
activity.RunOnUiThread (() => {
this.SetImageData (this.Contact.GetProfilePhotoPath (), this.Contact.GetProfilePhoto ());
});
});
}
}
}
public override void SetImageBitmap (Bitmap bitmap)
{
if (bitmap == null)
{
this.SetImageResource (this.GetDefaultProfileImageID ());
}
else
{
ProfileImageDrawable drawable = new ProfileImageDrawable (bitmap, this.Width, this.Height, this.ProfileImageViewStyle);
this.SetImageDrawable (drawable);
}
}
public void ResetImage ()
{
if (this.Bitmap != null)
this.Bitmap.Recycle ();
this.SetImageBitmap (null);
}
#endregion
#region Private
private void SetImageData (byte[] imageData)
{
if (this.Bitmap != null)
{
this.Bitmap.Recycle ();
this.Bitmap = null;
}
if (imageData == null)
{
this.SetImageResource (this.GetDefaultProfileImageID ());
}
else
{
this.Bitmap = BitmapFactory.DecodeByteArray (imageData, 0, imageData.Length);
ProfileImageDrawable drawable = new ProfileImageDrawable (this.Bitmap, this.Width, this.Height, this.ProfileImageViewStyle);
this.SetImageDrawable (drawable);
}
}
private void SetImageData (string filePath, byte[] imageData)
{
if (this.Bitmap != null)
{
this.Bitmap.Recycle ();
this.Bitmap = null;
}
if (imageData == null)
{
this.SetImageResource (this.GetDefaultProfileImageID ());
}
else
{
this.SetImageAsync (filePath);
}
}
private void SetImageAsync (string filePath)
{
ImageDrawTask task = new ImageDrawTask (filePath, this, (Drawable drawable) => {
this.Activity.RunOnUiThread (() => {
this.SetImageDrawable (drawable);
});
});
task.Execute ();
}
private int GetDefaultProfileImageID ()
{
if (this.ProfileImageViewColor == ProfileImageViewColor.Default)
return (int)typeof (Resource.Drawable).GetField ("profile_image_placeholder").GetValue (null);
else
return (int)typeof (Resource.Drawable).GetField ("profile_image_placeholder_white").GetValue (null);
}
#endregion
}
public class ImageDrawTask: AsyncTask {
public delegate void ImageDrawTaskCompletion (Drawable drawable);
private string FilePath;
private ProfileImageView ImageView;
private ImageDrawTaskCompletion Completion;
public ImageDrawTask (string filePath, ProfileImageView imageView, ImageDrawTaskCompletion completion)
{
this.FilePath = filePath;
this.ImageView = imageView;
this.Completion = completion;
}
protected override void OnPreExecute()
{
}
protected override Java.Lang.Object DoInBackground(params Java.Lang.Object[] #params)
{
Bitmap bitmap = ImageUtilities.FixRotation (this.FilePath);
ProfileImageDrawable drawable = new ProfileImageDrawable (bitmap, this.ImageView.Width, this.ImageView.Height, this.ImageView.ProfileImageViewStyle);
Completion (drawable);
return null;
}
protected override void OnPostExecute(Java.Lang.Object result)
{
}
}
}
And finally here is my drawable class...
namespace AndroidApp
{
public class ProfileImageDrawable : Drawable
{
Bitmap Bitmap;
ProfileImageViewStyle Style;
int Width;
int Height;
private RectF DrawFrame;
public ProfileImageDrawable (Bitmap bmp, int width, int height, ProfileImageViewStyle style)
{
this.Bitmap = bmp;
this.Style = style;
this.DrawFrame = new RectF ();
this.Width = width;
this.Height = height;
}
public override void Draw (Canvas canvas)
{
if (this.Style == ProfileImageViewStyle.Square)
{
canvas.DrawBitmap (this.Bitmap, this.GetMatrix (this.Bitmap, this.Width, this.Height), null);
}
else
{
BitmapShader bmpShader = new BitmapShader (this.Bitmap, Shader.TileMode.Clamp, Shader.TileMode.Clamp);
bmpShader.SetLocalMatrix (this.GetMatrix (this.Bitmap, this.Width, this.Height));
Paint paint = new Paint () { AntiAlias = true, Dither = true };
paint.SetShader (bmpShader);
canvas.DrawOval (this.DrawFrame, paint);
}
}
protected override void OnBoundsChange (Rect bounds)
{
base.OnBoundsChange (bounds);
this.DrawFrame.Set (0, 0, bounds.Width (), bounds.Height ());
}
public override int IntrinsicWidth {
get {
return this.Width;
}
}
public override int IntrinsicHeight {
get {
return this.Height;
}
}
public override void SetAlpha (int alpha)
{
}
public override int Opacity {
get {
return (int)Format.Opaque;
}
}
public override void SetColorFilter (ColorFilter cf)
{
}
private Matrix GetMatrix (Bitmap bmp, int width, int height)
{
Matrix mtx = new Matrix ();
float scaleWidth = ((float) width) / bmp.Width;
float scaleHeight = ((float) height) / bmp.Height;
float newWidth = 0;
float newHeight = 0;
if (scaleWidth > scaleHeight)
{
mtx.PostScale (scaleWidth, scaleWidth);
newWidth = scaleWidth * bmp.Width;
newHeight = scaleWidth * bmp.Height;
}
else
{
mtx.PostScale (scaleHeight, scaleHeight);
newWidth = scaleHeight * bmp.Width;
newHeight = scaleHeight * bmp.Height;
}
mtx.PostTranslate ((width - newWidth) / 2, (height - newHeight) / 2);
return mtx;
}
}
}

ImageView visible in ListView on wrong position when scrolling fast, using AQuery

I got the following getView in listView's adapter:
#Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
View view = convertView;
if (view == null) {
view = LayoutInflater.from(context).inflate(R.layout.item_message, null);
}
final Message msg = getItem(position);
final AQuery aq = new AQuery(view);
aq.id(R.id.message_baloon).background(myMessage ? R.drawable.chat_message_own : R.drawable.chat_message_other);
// shared image
if (msg.getPhotos() != null && msg.getPhotos().size() != 0) {
aq.id(R.id.sent_photo).visible();
aq.image(msg.getPhotos().get(0).getUrl(), true, true, 540, R.drawable.room_details_gallery_placeholder);
aq.clicked(new View.OnClickListener() {
#Override
public void onClick(View v) {
//show fullsecreen photo
}
});
} else {
aq.id(R.id.sent_photo).gone();
}
if (msg.getText() == null || msg.getText().length() == 0) {
aq.id(R.id.message).gone();
} else {
aq.id(R.id.message).text(msg.getText());
aq.id(R.id.message).visible();
}
return view;
}
The method is actually a longer but this part contains everything related to that ImageView. So, as the title states, when scrolling really fast the ImageView, with "R.id.sent_photo", is visible for a position which doesn't have a photo and not for a fraction of a second, it remains visible (that's AndroidQuery library that I'm using).
Thank you!
I was got same problem so, i had used following methods in my custom adapter, i got solution.
Add following methods inside your ListViewItemsAdapter:
#Override
public int getCount() {
return alUpgradeTour.size();
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public int getViewTypeCount() {
return getCount();
}
Try it, you will also get solution.
Try this, it seems that AndroidQuery library don't put placeholder image before download
if (msg.getPhotos() != null && msg.getPhotos().size() != 0) {
aq.id(R.id.sent_photo).visible();
aq.id(R.id.sent_photo).setImageResource(R.drawable.room_details_gallery_placeholder);
aq.image(msg.getPhotos().get(0).getUrl(), true, true, 540, R.drawable.room_details_gallery_placeholder);
aq.clicked(new View.OnClickListener() {
#Override
public void onClick(View v) {
//show fullsecreen photo
}
});
} else {
aq.id(R.id.sent_photo).gone();
}
The solution is not using memory cache:
aq.image(msg.getPhotos().get(0).getUrl(), false, true, 540, R.drawable.room_details_gallery_placeholder);
AndroidQuery somewhere along that image function does the following
public static void async(Activity act, Context context, ImageView iv, String url, boolean memCache, boolean fileCache, int targetWidth, int fallbackId, Bitmap preset, int animation, float ratio, float anchor, Object progress, AccountHandle ah, int policy, int round, HttpHost proxy, String networkUrl){
Bitmap bm = null;
if(memCache){
bm = memGet(url, targetWidth, round);
}
if(bm != null){
iv.setTag(AQuery.TAG_URL, url);
Common.showProgress(progress, url, false);
setBmAnimate(iv, bm, preset, fallbackId, animation, ratio, anchor, AjaxStatus.MEMORY);
}else{
Bit...
So if it got a bitmap from memCache it calls setBmAnimate
private static void setBmAnimate(ImageView iv, Bitmap bm, Bitmap preset, int fallback, int animation, float ratio, float anchor, int source){
bm = filter(iv, bm, fallback);...
And filter is:
private static Bitmap filter(View iv, Bitmap bm, int fallback){
//ignore 1x1 pixels
if(bm != null && bm.getWidth() == 1 && bm.getHeight() == 1 && bm != empty){
bm = null;
}
if(bm != null){
iv.setVisibility(View.VISIBLE);
}else if(fallback == AQuery.GONE){
iv.setVisibility(View.GONE);
}else if(fallback == AQuery.INVISIBLE){
iv.setVisibility(View.INVISIBLE);
}
return bm;

android caching image from sdcard

i want to get image from sdcard in listview item i am able to show image but i want to cache that image so that i have smooth scroll can anyone please tell me how to cache image from sdcard i got the code but it show image from drawable but i want from sdcard
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.util.LruCache;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridLayout.LayoutParams;
import android.widget.GridView;
import android.widget.ImageView;
public class ListAdapter extends BaseAdapter {
Context context;
ArrayList<String> items;
private LruCache<String, Bitmap> mMemoryCache;
public ListAdapter(Context context, ArrayList<String> items) {
this.context = context;
this.items = items;
// Get memory class of this device, exceeding this amount will throw an
// OutOfMemory exception.
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in bytes rather than number
// of items.
return bitmap.getByteCount();
}
};
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int arg0) {
return items.get(arg0);
}
#Override
public long getItemId(int arg0) {
return arg0;
}
#Override
public View getView(int arg0, View convertView, ViewGroup arg2) {
ImageView img = null;
if (convertView == null) {
img = new ImageView(context);
img.setScaleType(ImageView.ScaleType.CENTER_CROP);
img.setLayoutParams(new GridView.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
} else {
img = (ImageView) convertView;
}
int resId = context.getResources().getIdentifier(items.get(arg0),
"drawable", context.getPackageName());
loadBitmap(resId, img);
return img;
}
public void loadBitmap(int resId, ImageView imageView) {
if (cancelPotentialWork(resId, imageView)) {
final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
imageView.setBackgroundResource(R.drawable.empty_photo);
task.execute(resId);
}
}
static class AsyncDrawable extends BitmapDrawable {
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
public AsyncDrawable(Resources res, Bitmap bitmap,
BitmapWorkerTask bitmapWorkerTask) {
super(res, bitmap);
bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(
bitmapWorkerTask);
}
public BitmapWorkerTask getBitmapWorkerTask() {
return bitmapWorkerTaskReference.get();
}
}
public static boolean cancelPotentialWork(int data, ImageView imageView) {
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
if (bitmapWorkerTask != null) {
final int bitmapData = bitmapWorkerTask.data;
if (bitmapData != data) {
// Cancel previous task
bitmapWorkerTask.cancel(true);
} else {
// The same work is already in progress
return false;
}
}
// No task associated with the ImageView, or an existing task was
// cancelled
return true;
}
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
if (imageView != null) {
final Drawable drawable = imageView.getDrawable();
if (drawable instanceof AsyncDrawable) {
final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
return asyncDrawable.getBitmapWorkerTask();
}
}
return null;
}
public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null) {
mMemoryCache.put(key, bitmap);
}
}
public Bitmap getBitmapFromMemCache(String key) {
return (Bitmap) mMemoryCache.get(key);
}
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
public int data = 0;
private final WeakReference<ImageView> imageViewReference;
public BitmapWorkerTask(ImageView imageView) {
// Use a WeakReference to ensure the ImageView can be garbage
// collected
imageViewReference = new WeakReference<ImageView>(imageView);
}
// Decode image in background.
#Override
protected Bitmap doInBackground(Integer... params) {
data = params[0];
final Bitmap bitmap = decodeSampledBitmapFromResource(
context.getResources(), data, 100, 100);
addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);
return bitmap;
}
// Once complete, see if ImageView is still around and set bitmap.
#Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
public static Bitmap decodeSampledBitmapFromResource(Resources res,
int resId, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
// Calculate ratios of height and width to requested height and
// width
final int heightRatio = Math.round((float) height
/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// Choose the smallest ratio as inSampleSize value, this will
// guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
}
I think you have to use AQuery. Download AQuery jar file from here. Add it into your Build path and then where you want to show your image, just display it like below:
AQuery aQuery=new AQuery(this);
File file = new File(YOUR IMAGE PATH);
aq.id(R.id.avatar).image(file, true,true); // that both true means you caching your images.

Categories

Resources