如何实现不拉伸的android:background?


100

我发现了一个很棒的线程,描述了如何“吃蛋糕,也要吃蛋糕”,即使用image Button代替ImageButton(不允许SetText(),调整大小等)。

这是通过使用View属性来实现的:

android:background="@drawable/bgimage"

唯一的问题是它会拉伸图像以适合按钮大小。

缺少对固定的按钮大小(以像素为单位!)进行硬编码的方法,有没有办法告诉Android 不要完全拉伸背景图像,而不是裁剪或填充背景图像?

Answers:


29

如果您不希望它拉伸,则应使用ImageView。背景图像将始终拉伸以适合视图。您需要将其设置为Drawable,以将图像外观强制到对象。

否则,如果您坚持使用Button的想法,则需要在按钮中强制缩放,以防止图像拉伸。

码:

onCreate(Bundle bundle) {
  // Set content layout, etc up here

  // Now adjust button sizes
  Button b = (Button) findViewById(R.id.somebutton);
  int someDimension = 50; //50pixels
  b.setWidth(someDimension);
  b.setHeight(someDimension);
}

1
谢谢+ 1. ImageView看起来很有趣。我注意到它,这不是在一个属性Buttonandroid:cropToPadding。我不介意使用ImageView,只要它具有setOnClickListener()功能即可。从切换到Button,我将失去什么ImageView
ef2011 2011年

1
顺便说一句,您建议的第二个解决方案仍然可以拉伸图像。
ef2011 2011年

我最终使用了固定的按钮大小(以像素为单位!),但我接受了您的回答,因为第一个建议看起来像是一种可行的替代解决方案。
ef2011 2011年

1
@ ef2011对于ImageView,不要将其设置为背景图像,而必须将其设置为a setDrawableResource,然后确保setAdjustViewBounds将其设置为true
Dr.J.11年

9
投票赞成for脚的解决方案。此处的正确解决方案:stackoverflow.com/a/9362168/145046
Aleks N. 2012年

260

您可以创建一个xml位图,并将其用作视图的背景。为了防止拉伸,您可以指定android:gravity属性。

例如:

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/dvdr"
    android:tileMode="disabled" android:gravity="top" >
</bitmap>

您可以使用很多选项来自定义图像的渲染

http://developer.android.com/guide/topics/resources/drawable-resource.html#Bitmap


真棒答案哥们!
Carnal

3
使用ImageViews是一种解决方法,并非总是可行的选择-我认为这是正确的解决方案:)
JakeP 2014年

3
我在运行时设置背景。是否有在运行时创建位图的解决方案?
Vivek Kumar Srivastava 2014年

1
对我来说,这是最好的解决方案,但是删除了“ gravity”属性,这使其与默认值“ fill”相匹配。这将允许调整图像大小以适合屏幕。请研究@Santosh链接以获取更多信息。谢谢!
雨果

12
我只看到这种方法的一个问题。如果可绘制源已经大于容器,则它将裁剪图像(基于重力),而不是调整其大小(保持宽高比)以适合容器。
Shashwat Black

25

简单地使用ImageButton代替而不是Button解决问题。

<ImageButton android:layout_width="30dp"
             android:layout_height="30dp"
             android:src="@drawable/bgimage" />

你可以设置

android:background="@null"

如果需要,删除按钮背景。

快速解决 !!:-)


1
然后使用对我有用的setImageResource()方法设置图像。
arlomedia

我希望按钮中既有图像颜色又有背景颜色...这就像一种魅力
Abhishek Chauhan 2014年

它对我来说更准确(例如,我的意思是“ layout_centerVertical”)。
Maxim Firsoff

11

我在RelativeLayout中使用了与我的常规布局重叠的ImageView。无需代码。它将图像缩放到屏幕的整个高度(或您使用的任何其他布局),然后左右裁剪图像以适应宽度。在我的情况下,如果用户转动屏幕,则图片可能会有点太小。因此,我使用match_parent,如果太小,它将使图像在宽度上拉伸。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/main_backgroundImage"
        android:layout_width="match_parent"
        //comment: Stretches picture in the width if too small. Use "wrap_content" does not stretch, but leaves space

        android:layout_height="match_parent"
        //in my case I always want the height filled

        android:layout_alignParentTop="true"
        android:scaleType="centerCrop"
        //will crop picture left and right, so it fits in height and keeps aspect ratio

        android:contentDescription="@string/image"
        android:src="@drawable/your_image" />

    <LinearLayout
        android:id="@+id/main_root"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    </LinearLayout>

</RelativeLayout>

一个问题这实际上更容易的解决方案,不应该存在
AKOSNikházy


5

使用Android Studio SDK工具中包含的draw9patch ...。您可以定义图像的可拉伸区域。重要部分受到约束,图像看起来并没有全部变形。这里是dra9patch的一个很好的演示

使用draw9patch将现有的splash.png更改为new_splash.9.png,将new_splash.9.png拖动到drawable-hdpi项目文件夹中,确保AndroidManifest和styles.xml如下所示正确:

AndroidManifest.xml:

<application
...
        android:theme="@style/splashScreenStyle"
>

styles.xml:

<style name="splashScreenStyle" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:windowBackground">@drawable/new_splash</item>
</style>

3

我有一张背景图片,虽然尺寸不大,但是尺寸很奇怪-因此拉伸效果很差。我用参数Context,View和可绘制的ID(int)制作了一个与设备屏幕尺寸匹配的方法。在Fragments onCreateView中使用它来设置背景。

public void setBackground(Context context, View view, int drawableId){
    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),drawableId);

    bitmap = Bitmap.createScaledBitmap(bitmap, Resources.getSystem().
             getDisplayMetrics().widthPixels,
             Resources.getSystem().getDisplayMetrics().heightPixels,
             true);

    BitmapDrawable bitmapDrawable = new BitmapDrawable(context.getResources(), 
                                    bitmap);

    view.setBackground(bitmapDrawable);
}

1

这是Santosh针对以编程方式创建的按钮的答案的一个版本,不需要单独的XML配置:

Button button = new Button(getContext());
Bitmap backgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_button);
BitmapDrawable backgroundDrawable = new BitmapDrawable(getResources(), backgroundBitmap);
backgroundDrawable.setGravity(Gravity.CENTER); // also LEFT, CENTER_VERTICAL, etc.
backgroundDrawable.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_ATOP));
button.setBackground(backgroundDrawable);

我加入了ColorFilter行,因为它的作用与带有普通背景图像的按钮有些不同。


1

您可以将FrameLayoutImageView用作第一个孩子,然后将常规布局用作第二个孩子:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <ImageView
        android:id="@+id/background_image_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@drawable/your_drawable"/>

  <LinearLayout
        android:id="@+id/your_actual_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

  </LinearLayout>

</FrameLayout>

0

关键是将可绘制对象设置为按钮的图像,而不是背景。像这样:

rb.setButtonDrawable(R.drawable.whatever_drawable);

这是CompoundButton的方法,而不是Button的方法。
arlomedia

0

可以在xml中使用普通的ImageView并使它可点击(android:clickable =“ true”)吗?您只需要使用形状像按钮(即圆角)的图像作为src。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.