How do I keep the aspect ratio on image buttons in android?

穿精又带淫゛_ 提交于 2019-11-27 00:56:51
neteinstein
   <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);
    }
}
leafcutter

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" />
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!