I am trying to download an image from the network and display in the ImageView with Glide using scaleType="centerInside" option.
For some reason, the image, when downloaded from the network, looks much smaller on the screen than when the same image is put into the ImageView from resources.
Example:
Both images can be found here. I would argue that even those images that have been set from resources look smaller than they could actually be when compared to what I see on my laptop. I understand that there is something related to the screen density in play, but how can I make these images be of "user-friendly size", e.g., a bit larger?
Even a different image of 600x250 px size is ridiculously small on the phone (with ImageView's layout_height and layout_width set to "wrap_content").
Code from the Activity:
public class DisplayImagesActivity extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.display_image_activity);
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
setTitle("Hello StackOverflow!");
ImageView top_left = (ImageView) findViewById(R.id.top_left);
ImageView top_right = (ImageView) findViewById(R.id.top_right);
ImageView bottom_left = (ImageView) findViewById(R.id.bottom_left);
ImageView bottom_right = (ImageView) findViewById(R.id.bottom_right);
String[] urls = new String[] {
"http://imgur.com/6jMOdg0.png",
"http://imgur.com/AhIziYr.png"
};
top_left.setImageResource(R.drawable.top_left);
top_right.setImageResource(R.drawable.top_right);
Glide.with(this)
.load(urls[0])
.signature(new StringSignature(new Date().toString()))
.into(bottom_left);
Glide.with(this)
.load(urls[1])
.signature(new StringSignature(new Date().toString()))
.into(bottom_right);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
this.finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
display_image_activity.xml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/match_parent"
android:orientation="vertical">
<include layout="#layout/_toolbar" />
<ScrollView
style="#style/match_parent">
<RelativeLayout
style="#style/match_parent"
android:padding="16dp">
<TextView
style="#style/wrap_content"
android:id="#+id/text_resources"
android:layout_marginBottom="10dp"
android:text="From Resources"/>
<ImageView
android:id="#+id/top_left"
android:background="#color/Linen"
android:layout_width="150dp"
android:layout_height="120dp"
android:layout_marginBottom="20dp"
android:layout_below="#id/text_resources"
android:scaleType="centerInside"/>
<ImageView
android:id="#+id/top_right"
android:background="#color/Linen"
android:layout_width="150dp"
android:layout_height="120dp"
android:layout_toRightOf="#id/top_left"
android:layout_toEndOf="#id/top_left"
android:layout_below="#id/text_resources"
android:layout_marginLeft="20dp"
android:layout_marginStart="20dp"
android:scaleType="centerInside"/>
<TextView
style="#style/wrap_content"
android:id="#+id/text_network"
android:layout_below="#id/top_left"
android:layout_marginBottom="10dp"
android:text="From Network"/>
<ImageView
android:id="#+id/bottom_left"
android:background="#color/Linen"
android:layout_width="150dp"
android:layout_height="120dp"
android:layout_below="#id/text_network"
android:scaleType="centerInside" />
<ImageView
android:id="#+id/bottom_right"
android:background="#color/Linen"
android:layout_width="150dp"
android:layout_height="120dp"
android:layout_toRightOf="#id/bottom_left"
android:layout_toEndOf="#id/bottom_left"
android:layout_below="#id/text_network"
android:layout_marginLeft="20dp"
android:layout_marginStart="20dp"
android:scaleType="centerInside" />
</RelativeLayout>
</ScrollView>
</LinearLayout>
I faced the same problem. Glide tries to interpret what my app needs and transforms the images accordingly, resulting in too small images in some places. In my case the ImageViews use adjustViewBounds="true" and MaxWdth/Height leading to problems
While I am not anything close to being a Glide Expert, I found a quick fix working for me.
I simply added a .dontTransform() mehod call, which in my case is OK since I use thumbnails that already have been pre-scaled.
GlideApp.with(context).load(fireStorage).dontTransform().into(imgView);
(Using a Placeholder would probably also have helped, but again, for me this was the easiest way)
Your images cannot be bigger than what you defined:
android:layout_width="150dp"
android:layout_height="120dp"
Try
android:layout_width="match_parent"
android:layout_height="wrap_content"
Your ImageViews can be that fixed size if you want although they should be flexible with match_parent/wrap_content.
I don't know what Glide does for sure but it looks like the resolution of the images from the network is smaller than the ones from resources. The android:scaleType="centerInside" gives you the behaviour that the image will be SHRUNK until both dimensions of the image fit in the ImageView and it's aspect ratio is maintained. If you want the images to expand to fit the ImageView you probably want android:scaleType="fitCenter" instead. You might also want android:adjustViewBounds to be true/false depending on how you want it to behave if you decide to make the dimensions flexible.
The documentation for scaleType is useful here:
https://developer.android.com/reference/android/widget/ImageView.ScaleType.html
https://developer.android.com/reference/android/graphics/Matrix.ScaleToFit.html#CENTER
This code saved my time. It works for me!
//Get actual width and height of image
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Bitmap bitmap = null;
try {
URL url = new URL(imgUrl);
bitmap = BitmapFactory.decodeStream((InputStream)url.getContent());
} catch (IOException e) {
Timber.e("Image Loading Error %s", e.getLocalizedMessage());
}
if (bitmap != null) {
final float scale = resources.getDisplayMetrics().density;
final int dpWidthInPx = (int) (bitmap.getWidth() * scale + 0.5f);
final int dpHeightInPx = (int) (bitmap.getHeight() * scale + 0.5f);
//Set result width and height to image
GlideApp.with(imgAns.getContext())
.load(imgUrl)
.override(dpWidthInPx, dpHeightInPx)
.into(imgAns);
}
Related
I am using Glide (also made a try with Picasso with the same behavior) to load a list of image urls into cards that should be shown in a camera view. Everything is working like a charm, but if i try to load more then around 8-12 images, only some of the last created cardviews are shown. Views created before are completely removed or shown as squashed image without card layout. There are no loading errors or further informations in the console log.
Now comes the crux of the story. When i exclude the images from the cardviews or use a local drawable as the image content, even loaded with Glide, all cards are displayed as expected.
I thought about a caching issue and added android:largeHeap="true" with no success. Also i've used a small thumbnail for all cards. Same scenario.
This is the function i am using to create the cardview's from a list of pois:
for (PlacesModel placesModel : mPlacesModelList) {
if ((placesModel.getDistance() / 1000f) < showDist) {
View view = layoutInflator.inflate(R.layout.ar_view, null);
view.setTag(placesModel.getPlaceId());
view.setVisibility(View.INVISIBLE);
ImageView img = view.findViewById(R.id.card_view_image);
view.setScaleY(setSize(placesModel.getDistance()) / 8.0f);
view.setScaleX(setSize(placesModel.getDistance()) / 8.0f);
TextView text = view.findViewById(R.id.t);
TextView desc = view.findViewById(R.id.d);
text.setMinWidth(200);
text.setText(placesModel.getPlaceName());
desc.setText(Config.cDist(placesModel.getDistance()));
text.setTextSize(TypedValue.COMPLEX_UNIT_SP, setSize(placesModel.getDistance()) / 3.0f);
desc.setTextSize(TypedValue.COMPLEX_UNIT_SP, (setSize(placesModel.getDistance()) - 1) / 2.0f);
Glide.with(getApplicationContext())
.load(placesModel.getImageThumbnail())
.thumbnail(0.1f)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.error(R.drawable.no_image)
.listener(new RequestListener<Drawable>() {
#Override
public boolean onLoadFailed(#Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
view.setVisibility(View.GONE);
return false;
}
#Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
view.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
view.setVisibility(View.GONE);
return false;
}
})
.into(img);
infl.addView(view);
}
}
}
This is the according layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/marker"
android:clickable="true"
android:focusable="true"
android:onClick="cardViewClicked"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:id="#+id/mainMarker"
android:orientation="vertical"
android:padding="4dp"
android:background="#ffffff"
app:cardBackgroundColor="#ffffff"
app:cardCornerRadius="1dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:padding="2dp"
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/card_view_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"/>
<TextView
android:id="#+id/t"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lines="1"
android:maxWidth="80dp"
android:textAppearance="#style/TextAppearance.FontPath.Bold"
android:textColor="#android:color/black"/>
<TextView
android:id="#+id/d"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lines="1"
android:maxWidth="80dp"
android:text=""/>
</LinearLayout>
</androidx.cardview.widget.CardView>
<ImageView
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_below="#+id/mainMarker"
android:layout_centerHorizontal="true"
android:scaleType="fitXY"
android:src="#drawable/ic_marker" />
</RelativeLayout>
Create CardView and its contents dynamically (programmatically). In XML file, just create a layout and add the cards using CardView dynamically inside java file.
Create object inside class, but outside onCreate method.
RelativeLayout relativeLayout = new RelativeLayout;
Then, link the layout using its id
relativeLayout = findViewById(R.id.marker);
Then create a function which will be called while creating a card. Code inside that function will look like:
TextView textView = new TextView(this);
textView.setText("Something...");
CardView cardView = new CardView(this);
cardView.addView(textView);
relativeLayout.addView(cardView);
I've found the solution.
There was a Glide info in Logcat where others mentioned i can be slightly ignored.
Glide treats LayoutParams.WRAP_CONTENT as a request for an image the size of this device's screen dimensions. If you want to load the original image and are ok with the corresponding memory cost and OOMs (depending on the input size), use override(Target.SIZE_ORIGINAL). Otherwise, use LayoutParams.MATCH_PARENT, set layout_width and layout_height to fixed dimension, or use .override() with fixed dimensions.
Now i had only to set the layout parameters to Target.SIZE_ORIGINAL like this
view.setLayoutParams(new LinearLayout.LayoutParams(
Target.SIZE_ORIGINAL,
Target.SIZE_ORIGINAL));
I'm placing a very wide image inside a HorizontalScrollView.
The ImageView/ScrollView height is dynamic as I've set the height to 0dp and added constraints. Since the ImageView's scale type is fitStart and adjustViewBounds is true - the image's width is being resized.
XML:
<HorizontalScrollView
android:id="#+id/mapScrollView"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginBottom="10dp"
app:layout_constraintBottom_toTopOf="#id/playButton"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.constraint.ConstraintLayout
android:id="#+id/mapLayout"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<ImageView
android:id="#+id/mapImage"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:adjustViewBounds="true"
android:scaleType="fitStart"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.gigi.testmap.activities.quest.QuestMapPathView
android:id="#+id/mapLinesView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="#id/mapImage"
app:layout_constraintEnd_toEndOf="#id/mapImage"
app:layout_constraintStart_toStartOf="#id/mapImage"
app:layout_constraintTop_toTopOf="#id/mapImage" />
</android.support.constraint.ConstraintLayout>
</HorizontalScrollView>
I'm trying to get the ImageView width (total width, visible & invisible part). Getting the ScrollView total width will also help.
My goal is to place buttons on top of the map in positions calculated according to width & height of the rendered ImageView.
I'm loading the image using Glide:
final ImageView mapImage = mActivity.findViewById(R.id.mapImage);
Glide.with(mActivity).load(R.drawable.fullmap).into(mapImage);
mapImage.getViewTreeObserver().addOnGlobalLayoutListener(new
ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
mapImage.getWidth(); // --> returns 0
mapImage.getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
}
});
I've tried getting the width using tree view observer's global layout listener but all I got is 0. The height is returned correctly though.
Any help will be much appreciated,
Thank you very much.
I have no experience with Glide.
You are setting the all views / containers android:layout_height="0dp"
try first to change it to any other arbitrary value or wrap_content.
you did not attach the code of how you are trying to get the height.
Have you tryed mapImage.getHeight()
For Bitmap, I used to get this way
Glide.with(mContext())
.asBitmap()
.load(path)
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap bitmap,
Transition<? super Bitmap> transition) {
int w = bitmap.getWidth();
int h = bitmap.getHeight()
}
});
It seems that the image is not fully rendered once the tree view global layout listener is first called (I guess it's because the image width is pretty big) - What I did was to have a check for the image width and only if greater than 0, remove the listener and continue with my code.
final ImageView mapImage = mActivity.findViewById(R.id.mapImage);
Glide.with(mActivity).load(R.drawable.fullmap).into(mapImage);
mapImage.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (mapImage.getWidth() > 0) {
mapImage.getViewTreeObserver().removeOnGlobalLayoutListener(this);
//continue width related code here
}
}
});
Maybe not the prefect solution and there is a small delay until the image shows up - but it is ok for my use case.
I have a ListView with a custom adapter. Every row has a Pokémon sprite that I download to a bitmap, the sprites are always 96 x 96. I manually downloaded a dummy image and put it in my drawables folder, and it renders fine:
How it should be
But when I actually download the images programmatically, it gives me this result:
How it is
Why are then suddenly so small? When I sysout the height and width of the downloaded bitmaps, it says 96 x 96, but it clearly doesn't render as 96 x 96.
Here's the code of the task that downloads the image
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
#Override
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap bm = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
bm = BitmapFactory.decodeStream(in);
} catch (Exception e) {
e.printStackTrace();
}
return bm;
}
}
How I call the task
try {
Bitmap bm = new DownloadImageTask().execute(dataModel.getSpriteUrl()).get();
viewHolder.sprite.setImageBitmap(bm);
} catch (Exception e) {
e.printStackTrace();
}
Pokemon row XML
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/img_sprite"
android:layout_width="96dp"
android:layout_height="96dp"
android:scaleType="fitCenter" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="left|center_vertical"
android:orientation="vertical">
<TextView
android:id="#+id/text_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#android:color/black"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="#+id/text_cp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp" />
<TextView
android:id="#+id/text_gendershiny"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="end"
android:orientation="vertical">
<Button
android:id="#+id/btn_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:backgroundTint="#color/colorPrimary"
android:text="DELETE"
android:textColor="#ffffff"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
You might want to take a look at this website. I gives some helpful tips of how to use the scaleType attribute with the ImageView:
https://robots.thoughtbot.com/android-imageview-scaletype-a-visual-guide
Please see the edit at the bottom of this answer.
Now to the issue with using get() method of an AsyncTask
Use an interface to let you know when the AsyncTask is complete:
public interface BitmapLoaderListener {
void onCompletedBitmapLoaded(Bitmap bm);
}
Your AsyncTask could look like this:
public class BitmapLoader extends AsyncTask<String, Integer, Bitmap> {
private static final String TAG = BitmapLoader.class.getSimpleName();
private BitmapLoaderListener mListener;
private String imageUrl = "";
public BitmapLoader(String imageUrl, BitmapLoaderListener listener){
this.imageUrl = imageUrl;
this.mListener = listener;
this.selectedSource = source;
}
#Override
protected Bitmap doInBackground(String... params) {
Bitmap bm = null;
try{
// Your code here !!!
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
return bm;
}
protected void onPostExecute(Bitmap bm) {
mListener.onCompletedBitmapLoaded(bm);
}
}
Call the AsyncTask from your RecyclerView from the onBindViewHolder:
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position){
MyData data = mData.get(position);
// Add whatever code you need here
BitmapLoaderListener listener = new BitmapLoaderListener() {
#Override
public void onCompletedBitmapLoaded(Bitmap bm) {
if (bm == null) return;
holder.myImageView.setImageBitmap(bm);
}
};
BitmapLoader loader = new BitmapLoader(imageUrl, listener);
loader.execute();
}
You could implement a cache type system where you persist the images to the device storage and load them from the internet only when needed. I do this with a lot of my apps. This is possible, but it requires experience with dealing with threads and resources... As Angelina pointed out you can always use Glide or Picasso libraries. Although I very rarely use third party libraries in this case you might want to consider it--they are well designed and well maintained libraries.
Edit:
Using a scaling method createScaledBitmap()for every downloaded image seems a bit heavy weight.
You might want to make this simple change to your layout file:
<ImageView
android:id="#+id/img_sprite"
android:layout_width="96dp"
android:layout_height="96dp"
android:scaleType="fitCenter"/>
There are many ways to achieve the result you want by making some changes to your layout file. I just pick the easiest with regard to the image size you are downloading (96x96).
This example takes the image and forces it into an ImageView 96dpx96dp so that the image is centered and scaled to fit the view bounds maintaining the original aspect ratio.
This is much easier to maintain and modify as well as much more light weight then using createScaledBitmap() method for every image--rather it needs it or not, ouch!
Using AsyncTask to download an image is not the common thing. Usually this is done with a library called Glide. It downloads the image in background thread and caches it. You can also set ScaleType of the image there.
As the title suggest, I am having a lot of issues maintaining the quality and aspect ratio of my images on my android application.
Basically I have an image view and I am trying to get images to fit the image view and maintain it's image quality. I cant use fitxy because that will stretch the image to fill the entire imageview, but I only desire the image to automatically scale it's self and show as crisp as possible like your phone gallery.
In my code, I use fitCenter as the scale type and the size of the image seems alright, however the image is terrible distorted. This is the code.
Ive also included a snapshot of the android and iphone version to show how the exact same image is showing differently on the same image.
<?xml version="1.0" encoding="utf-8"?>
<!-- This controls layout for the slider in Gallery -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent">
<ImageView
android:id="#+id/pagerimage"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_gravity="center_horizontal"
/>
</RelativeLayout>
</LinearLayout>
iPhone
Android
public void handleGalleryImages() {
try {
for (int j = 0; j < imagesNaturalItemlist.size(); j++) {
Log.e("ImagePATH>>>>>", imagesNaturalItemlist.get(j).getImage());
String imageid = imagesNaturalItemlist.get(j).getUniqueId();
downgalleryimage = new DownloadImage(imagesNaturalItemlist.get(j).getImage(), imageid);
downgallerylist.add(downgalleryimage);
beachimages.add(imagesNaturalItemlist.get(j).getImage());
}
} catch (NullPointerException e) {
e.printStackTrace();
}
adapter
public Object instantiateItem(ViewGroup container, int position) {
View itemView = LayoutInflater.from(context).inflate(R.layout.sliding_pager_row, container, false);
ImageView imageView = (ImageView) itemView.findViewById(R.id.pagerimage);
if (images.get(position) != null && !images.get(position).equals("")) {
//Picasso.with(context).load(images.get(position)).into(imageView);
Glide.with(context)
.load(images.get(position))
.apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.ALL).override(600, 250))
.into(imageView);
}
container.addView(itemView);
return itemView;
}
I have:
a recyclerview with GridLayoutManager
grid item layout with an ImageView in it (with height wrap_content and width match_parent) wrapped in a Framelayout, so the image is bottom|center_horizontal aligned
Picasso loading an image into ImageView asynchronously from the web
Current situation:
The image is loaded into the imageView, but the imageview's size is the recycled grid item's imageview's size.
What I would like to achieve:
After loading the image into the imageview, resize the imageview on runtime (redraw).
What I have tried:
notifyItemChanged() - could do the trick (in theory at least), but I
am not able to check if the current grid item's view is in layout
state, so my app crashed with IllegalStateException
listening to Picasso's load with a Callback, and onSuccess() check the imageview drawable aspectratio and try to resize the imageview itself with
requestLayout(). Did not work. (Well it worked, but only when there
is an animation or something triggering the redraw of the layout. If
there is nothing, then the imageview is not redrawn.)
listening to Picasso's load with a Callback, and onSuccess() start an animation animating the alpha of the imageview. This would trigger the redraw. But this sometimes worked sometimes not(and I don't know why).
What I did was putting an ImageView into FrameLayout and then changing this FrameLayout's size to needed. Hope it would help you.
<FrameLayout
android:id="#+id/frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
<ImageView
android:id="#+id/video_thumbnail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitStart"
android:adjustViewBounds="true" />
</FrameLayout>
P.S. changing FrameLayout's size:
viewHolder.frame.setMinimumWidth(neededWidth);
Picasso has a function to resize your image. Something like this:
Picasso.with(context)
.load(url)
.resize(50, 50)
.centerCrop()
.into(imageView)
You can change centerCrop, to play with aspect ratio
I wanna show this using a
Campaign Banner List Using Dynamic Width - Height Example
that:
Create an item_campaign_banner.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white">
<RelativeLayout
android:id="#+id/campaignImageSuperView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/campaignImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="#drawable/campaign_image_error_icon"
android:visibility="visible"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"/>
<View
android:id="#+id/campaignSectionLine"
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_below="#+id/campaignImage"
android:background="#F2F2F2" />
</RelativeLayout>
</RelativeLayout>
Than create a BannerHolder.java
public class BannerHolder extends RecyclerView.ViewHolder {
private ImageView campaignImage;
private View campaignSectionLine;
private ViewGroup campaignImageSuperView;
public BannerHolder(#NonNull View itemView) {
super(itemView);
campaignImage = (ImageView) itemView.findViewById(R.id.campaignImage);
campaignSectionLine = itemView.findViewById(R.id.campaignSectionLine);
campaignImageSuperView = itemView.findViewById(R.id.campaignImageSuperView);
}
public ImageView getCampaignImage() {
return campaignImage;
}
public ViewGroup getCampaignImageSuperView() {
return campaignImageSuperView;
}
}
Than apply this in onBindViewHolder(#NonNull RecyclerView.ViewHolder incomingHolder, int position) method that
your created YourAdapter.java
if (incomingHolder instanceof BannerHolder) {
BannerHolder bannerHolder = (BannerHolder) incomingHolder;
Banner banner = (Banner) campaigns.get(position);
if(banner != null && banner.getImage() != null && banner.getImage().getWidth() != null && banner.getImage().getHeight() != null) {
Picasso.with(activity)
.load(banner.getImage().getUrl())
.error(R.drawable.campaign_image_error_icon)
.into(bannerHolder.getCampaignImage());
bannerHolder.getCampaignImageSuperView().setMinimumWidth(banner.getImage().getWidth());
bannerHolder.getCampaignImageSuperView().setMinimumHeight(banner.getImage().getHeight());
}
}
That's all!