I have 5 square ImageButtons that I want to have lined up side by side on the bottom of the screen. I have each one set (different id's) as:
<ImageButton
android:id="#+id/box1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:layout_weight="1"
android:layout_margin="1dp"
/>
and I have the background assigned in main java like this:
int[] imageIds = new int[] {R.id.box1,R.id.box2,R.id.box3,R.id.box4,R.id.box5};
for(int i = 0; i<5; i++){
imageButtons[i] = (ImageButton) findViewById(imageIds[i]);
imageButtons[i].setBackgroundResource(R.drawable.blank);
}
What I would like to have it do is scale the width to fit neatly side-by-side at the bottom of the screen (which it does now ok), but have the height automatically scale to match the width as well. is this possible? I don't want to use setImageSource because then it puts a border around the imagebutton.
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/layoutButtons">
<com.package.SquareButton
android:layout_height="fill_parent"
android:layout_width="0dip"
android:layout_weight="1"
<ImageView
android:id="#+id/box1"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"/>
</com.package.SquareButton>
<com.package.SquareButton
android:layout_height="fill_parent"
android:layout_width="0dip"
android:layout_weight="1"
<ImageView
android:id="#+id/box2"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"/>
</com.package.SquareButton>
.........
</LinearLayout>
And then add this custom button class:
public class SquareButton extends LinearLayout {
public SquareButton(Context context) {
super(context);
}
public SquareButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
// This is used to make square buttons.
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
}
I have had a similar headache in trying to get my buttons in a row. The solution I found was to use ImageButton and the android:src property (setImageSource in code) in combination with android:background="#null"
As I understand it the background of an image button doesn't get affected by the adjustViewBounds, it is only the imageView which you set in android:src.
The default behavior is then to give you a square button with the imageView in the middle of it. You can override that by setting the background to #null, which leaves you with only the image.
You can then use either a LinearLayout or a table to layout your buttons. I did everything in XML and used the following layout to create a row of two buttons at the bottom of the screen that scale up or down maintaining the aspect ratio with different device screens sizes. Hope this helps.
<TableLayout
android:id="#+id/tableLayout2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dip"
android:stretchColumns="*">
<TableRow>
<ImageButton
android:id="#+id/button_one"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:layout_weight="0.5"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:onClick="clickOne"
android:background="#null"
android:src="#drawable/button_one_drawable" />
<ImageButton
android:id="#+id/button_two"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:layout_weight="0.5"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:onClick="clickTwo"
android:background="#null"
android:src="#drawable/button_two_drawable" />
</TableRow>
</TableLayout>
Instead of
android:scaleType="fitXY"
use:
android:scaleType="centerInside"
EDIT1: Try this one:
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/layoutToInflateButtons"
>
<ImageButton
android:id="#+id/box1"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:layout_weight="1"
android:layout_margin="1dp"
/>
</LinearLayout>
You can use Google's Percent Relative Layout that helps you to manage view aspect ratio.
You can use it like this
<android.support.percent.PercentRelativeLayout
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="match_parent">
<ImageButton
android:id="#+id/box1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:scaleType="fitXY"
app:layout_aspectRatio="100%"
android:layout_weight="1"
/>
</android.support.percent.PercentFrameLayout>
The aspect ratio 100% will make width same as height.
example:
android:layout_width="300dp"
app:layout_aspectRatio="178%"
a width 178% of the height. This is the format the layout_aspectRatio expects
You can read it in detail here
I am sure you want to have that 5 buttons of EQUAL width/height. If this is the case then take LinearLayout and put all those 5 buttons with layout_width="0dip" and layout_weight="1"
For example:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/layoutButtons">
<ImageButton
android:id="#+id/box1"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:layout_height="wrap_content"
android:layout_width="0dip"
android:layout_weight="1"/>
<ImageButton
android:id="#+id/box2"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:layout_height="wrap_content"
android:layout_width="0dip"
android:layout_weight="1"/>
.........
</LinearLayout>
After checking Google I/O sample application from this year I've found that Google is using dimen values for specifying varios heights or widths based on the screen type. For details you can check the source code from http://code.google.com/p/iosched/.
You can specify the height of the button for exemple in values-xhdpi or values-sw720dp as:
<resources>
<dimen name="button_height">50dp</dimen>
</resources>
And then you can just use this dimen value when specifying the height:
android:layout_height="#dimen/button_height"
Set the width of the ImageButtons to fill_parent and use scaletype fitStart for the images that hug the left margin, and fitEnd for the ones on the right. Should do the trick, at least as far as your example image goes. You may have some spacing issues if the proportional width of the images exceed the screen width, but it should work for you.
ViewGroup.LayoutParams params = imageButtonName.getLayoutParams();
// Changes the height(or width) and width(or height) to the specified
params.height = layout.getWidth();
Look into making a custom ImageButton. I like this because its one class. Here is a button that adjusts its height based on the image aspect ratio. I imagine you can tweak to your needs :
public class AspectImageButton extends ImageButton {
public AspectImageButton(Context context) {
super(context);
// TODO Auto-generated constructor stub
this.getDrawable();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
Drawable d=this.getDrawable(); //grab the drawable
float fAspectRatio=(float)d.getIntrinsicWidth()/(float)d.getIntrinsicHeight();
float fHeight=(float)width/fAspectRatio;//get new height
setMeasuredDimension(width, (int)fHeight);
}
public AspectImageButton(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public AspectImageButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
}
then in xml just use it like this:
<com.package.AspectImageButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="#drawable/home_1b"
android:background="#null"
android:scaleType="fitXY"
android:adjustViewBounds="true" />
Related
Is it possible that a view should make it height same as it's width?
or any other layout for this purpose, because for vector image it's compulsory to provide width and height.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/googleLoginBtn"
android:orientation="horizontal"
android:layout_centerVertical="true">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:layout_width="fill_parent"
android:layout_height="<height should be equal to the width>"
app:srcCompat="#drawable/simple"
tools:ignore="MissingPrefix"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Snappy"
android:textColor="#FF4081"
android:textSize="30dp"
android:singleLine="true"
android:gravity="center"
android:layout_margin="10dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Type less, do more. Fastest way to transfer money & make other transactions."
android:layout_margin="10dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="#drawable/simple"
tools:ignore="MissingPrefix"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Smart"
android:textColor="#FF4081"
android:textSize="30dp"
android:gravity="center"
android:layout_margin="10dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Type less, do more. Fastest way to transfer money & make other transactions."
android:layout_margin="10dp"/>
</LinearLayout>
</LinearLayout>
Update:
I would use a ConstraintLayout today and use the property app:layout_constraintDimensionRatio="1:1"
Old Answer:
It's not possible entirely in xml without using a custom ImageView. This would be a solution:
public class SquareImageView extends ImageView {
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
setMeasuredDimension(width, width);
}
}
However if your Image is already Square you can use the normal ImageView:
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:adjustViewBounds="true" />
A third solution would be setting the width and height directly in your Code:
LayoutParams params = imageView.getLayoutParams();
params.height = params.width ;
imageView.setLayoutParams(params);
You should be able to use the Percent support library for this.
You can either replace the LinearLayout the ImageViewis inside of with a PercentRelativeLayout and have the other views android:layout_belowor wrap the ImageView in a PercentFrameLayout.
I'm going to assume you've already defined the app namespace in this file as xmlns:app="http://schemas.android.com/apk/res-auto" since I see you using the namespace.
Once you've included the appropriate support library, the PercentFrameLayout approach would look something like this:
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<android.support.percent.PercentFrameLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="fill_parent"
app:layout_aspectRatio="100%"
app:srcCompat="#drawable/simple"
tools:ignore="MissingPrefix"/>
</android.support.percent.PercentFrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Snappy"
android:textColor="#FF4081"
android:textSize="30dp"
android:singleLine="true"
android:gravity="center"
android:layout_margin="10dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Type less, do more. Fastest way to transfer money & make other transactions."
android:layout_margin="10dp"/>
</LinearLayout>
Just a little update: The PercentFrameLayout class was deprecated in API level 26.1.0. Consider using ConstraintLayout and associated layouts instead. More information here: https://developer.android.com/reference/android/support/percent/PercentFrameLayout
use this
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
int myWidth = (int) (parentHeight * 0.5);
super.onMeasure(MeasureSpec.makeMeasureSpec(myWidth, MeasureSpec.EXACTLY), heightMeasureSpec);
}
I have this layout:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioGroup
android:id="#+id/MyTabs"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RadioButton ... />
<RadioButton ... />
</RadioGroup>
<SquareImageView
android:layout_height="match_parent" />
</LinearLayout>
and here's the code for the SquareImageView:
public class SquareImageView extends ImageView {
public SquareImageView(Context context) {
super(context);
}
public SquareImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int size = getMeasuredHeight();//Math.min(getMeasuredWidth(), getMeasuredHeight());
setMeasuredDimension(size, size);
}
}
Now, what I want to achieve is this:
I want the RadioGroup to occupy as much space as possible. The height of the LinearLayout should adapt to the required height of the RadioGroup. Each RadioButton should occupy 50% of the RadioGroup. The SquareImageView should adapt it's height to match the height of the LinearLayout, and it's width should also adapt to make it square.
Is this even possible?
The RadioGroup is no problem on it's own, but the tricky part is the square ImageView because I cannot get it to adapt it's width automatically. It is square, but I need to set the width of it manually. If I do not set a width manually it seems to be square (in the Eclipse Preview Layout Manager) but it ends up outside of the screen and the RadioGroup occupies the entire screen width. If I set a too wide width there is dead space to the right of it.
Tried fiddling with all kinds of settings but nothing gets it quite right. I would like to avoid setting dimensions in absolute values, and rather let the height of the RadioGroup determine the rest of the Views' dimensions...
Try this:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioGroup
android:id="#+id/MyTabs"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weig="1" >
<RadioButton
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
... />
<RadioButton
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
... />
</RadioGroup>
<SquareImageView
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
You can try below steps:
1, Set the layout as below:
<RadioGroup
android:id="#+id/MyTabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="1" >
<RadioButton
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"
... />
<RadioButton
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"
... />
</RadioGroup>
<SquareImageView
android:layout_width="0dp"
android:layout_height="match_parent" />
2, Once the view loads, programatically find the height of linear layout and then programatically set the width of the squareview to this same value to make it a square
3, Find the width of the screen and then set the width of the radio group to the difference between screen width and above sqaureview width so that it occupies the remaining screen width.
I have such layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/my_image"
android:ellipsize="end"
android:singleLine="true"
android:text="Some text"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="#+id/my_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/title"
android:layout_alignBottom="#+id/title"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:src="#drawable/my_bitmap_image" />
This layout does almost what I need: it makes image view height the same as text view. The image graphic contents stretched also keeping aspect ratio.
But, the width of the image view does not change! As a result, I have a wide gap between text and the image view! As a temporal solution, I override View#onLayout.
The question: how to change image width in xml layout?
UPDATE:
This is a final layout I need (text + a few images).
Look at the first image: its width should be exactly the same as scaled image in it with no paddings and margins:
For the imageView you can add the images to a linearlayout and give the weight property. For example if you have 3 images then give the linearlayout weight as 3 and then for each image you give the weight as 1. This way it will be uniformly aligned with equal width for all the images. Make linear orientation as horizontal hope so u got my point.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="3"
>
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight ="1" />
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight ="1" />
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight ="1" />
</LinearLayout>
OK, as I see from the answers, there is no solution to force image views to change theirs width and height proportionally.
So, this can be solved only programmatically.
There is my solution below :
a) Create you custom layout class
(don't forget to override all the parent constructors with public access modifier, otherwise GUI editor will fail):
public class MyLayout extends RelativeLayout {...
b) Override method: Deprecated - changing layout params in this method might cause side effects. See recommended approach below
protected void onLayout(boolean changed, int l, int t, int r, int b) {
ImageView icon = (ImageView) findViewById(R.id.my_image);
icon.setMaxWidth(icon.getMeasuredHeight());
super.onLayout(changed, l, t, r, b);
}
b) Add creational method:
public static MyLayout createLayout(ViewGroup parent) {
Context context = parent.getContext();
MyLayout item = (MyLayout) LayoutInflater.from(context).inflate(
R.layout.my_layout, parent, false);
TextView tv = (TextView) findViewById(R.id.title);
ImageView icon = (ImageView) findViewById(R.id.my_image);
ViewGroup.LayoutParams p = icon.getLayoutParams();
p.width = (int) tv.getTextSize();;
icon.setLayoutParams(p);
return item;
}
c) Final layout:
<?xml version="1.0" encoding="utf-8"?>
<com.mypackage.MyLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/my_image"
android:ellipsize="end"
android:singleLine="true"
android:text="Some text"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="#+id/my_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/title"
android:layout_alignBottom="#+id/title"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:src="#drawable/my_bitmap_image" />
</com.mypackage.MyLayout>
Instead of RelativeLayout, use LinearLayout. You may add "Weight" property to ensure desired spacing.
see the code below
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/logonFormButtons"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:orientation="horizontal">
<TextView
android:id="#+id/logonFormBTLogon"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Some Text"
android:layout_weight="0.5" />
<ImageView
android:id="#+id/logonFormBTCancel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="#drawable/apk"
android:layout_weight="0.5" />
</LinearLayout>
I guess this has to do with android:layout_alignParentRight="true" for your ImageView. Have you tried layout_toRightOf="#id/title" ?
Also you can try android:scaleType="fitStart" on the ImageView. This should align the image to the top left of the ImageView.
As for me I appreciate to change width or height dinamically in my code using getLayoutParams()... for example
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int wwidth = displaymetrics.widthPixels;
convertPixelsToDp(wwidth, getApplicationContext());
// Toast.makeText(getApplicationContext(), height+ "= "+convertPixelsToDp(height, getApplicationContext()) +
// " " + wwidth+ "= "+convertPixelsToDp(wwidth, getApplicationContext()), Toast.LENGTH_LONG).show();
//scroll view 1 screen height size
scr1 = (ScrollView) findViewById(R.id.ScrollView01);
scr1.getLayoutParams().height=height - 200;
put image view in Linear Layout . the give weight to each and every image view.. it will increase the size proportionately ..
try to add scaleType = fitXY OR centerInside property to imageView
I have the following GridView defined w/stretchMode set to "columnWidth".
<GridView android:id="#+id/grid"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:columnWidth="160dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:listSelector="#drawable/list_selector"
/>
Each item in the GridView is structured as follows.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="2dp"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<ImageView android:id="#+id/videoGridItemImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
/>
<TextView android:id="#+id/videoGridItemDuration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#88000000"
android:textColor="#F1F1F1"
android:textAppearance="#android:style/TextAppearance.Small"
android:padding="2dp"
/>
</FrameLayout>
<TextView android:id="#+id/videoGridItemTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:textAppearance="#android:style/TextAppearance.Medium"
android:textColor="#F1F1F1"
android:maxLines="1"
android:background="#88000000"
android:paddingLeft="2dp"
android:paddingRight="2dp"
/>
<TextView android:id="#+id/videoGridItemSubtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:textStyle="italic"
android:textColor="#666"
android:textAppearance="#android:style/TextAppearance.Small"
android:maxLines="1"
android:background="#88000000"
android:paddingLeft="2dp"
android:paddingRight="2dp"
/>
</LinearLayout>
In the GridView's adapter, I'm async loading and displaying the images by passing the url and reference of the ImageView to a dedicated class. The class downloads the image into a bitmap and then updates the ImageView using setImageBitmap(). This workflow functions as expected; however, my images aren't filling the entire width of the ImageView. There's a small amount of paddding on the left/right sides. I realize that I can use scaleType="fitXY", but this isn't ideal as it skews the images. Setting the src attribute of ImageView to a local image scales just fine with stretchMode="columnWidth". My guess is that the ImageView is scaling to the original columnWidth and not the stretched/dynamic width. Does anyone have any insight as to why this is occurring and/or how to fix? Thanks in advance for your help.
You have two options:
Set your ImageView's layout_width to wrap_content. The ImageView will resize based on the size of the image and your column will adjust accordingly.
Set your ImageView's scaleType to centerCrop. This will try to fit the image into the imageview without skewing it and will just cut off any excess that doesn't fit. This will leave no blank space.
I had the same issue. My solution was to override the ImageView (in my case) FrameLayout to set it's height prior to image download. I wanted square tiles enforced in my GridView, and accomplished like so:
public class SquareFrameLayout extends FrameLayout {
public SquareFrameLayout(Context context) {
super(context);
}
public SquareFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareFrameLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
}
Each GridView item is this:
<com.my.client.ui.layout.SquareFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/discovery_tile"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="#+id/my_image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:cropToPadding="true"
android:contentDescription="#string/my_desc" />
</com.my.client.ui.layout.SquareFrameLayout>
Then in the GridView I used this:
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:name="com.my.client.ui.MyFragment"
android:id="#+id/my_gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="3"
android:verticalSpacing="0px"
android:horizontalSpacing="0px"
android:stretchMode="columnWidth"
android:gravity="fill" />
In my horizontal LinearLayout I have a TextEdit and an ImageButton. The ImageButton is as high as the TextEdit.
I'd like that the ImageButton is exactly as wide as it's long.
At the moment it looks like the width of the ImageButton is like when there is no scaling (ImageButton width [px] = unscaled drawable width [px]):
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText
android:id="#+id/txtName"
android:layout_width="1dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ImageButton
android:id="#+id/btSet"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:scaleType="fitEnd"
android:src="#drawable/pin2" />
</LinearLayout>
How it should look like:
Try this, I think this should work:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal" >
<ImageButton
android:id="#+id/btSet"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:scaleType="centerInside"
android:adjustViewBounds="true"
android:src="#drawable/pin2" />
<EditText
android:id="#+id/txtName"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toLeftOf="#id/btSet" />
</RelativeLayout>
Explaination: centerInside will assure that the image will scale proportionally within the bounds of the ImageButton. adjustViewBounds="true" will...well, adjust the view's bounds, if the image needed to be scaled.
try adding
adjustViewBounds="true"
to the ImageButton, that should clip the excess width
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText
android:id="#+id/txtName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ImageButton
android:id="#+id/btSet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="#drawable/pin" />
</LinearLayout>
Use
android:scaleType="fitCenter"
or android:scaleType="centerInside"
in the ImageButton in xml File.
I might be a bit late to the party.
However there's an easy way to achieve this behavior by overriding the onMeasure().
Here's how it'd look like :
public class MySquareImageButton extends ImageButton {
public MySquareImageButton(Context context) {
super(context);
}
public MySquareImageButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MySquareImageButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//(1)if you want the height to match the width
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
//(2)if you want the width to match the height
//super.onMeasure(heightMeasureSpec, heightMeasureSpec);
}
}
And then you'd simply replace your XML's ImageButton with this custom one :
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText
android:id="#+id/txtName"
android:layout_width="1dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.whatever_your_package.MySquareImageButton
android:id="#+id/btSet"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:scaleType="fitEnd"
android:src="#drawable/pin2" />
</LinearLayout>
You'd simply put wrap_content to width or height, depending on which one you want to dictate the size of your button.
In the case you want your button to wrap its height to the image, and that the width simply matches the height, you'd use
android:layout_width="wrap_content"
android:layout_height="wrap_content"
and use
//(2)if you want the width to match the height
//super.onMeasure(heightMeasureSpec, heightMeasureSpec);
I had the same problem.
I was trying to create something that looked like this:
But what I was getting was this:
The ImageButton was getting stretched horizontally.
All the top answers didn't work for me. But I noticed people mentioning layout_weight and just looked it up out of curiosity and found the following on Android docs:
Layout Weight
LinearLayout also supports assigning a weight to individual children with the android:layout_weight attribute. This attribute assigns an "importance" value to a view in terms of how much space it should occupy on the screen. A larger weight value allows it to expand to fill any remaining space in the parent view. Child views can specify a weight value, and then any remaining space in the view group is assigned to children in the proportion of their declared weight. Default weight is zero.
For example, if there are three text fields and two of them declare a weight of 1, while the other is given no weight, the third text field without weight will not grow and will only occupy the area required by its content. The other two will expand equally to fill the space remaining after all three fields are measured. If the third field is then given a weight of 2 (instead of 0), then it is now declared more important than both the others, so it gets half the total remaining space, while the first two share the rest equally
So basically, if you set the layout_width to be 0 for an element, it'll appear according to the dimensions of its content.
If you set it to anything else, the element will fight for extra space in the parent element that contains it; with more weighted elements taking up more space.
So, when I set layout_width = 0 for both TextView and ImageButton in my example, neither of them takes up any extra space and they both huddle up to the left.
But when I set it to 1 for TextView and 0 for ImageButton, the ImageButton doesn't take any more space than required by its content; while the TextView takes up all the extra space and pushes ImageButton to the right.
Just the way I want it.
Initially, what had happened was both the elements were set to have a default layout_weight of 1 and hence both were equally competing for the extra space.
Simply use the weightSum to devide the size of controls accordingly...
<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1.0" >
<EditText
android:id="#+id/txtName"
android:layout_weight="0.8"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:inputType="text"
android:singleLine="true"/>
<ImageButton
android:id="#+id/btSet"
android:layout_weight="0.2"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:scaleType="fitEnd"
android:src="#drawable/pin2" />
</LinearLayout>
</LinearLayout>
Hope it will help you.
as you want your ImageButton is stretchable & exactly as wide as it's long, its better to use NinePatch Image. you may find help form here Draw 9-patch & How does Android’s nine-patch tool work ?
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1.0" >
<EditText
android:id="#+id/txtName"
android:layout_weight="0.75" // this work like percentage adjust as u want 70 or 75
android:layout_height="wrap_content"
android:layout_width="0dp"
android:inputType="text"
android:singleLine="true"/>
<ImageButton
android:id="#+id/btSet"
android:layout_weight="0.25" // this work like percentage adjust as u want 25 or 30
android:layout_height="wrap_content"
android:layout_width="0dp"
android:scaleType="fitEnd"
android:src="#drawable/pin2" />
</LinearLayout>
Just add the following line to your ImageButton and the extra background will fade away:
android:layout_gravity="center|clip_horizontal"
hope this works
Just ran into something like this and the other suggestions didn't help. What did help was setting the padding in the ImageButton:
android:padding="5dp"
Besides that, I didn't touch the original layout. The button became square on the 3 emulators that I tested (3.2, 4.4.2, 5.1)
I tried myself,it works
Simply do the Following...
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="#+id/editText1"
android:layout_width="0dp"
android:layout_weight="5"
android:layout_height="wrap_content"
android:inputType="text"/>
<ImageButton
android:id="#+id/imageButton"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
</LinearLayout>
Use Layout Weight ratio 5:1 inside a LinearLayout for EditText and ImageButton
You Can resize the Image button using px... like below...
`android:layout_width="5px"
android:layout_height="5px"`