在安卓上如何保持图像按钮的纵横比?

37

我有5个正方形的ImageButton,想要它们在屏幕底部依次排列。我已经为每一个ImageButton设置了不同的id:

        <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"
         /> 

我在Java的主文件中这样指定了背景:

    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);
    }

我希望它能够自动缩放高度以匹配宽度,从而在屏幕底部整齐地并排显示(现在已经可以),但我不想使用setImageSource,因为这会在imagebutton周围添加边框。是否有可能实现这一点?

9个回答

34

我曾经也遇到过一样的问题,即如何将我的按钮排成一排。我发现的解决方法是使用 ImageButtonandroid:src 属性(在代码中为 setImageSource),同时结合 android:background="@null"

据我所知,图像按钮的背景不会受到 adjustViewBounds 的影响,只有你在 android:src 中设置的 imageView 会受到影响。

默认情况下,这将给你一个方形的按钮,其中 imageView 居中。你可以通过将背景设置为 @null 来覆盖它,这样只留下了图片。

然后,您可以使用 LinearLayout 或表格来布置按钮。我使用 XML 完成了所有操作,并使用以下布局创建了屏幕底部的两个按钮行,在不同的设备屏幕尺寸上缩放并保持纵横比。希望这能帮到你。

<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>

这就是我一直在寻找的答案!你的解释帮助我更好地理解了ImageButton。 :D - Brad
这是最好的答案。如果您想修复高度并希望宽度根据纵横比自动缩放,则非常有效。+1 - ricosrealm
干得好!折腾了一整天GridLayout,这个代码完美解决了问题。谢谢。 - BonanzaDriver
这个对我比SquareButton类更有效,因为那个类对我仍有一些裁剪问题,可能是因为布局管理器中没有被认为是“图像类型”。谢谢两位。 - MattMatt
工作得很好!但我无法将背景设置为null,所以我将其设置为透明:android:background="#00000000" - fersarr

34
   <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>

然后添加这个自定义按钮类:

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);
    }
}

终于成功了!对我来说,似乎应该有一种更简单的方法,但考虑到花了将近一年时间才得到一个对我有效的答案,我认为这就是它了。非常感谢! - clayton33
1
你能解释一下它们的区别吗? - neteinstein
最好把它命名为SquareLayout。 - Roel
如果 MeasureSpec.getMode(widthMeasureSpec)MeasureSpec.AT_MOST,那么这个解决方案就无法正常工作(当我将不同大小的相同图像放入不同的 drawable 文件夹中时,我遇到了这个问题)。 - FlorianT
如果这个答案能够结合解释,那就更好了。 - Matt Strom
显示剩余2条评论

12

不是使用

android:scaleType="fitXY" 

使用:

android:scaleType="centerInside"

编辑1: 尝试这个:

    <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>

1
聪明的回答(而且没有搞乱子类),谢谢! - Rick77
2
我必须将 android:layout_width="wrap_content"android:layout_height="0dp" 添加到 ImageButton,以使此代码正常工作。 - Roberto Lombardini

3
您可以使用 Google 的百分比相对布局,它可以帮助您管理视图的宽高比。您可以像这样使用它:
     <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>

百分之百的纵横比将使宽度与高度相同。

例子:

android:layout_width="300dp"
app:layout_aspectRatio="178%"

一个宽度为高度的178%。这是layout_aspectRatio所期望的格式。
您可以在此处详细阅读:这里

1

我相信你想要那5个按钮具有相等的宽度/高度。如果是这种情况,那么请使用LinearLayout,并将所有这些5个按钮放置在其中,使用layout_width="0dip"layout_weight="1"

例如:

<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>

不,我尝试了你的代码,它看起来像这样:http://i.imgur.com/3piDS.jpg 应该看起来像这个:http://imgur.com/4FFzD(忽略添加的边距)。我唯一使其正常工作的方法是通过改变边距和其他东西来欺骗它,但是当我切换到不同的显示尺寸,比如平板电脑时,它就会出现问题。所以现在我回到我的原始代码,尝试让它正常工作。这些图片的大小为90x90像素,如果这有帮助的话。 - clayton33

1

在查看今年的Google I/O示例应用程序后,我发现Google正在使用dimen值来指定基于屏幕类型的各种高度或宽度。有关详细信息,您可以从{{link1:http://code.google.com/p/iosched/}}检查源代码。

例如,您可以在values-xhdpi或values-sw720dp中指定按钮的高度:

 <resources>
    <dimen name="button_height">50dp</dimen>
</resources>

然后在指定高度时,您可以直接使用此dimen值:

android:layout_height="@dimen/button_height"

0

研究如何创建自定义的ImageButton。我喜欢它,因为它只需要一个类。这是一个可以根据图像纵横比调整高度的按钮。我想你可以根据自己的需求进行调整:

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
}

}

然后在 XML 中就可以像这样使用它:

<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" />

0
ViewGroup.LayoutParams params = imageButtonName.getLayoutParams();
// Changes the height(or width) and width(or height) to the specified 
params.height = layout.getWidth();

0
将ImageButtons的宽度设置为fill_parent,并对贴着左边缘的图像使用scaletype fitStart,对右侧的图像使用fitEnd。这应该可以解决问题,至少对于你的示例图像而言是如此。如果图像的比例宽度超过屏幕宽度,则可能会出现一些间距问题,但对你来说应该可以工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接