Fit image to screen width in viewpager in landscape mode in android - android

I have a VerticalViewPager and I have some images in it. When I rotate my device in landscape mode my ImageView doesn't scale to width of my screen. It fits the height if image instead. I used AspectRatioImageView. It fits the width but VerticalViewPager doesn't scroll down.
Thank you.
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<HackyViewPager
android:id="#+id/vvp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff"
>
</HackyViewPager>
</RelativeLayout>
Here is rowitemview.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:pixlui="http://schemas.android.com/apk/com.neopixl.pixlui"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#fff" >
<AspectRatioImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:src="#drawable/m4_3" />
</LinearLayout>
and here is my instaniateItem of my ImagePageAdapter that extends PagerAdapter:
#Override
public Object instantiateItem(ViewGroup container, int position)
{
Context context = MainActivity.this;
container.requestLayout();
AspectRatioImageView imageView = new AspectRatioImageView(context);
imageView.setImageDrawable(getResources().getDrawable(R.drawable.m4_3));
mAttacher = new PhotoViewAttacher(imageView);
mAttacher.setOnMatrixChangeListener(new OnMatrixChangedListener() {
#Override
public void onMatrixChanged(RectF rect) {
if((int)rect.width()>_width)
viewPager.setLocked(true);
else
viewPager.setLocked(false);
}
});
P.S : The issue is with viewPager height. When I scroll down the image it just goes to the other page instead of scrolling the scaled image.

Here's what you need.
This is a good solution I found out.
Android Crop Center of Bitmap
This allows to set the height and your width according to your orientation.
To change the image's scale to full screen, you generally use center crop like this:
yourImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
Hope this information was useful..:)

Use android:scalType = "fitxy" in activity code like this imageView.setScaleType(ImageView.ScaleType.FIT_XY);

Related

View width is zero when set to MATCH_PARENT

I have an ImageView inside of a LinearLayout which is an item of a RecyclerView. I have all these views' width as MATCH_PARENT.
Now, I'm trying to calculate the heigth using the aspect ratio before the image is loaded so there's no resizing.
But, what I've seen is that before the image is loaded, its width is zero.
The thing is that I'm doing similar things in other parts of the app and it's working fine, I don't really know what I'm missing here.
RecyclerView item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white">
<LinearLayout
...
</LinearLayout>
<!-- This is the image -->
<ImageView
android:id="#+id/descubre_shop_banner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/colorLightText"
android:layout_marginRight="16dp"
android:layout_marginLeft="16dp"
android:layout_marginBottom="8dp"/>
</LinearLayout>
ViewHolder
mBannerTarget = new Target()
{
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from)
{
mShopBannerImageView.setImageBitmap(bitmap);
// Wrap content when the images is loaded.
mShopBannerImageView.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
mShopBannerImageView.setBackgroundColor(-1);
mShopBannerImageView.setAlpha(1.0f);
Animation fadeOut = new AlphaAnimation(0, 1);
fadeOut.setInterpolator(new AccelerateInterpolator());
fadeOut.setDuration(250);
mShopBannerImageView.startAnimation(fadeOut);
LOADED = true;
}
#Override
public void onBitmapFailed(Drawable errorDrawable)
{
mShopBannerImageView.setBackgroundColor(
mContext.getResources().getColor(android.R.color.holo_red_dark));
mShopBannerImageView.setAlpha(0.2f);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable)
{
// This is 0
Log.d(Properties.TAG, "" + mShopBannerImageView.getWidth());
// Remove the old bitmap
mShopBannerImageView.setImageBitmap(null);
// Set the height using the width and the aspect ratio.
mShopBannerImageView.getLayoutParams().height =
(int) (mShopBannerImageView.getWidth() * shop.getAspectRatio());
// Set a color while loading.
mShopBannerImageView.setBackgroundColor(
mContext.getResources().getColor(R.color.colorAccent));
mShopBannerImageView.setAlpha(0.25f);
}
};
I tried to set the width of the ImageView and its parent as MATCH_PARENT in code but no luck. Any clue of what's going on?
Regards,
The views dimensions is always 0 before being fully created, if you wanted to know the actual width, you have to use the method: post():
view.post(new Runnable() {
#Override
public void run() {
// This is where width would be different than 0
}
});
That being said, you should actually use an other method to keep the ratio than actually calculating it yourself!
See this thread for further information How to scale an Image in ImageView to keep the aspect ratio

