如何实现一个 android: 背景不伸缩?

我发现这个 好主意描述了如何“吃蛋糕,也吃蛋糕”,也就是说,使用图像的 Button而不是 ImageButton(这不允许 SetText(),调整大小等)。

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

android:background="@drawable/bgimage"

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

缺少固定按钮大小的硬编码(以像素为单位!)有没有办法告诉 Android 没有把背景图片拉长,或者剪裁或者垫起来?

118541 次浏览

You should use ImageView if you don't want it to stretch. Background images will always stretch to fit the view. You need to set it as a Drawable to force the image aspect to the object.

Otherwise, if you are sticking with the Button idea, then you will need to force the scaling in the button to prevent the image from stretching.

Code:

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

You can create an xml bitmap and use it as background for the view. To prevent stretching you can specify android:gravity attribute.

for example:

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

There are a lot of options you can use to customize the rendering of the image

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

The key is to set the drawable as the image of the button, not as a background. Like this:

rb.setButtonDrawable(R.drawable.whatever_drawable);

I had the same problem: you should only use a 9-patch image (.9.png) instead of your original picture.

Serge

I am using an ImageView in an RelativeLayout that overlays with my normal layout. No code required. It sizes the image to the full height of the screen (or any other layout you use) and then crops the picture left and right to fit the width. In my case, if the user turns the screen, the picture may be a tiny bit too small. Therefore I use match_parent, which will make the image stretch in width if too small.

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

Simply using ImageButton instead of Button fixes the problem.

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

and you can set

android:background="@null"

to remove button background if you want.

Quick Fix !! :-)

One can use a plain ImageView in his xml and make it clickable (android:clickable="true")? You only have to use as src an image that has been shaped like a button i.e round corners.

Here's a version of Santosh's answer for programmatically-created buttons, without the need for a separate XML configuration:

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

I included the ColorFilter line since that works a little differently from buttons with a normal background image.

Use draw9patch... included within Android Studio's SDK tools. You can define the stretchable areas of your image. Important parts are constrained and the image doesn't look all warped. A good demo on dra9patch is HERE

Use draw9patch to change your existing splash.png into new_splash.9.png, drag new_splash.9.png into the drawable-hdpi project folder ensure the AndroidManifest and styles.xml are proper as below:

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>

You can use a FrameLayout with an ImageView as the first child, then your normal layout as the second child:

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

I had a background image, not big in size, but with weird dimensions - therefore the stretching and bad performance. I made a method with parameters Context, a View and a drawable ID(int) that will match the device screen size. Use this in e.g a Fragments onCreateView to set the background.

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