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.
Related
According to this question I used a custom ImageGatter class to display images that I'm getting from a server in TextView using Picasso
public class PicassoImageGetter implements Html.ImageGetter {
private TextView textView = null;
Context mContext;
public PicassoImageGetter() {
}
public PicassoImageGetter(TextView target, Context context) {
textView = target;
mContext = context;
}
#Override
public Drawable getDrawable(String source) {
BitmapDrawablePlaceHolder drawable = new BitmapDrawablePlaceHolder();
Picasso.get().load(source).into(drawable);
return drawable;
}
private class BitmapDrawablePlaceHolder extends BitmapDrawable implements com.squareup.picasso.Target {
protected Drawable drawable;
#Override
public void draw(final Canvas canvas) {
if (drawable != null) {
drawable.draw(canvas);
}
}
public void setDrawable(Drawable drawable) {
this.drawable = drawable;
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
drawable.setBounds(0, 0, width, height);
setBounds(0, 0, width, height);
if (textView != null) {
textView.setText(textView.getText());
}
}
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
setDrawable(new BitmapDrawable(mContext.getResources(), bitmap));
}
#Override
public void onBitmapFailed(Exception e, Drawable errorDrawable) {
setDrawable(errorDrawable);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
}
}
and used like this
imageGetter = new PicassoImageGetter(contentTextView, this);
Spannable html;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
html = (Spannable) Html.fromHtml(content, Html.FROM_HTML_MODE_LEGACY, imageGetter, null);
} else {
html = (Spannable) Html.fromHtml(content, imageGetter, null);
}
contentTextView.setText(html);
I need to catch this images into internal or external storage to display it if there's no connection, but I don't know the path or file name.
You need to implement picasso cache by your own. This should be like this:
public class PicassoCache {
private static Picasso picassoInstance = null;
private PicassoCache(Context context) {
Downloader downloader = new OkHttp3Downloader(context, Integer.MAX_VALUE);
Picasso.Builder builder = new Picasso.Builder(context);
builder.downloader(downloader);
picassoInstance = builder.build();
}
public static Picasso getPicassoInstance(Context context) {
if (picassoInstance == null) {
new PicassoCache(context);
return picassoInstance;
}
return picassoInstance;
}
}
Then in your code:
#Override
public Drawable getDrawable(String source) {
BitmapDrawablePlaceHolder drawable = new BitmapDrawablePlaceHolder();
PicassoCache.getPicassoInstance(getContext()).load(source).into(drawable);
return drawable;
}
OkHttp3Downloader will install an image cache into your application cache directory. You can also use another constructor with your own provided directory public OkHttp3Downloader(final File cacheDir, final long maxSize)
As an alternative, you can use Glide. This is like picasso but also allows you to show gifs with animation and cache strategy IMHO is a bit easier.
Glide.with(context)
.load(source)
.apply(RequestOptions().diskCacheStrategy(DiskCacheStrategy.ALL))
.into(drawable)
This is my code in which the image is not showing properly:
public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.PhotoViewHolder> implements SizeCalculatorDelegate {
ArrayList<String> source_title = new ArrayList<String>();
private final double[] mImageAspectRatios;
private Context mContext;
public double aspectRatioForIndex(int index) {
// Precaution, have better handling for this in greedo-layout
if (index >= getItemCount()) return 1.0;
return mImageAspectRatios[getLoopedIndex(index)];
}
public class PhotoViewHolder extends RecyclerView.ViewHolder {
private ImageView mImageView;
public PhotoViewHolder(ImageView imageView) {
super(imageView);
mImageView = imageView;
}
}
public MoviesAdapter(Context context, ArrayList<String> image) {
mContext = context;
this.source_title = image;
mImageAspectRatios = new double[source_title.size()];
// calculateImageAspectRatios();
}
#Override
public PhotoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ImageView imageView = new ImageView(mContext);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
));
return new PhotoViewHolder(imageView);
}
#Override
public void onBindViewHolder(final PhotoViewHolder holder, int position) {
Picasso.with(mContext).load(source_title.get(position)).into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
holder.mImageView.setImageBitmap(bitmap);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
Log.d("bitmapfailed", "errorDrawable " + errorDrawable);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
Log.d("onPrepareLoad", "placeHolderDrawable " + placeHolderDrawable);
}
});
}
#Override
public int getItemCount() {
return source_title.size();
}
// private void calculateImageAspectRatios() {
// BitmapFactory.Options options = new BitmapFactory.Options();
// options.inJustDecodeBounds = true;
//
// for (int i = 0; i < source_title.size(); i++) {
//
// int value = Integer.parseInt(source_title.get(i));
//
// BitmapFactory.decodeResource(mContext.getResources(), value, options);
// mImageAspectRatios[i] = options.outWidth / (double) options.outHeight;
// }
// }
// Index gets wrapped around <code>Constants.IMAGES.length</code> so we can loop content.
private int getLoopedIndex(int index) {
return index % source_title.size(); // wrap around
}
}
and this is the original demo code
public class PhotosAdapter extends RecyclerView.Adapter<PhotosAdapter.PhotoViewHolder> implements SizeCalculatorDelegate {
private static final int IMAGE_COUNT = 500; // number of images adapter will show
private final int[] mImageResIds = Constants.IMAGES;
private final double[] mImageAspectRatios = new double[mImageResIds.length];
private Context mContext;
#Override
public double aspectRatioForIndex(int index) {
// Precaution, have better handling for this in greedo-layout
if (index >= getItemCount()) return 1.0;
Log.d("index", mImageAspectRatios + "");
return mImageAspectRatios[getLoopedIndex(index)];
}
public class PhotoViewHolder extends RecyclerView.ViewHolder {
private ImageView mImageView;
public PhotoViewHolder(ImageView imageView) {
super(imageView);
mImageView = imageView;
}
}
public PhotosAdapter(Context context) {
mContext = context;
calculateImageAspectRatios();
}
#Override
public PhotoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ImageView imageView = new ImageView(mContext);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
));
return new PhotoViewHolder(imageView);
}
#Override
public void onBindViewHolder(PhotoViewHolder holder, int position) {
Picasso.with(mContext)
.load(mImageResIds[getLoopedIndex(position)])
.into(holder.mImageView);
}
#Override
public int getItemCount() {
return IMAGE_COUNT;
}
private void calculateImageAspectRatios() {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
for (int i = 0; i < mImageResIds.length; i++) {
BitmapFactory.decodeResource(mContext.getResources(), mImageResIds[i], options);
mImageAspectRatios[i] = options.outWidth / (double) options.outHeight;
}
}
// Index gets wrapped around <code>Constants.IMAGES.length</code> so we can loop content.
private int getLoopedIndex(int index) {
return index % Constants.IMAGES.length; // wrap around
}
}
in this demo the image shows properly but in my demo images not show, tha data from source_title arraylist is showing properly but this demo does not work properly, as I use onBindViewHolder method it goes into onPrepareLoad exception called null value of placeHolderDrawable...
Is there any solution to use it or some other method or way to solve this issue?
Sorry for my english and thnx in advance...
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;
}
}
}
I'm having images from url and it store in string array and on touch ImageView i'm trying to display images in GridView but images not displayed.
here is my Activity class.
public class GridViewActivity extends Activity {
private GridViewImageAdapter adapter;
private GridView gridView;
private int columnWidth;
ArrayList<String> imagepath;
Utility utils;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid_view);
gridView = (GridView) findViewById(R.id.grid_view);
Intent i = getIntent();
imagepath = i.getExtras().getStringArrayList("event_photo");
Log.i("Grid View", "hello..."+imagepath);
utils = new Utility(this);
// Initilizing Grid View
InitilizeGridLayout();
// Gridview adapter
adapter = new GridViewImageAdapter(GridViewActivity.this, imagepath,
columnWidth);
// setting grid view adapter
gridView.setAdapter(adapter);
}
private void InitilizeGridLayout() {
Resources r = getResources();
float padding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
AppConstant.GRID_PADDING, r.getDisplayMetrics());
columnWidth = (int) ((utils.getScreenWidth() - ((AppConstant.NUM_OF_COLUMNS + 1) * padding)) / AppConstant.NUM_OF_COLUMNS);
gridView.setNumColumns(AppConstant.NUM_OF_COLUMNS);
gridView.setColumnWidth(columnWidth);
gridView.setStretchMode(GridView.NO_STRETCH);
gridView.setPadding((int) padding, (int) padding, (int) padding,
(int) padding);
gridView.setHorizontalSpacing((int) padding);
gridView.setVerticalSpacing((int) padding);
}
}
here is my adapter class.
public class GridViewImageAdapter extends BaseAdapter {
private Activity _activity;
private ArrayList<String> _filePaths = new ArrayList<String>();
private int imageWidth;
public GridViewImageAdapter(Activity activity, ArrayList<String> filePaths,
int imageWidth) {
this._activity = activity;
this._filePaths = filePaths;
this.imageWidth = imageWidth;
}
#Override
public int getCount() {
return this._filePaths.size();
}
#Override
public Object getItem(int position) {
return this._filePaths.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(_activity);
} else {
imageView = (ImageView) convertView;
}
// get screen dimensions
Bitmap image = decodeFile(_filePaths.get(position), imageWidth,
imageWidth);
Log.i("Grid View", "image bitmap..."+image);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(imageWidth,
imageWidth));
imageView.setImageBitmap(image);
// image view click listener
imageView.setOnClickListener(new OnImageClickListener(position));
return imageView;
}
class OnImageClickListener implements OnClickListener {
int _postion;
// constructor
public OnImageClickListener(int position) {
this._postion = position;
}
#Override
public void onClick(View v) {
// on selecting grid view image
// launch full screen activity
/*Intent i = new Intent(_activity, FullScreenViewActivity.class);
i.putExtra("position", _postion);
_activity.startActivity(i);*/
}
}
/*
* Resizing image size
*/
public static Bitmap decodeFile(String filePath, int WIDTH, int HIGHT) {
try {
File f = new File(filePath);
Log.i("Grid View", "imagefb bfhdb"+filePath);
Log.i("Grid View", "imagefb nj"+f);
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
final int REQUIRED_WIDTH = WIDTH;
final int REQUIRED_HIGHT = HIGHT;
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_WIDTH
&& o.outHeight / scale / 2 >= REQUIRED_HIGHT)
scale *= 2;
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
if any one have solution please let me know.
first,sorry for my English.
I'm new in Android,I have a activity to show news,the content is from web server and the content contains images.I used a TextView to display it and I want to the images fit the sreen,so I wrote these codes.
public class CustomImageGetter implements Html.ImageGetter {
private Activity context;
private Picasso picasso;
private TextView textView;
public CustomImageGetter(Activity context, Picasso picasso, TextView textView) {
this.context = context;
this.picasso = picasso;
this.textView = textView;
}
#Override
public Drawable getDrawable(final String source) {
final PlaceHolderBitmapDrawable result = new PlaceHolderBitmapDrawable();
new AsyncTask<Void, Void, Bitmap>() {
#Override
protected Bitmap doInBackground(Void... params) {
try {
return picasso
.load(Config.WEB_SERVER + source.substring(1))
.placeholder(R.drawable.placeholder)
.error(R.drawable.placeholder)
.get();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
try {
BitmapDrawable drawable = new BitmapDrawable(context.getResources(), bitmap);
DisplayMetrics metrics = new DisplayMetrics();
context.getWindowManager().getDefaultDisplay().getMetrics(metrics);
int width = metrics.widthPixels;
int height = width * bitmap.getHeight() / bitmap.getWidth();
drawable.setBounds(0, 0, width, height);
result.setDrawable(drawable);
result.setBounds(0, 0, width, height);
textView.setText(textView.getText());
} catch (Exception e) {
e.printStackTrace();
}
}
}.execute((Void) null);
return result;
}
private static class PlaceHolderBitmapDrawable extends BitmapDrawable {
protected Drawable drawable;
#Override
public void draw(Canvas canvas) {
if (drawable != null)
drawable.draw(canvas);
}
public void setDrawable(Drawable drawable) {
this.drawable = drawable;
}
}
}
The image's width is correct but the height is too short in android 4.4 but in android L is normal.
The left picture runs in android 4.4 and the right runs in android L.
How can I fix the problem?