ImageView expanding container despite adjustViewBounds

I want to wrap an ImageView inside a LinearLayout so that I can center a group of views. However, the original image needs to be scaled down to fit in the ImageView, and the original size expands the LinearLayout, despite my use of adjustViewBounds="true" and an enclosing FrameLayout as suggested by previous questions on SO.
The desired layout should look like this,
but the observed layout looks like this,
as produced by the XML below:
<android.support.percent.PercentRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="project.MainActivity">
<LinearLayout
android:layout_width="wrap_content"
app:layout_heightPercent="32%"
android:orientation="horizontal"
android:background="#b44343"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sample Text"/>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#5555ae">
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#2c8c4c"
android:src="#drawable/spades_icon"
android:adjustViewBounds="true"
android:scaleType="centerInside"/>
</FrameLayout>
</LinearLayout>
</android.support.percent.PercentRelativeLayout>
I can't use the other suggestion of setting android:maxHeight="100dp" because I need the height to be relative to that of the screen.
I see that you have added android:adjustViewBounds="true".
You can combine that with android:maxWidth="60dp"
So your imageView should look like this.
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#2c8c4c"
android:src="#drawable/spades_icon"
android:adjustViewBounds="true"
android:maxWidth="60dp"
android:scaleType="centerInside"/>
You can change the max width to any number you want.
Things you can do:
1) Set a specific width / height to the FrameLayout enclosing the ImageView and set android:scaleType to centerInside, fitCenter, or fitXY for the ImageViwe.
2) Programatically, in your activity, after onCreate, in onResume for example, you can get the LayoutParams and change the width and height of the ImageView doing you own scaleing. I take this aproach when I scale against the screen widht or height at run time.
EDIT 1
Example of second alternative:
public class TestActivity extends AppCompatActivity {
ImageView imgView;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.testactivity_layout);
imgView = (ImageView) findViewById(R.id.imgview);
}
#Override
protected void onResume() {
super.onResume();
ViewGroup.LayoutParams params = imgView.getLayoutParams();
params.width = 100;
}
}
Notes:
The width is expressed in pixel.
To get the display metrics:
How to get screen display metrics in application class
To establish a relative width for the ImageView, get the width of the display and calculate the desireed % as the width of the image.
Based on this answer to another question, a solution that removes the whitespace in the LinearLayout while preserving the height and aspect ratio of the image is:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
LinearLayout layout = (LinearLayout) findViewById(R.id.mLinearLayout);
ImageView imageView = (ImageView) findViewById(R.id.mImageView);
TextView textView = (TextView) findViewById(R.id.mTextView);
layout.getLayoutParams().width = textView.getWidth()+imageView.getWidth();
layout.requestLayout();
}
EDIT:
Based on #Juan's answer and these instructions, the following code also achieves the desired result:
#Override
protected void onResume() {
DisplayMetrics displayMetrics = new DisplayMetrics();
this.getWindowManager()
.getDefaultDisplay()
.getMetrics(displayMetrics);
ViewGroup.LayoutParams params = imgView.getLayoutParams();
params.height = (int)Math.floor(displayMetrics.heightPixels * 0.32);
}

Change ImageView size in a recyclerview after Picasso.load()?

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!

Layout height getting as -2

The below is the xml that iam inflating within my customList
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<RelativeLayout
android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<exp.viswanath.dropper.CustomView
android:id="#+id/custom_view"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="#e1e1e1"
android:padding="4dp" />
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#+id/custom_view" />
</RelativeLayout>
</LinearLayout>
And my custom view Layout is
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<exp.viswanath.dropper.CustomList
android:id="#+id/wrapper"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Iam getting the height of Layout with id parent and listview as -1 and -2 . But iam getting the correct height for element with id custom_view as 105. Iam inflating this within the constructor of my CustomList
CODE
View rowView = LayoutInflater.from(context).inflate(R.layout.activity_dropper, null);
parentLayout = (RelativeLayout)rowView.findViewById(R.id.parent);
Log.d("", "DEBUG:pl:" + parentLayout.getLayoutParams().height);
myView = (CustomView)parentLayout.findViewById(R.id.custom_view);
_viewHeight = myView.getLayoutParams().height;
initList();
_height = (-1) * _viewHeight;
Log.d("","height:" + _height);
listView = (ListView)parentLayout.findViewById(R.id.listView);
Log.d("", "DEBUG:lv:" + listView.getLayoutParams().height);
Does any one knows the problem or experienced the same? The layout is not visible at all
PROBLEM
MY VIEW IS NOT VISIBLE
The problem is that myView.getLayoutParams().height; will not return you the height as it has not been measured yet. In tghis case it returns you the constant associated with the view such as FILL_PARENT, WRAP_CONTENT etc. See documentation here:
Information about how tall the view wants to be. Can be one of the
constants FILL_PARENT (replaced by MATCH_PARENT , in API Level 8) or
WRAP_CONTENT. or an exact size.
To get the size of a layout, your should be using getWidth() or getMeasuredWidth() methods. However, these methods won't give you a meaningful answer until the view has been measured. Read about how android draws views here.
You can get the correct size, by overriding the onWindowFocusChanged() as mentioned in this thread.
Alternatively, you could do this:
myView.post(new Runnable() {
#Override
public void run() {
Log.d("", "DEBUG:lv:" + myView.getMeasuredHeight());
}
});
Try this way
listView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Log.d("", "DEBUG:lv:" + listView.getLayoutParams().height);
}
});

dialog doesn't take parent size

I am creating a dialog to zoom in on an image,
However, my content is 240px and I would like to resize it to the screen width, to "fill_parent". Could you tell me what's wrong here? My picture stays small, 240px, not 480px.
final Dialog dialog = new Dialog(myview);
dialog.setContentView(R.layout.zoom);
dialog.setTitle(""+passInfoNom+" ");
imgView2 = (ImageView)dialog.findViewById(R.id.ImageZoom);
imgView2.setImageDrawable(image);
dialog.show();
Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffffff"
>
<ImageView android:id="#+id/ImageZoom"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</ImageView>
</LinearLayout>
It looks like you have set the content to "fill_parent" but you have not set the size of the dialog to be "fill_parent." change that and you should see some results.
But i have a question: if you want the zoom dialog to take up the whole screen, why dont you start a new activity, or crop the image and set the cropped portion as the content? it seems weird to me that you would zoom in a dialog. Google maps, for example, just zooms in the existing View.
As specified in another anwser, I am adjusting the size of my dialog by creating my own Dialog class and setting its size:
public class ZoomZoom extends Dialog
{
public ZoomZoom(Context context) {
super(context);
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.zoom);
LayoutParams params = getWindow().getAttributes();
params.width = LayoutParams.FILL_PARENT;
//params.height = LayoutParams.FILL_PARENT;
params.height = screenLargeur;
getWindow().setAttributes((android.view.WindowManager.LayoutParams) params);
imgView2 = (ImageView)findViewById(R.id.ImageZoom);
imgView2.setImageDrawable(imageZ);
imgView2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialog.hide();
}
});
}
}
Not sure if this has been resolved for you but you can also use android:minWidth and android:minHeight, setting them to by dip. For instance:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/send_chat_layout"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:background="#292929"
android:minWidth="300dip"
android:minHeight="400dip">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
From my understanding, due to the way Android scales in resolution, with a 360x480 screen, setting the mins to 340x460 will keep its aspect to larger resolutions.

Categories

Resources