Làm thế nào để triển khai android: background không bị giãn?


100

Tôi tìm thấy chủ đề tuyệt vời này mô tả cách "ăn bánh và ăn cả nó nữa", tức là sử dụng hình ảnh Buttonthay vì ImageButton(không cho phép SetText(), thay đổi kích thước, v.v.).

Điều này đạt được bằng cách sử dụng thuộc tính View:

android:background="@drawable/bgimage"

Vấn đề duy nhất với điều này là nó kéo dài hình ảnh để phù hợp với kích thước nút.

Thiếu mã hóa cứng kích thước nút cố định (tính bằng pixel!), Có cách nào để yêu cầu Android không kéo giãn hình nền và cắt hoặc đệm nó không?

Câu trả lời:


29

Bạn nên sử dụng ImageView nếu không muốn nó bị giãn ra. Hình nền sẽ luôn kéo dài để vừa với chế độ xem. Bạn cần đặt nó là một Drawable để buộc khía cạnh hình ảnh vào đối tượng.

Ngược lại, nếu bạn đang theo đuổi ý tưởng Nút, thì bạn sẽ cần phải ép tỷ lệ trong nút để ngăn hình ảnh bị kéo giãn.

Mã:

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
Cảm ơn + 1. ImageViewtrông thú vị. Tôi nhận thấy nó có một thuộc tính mà không có trong Button: android:cropToPadding. Thay vào đó, tôi không ngại sử dụng ImageView, miễn là nó có setOnClickListener()- điều mà nó làm được. Tôi sẽ mất gì khi chuyển từ Buttonsang ImageView?
ef2011

1
BTW, giải pháp thứ 2 bạn đề xuất vẫn kéo dài hình ảnh.
ef2011

Tôi đã kết thúc bằng cách sử dụng kích thước nút cố định (tính bằng pixel!) Nhưng tôi chấp nhận câu trả lời của bạn vì gợi ý đầu tiên có vẻ như một giải pháp thay thế hoạt động.
ef2011

1
@ ef2011 Đối với ImageView, không đặt nó làm hình nền, bạn phải đặt nó làm hình nền setDrawableResourcevà sau đó đảm bảo setAdjustViewBoundsđược đặt thành true
Dr.J

9
Bỏ phiếu cho một giải pháp khập khiễng. Giải pháp chính xác ở đây: stackoverflow.com/a/9362168/145046
Aleks N.

260

Bạn có thể tạo một bitmap xml và sử dụng nó làm nền cho chế độ xem. Để tránh kéo căng, bạn có thể chỉ định android:gravitythuộc tính.

ví dụ:

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

Có rất nhiều tùy chọn bạn có thể sử dụng để tùy chỉnh kết xuất hình ảnh

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


Câu trả lời tuyệt vời bạn thân!
Carnal

3
Sử dụng ImageViews là một cách giải quyết mà không phải lúc nào cũng là một lựa chọn tốt - Tôi tin rằng đây là giải pháp đúng đắn :)
JakeP

3
Tôi đang thiết lập nền lúc chạy. Có giải pháp nào để tạo bitmap lúc chạy không?
Vivek Kumar Srivastava

1
đối với tôi đây là giải pháp tốt nhất nhưng loại bỏ thuộc tính "trọng lực", điều này làm cho nó khớp với giá trị mặc định "lấp đầy". Điều này sẽ cho phép thay đổi kích thước hình ảnh để phù hợp với màn hình. Nghiên cứu liên kết @Santosh để biết thêm thông tin. Cảm ơn!
Hugo

12
Tôi chỉ thấy một vấn đề với cách tiếp cận này. Nếu nguồn có thể kéo được đã lớn hơn vùng chứa, điều này sẽ cắt hình ảnh (dựa trên trọng lực) thay vì thay đổi kích thước nó, duy trì tỷ lệ khung hình, để vừa với vùng chứa.
Shashwat Black

25

Chỉ cần sử dụng ImageButtonthay vì Buttonkhắc phục sự cố.

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

và bạn có thể đặt

android:background="@null"

để xóa nền nút nếu bạn muốn.

Sửa nhanh !! :-)


1
Và sau đó đặt hình ảnh bằng phương thức setImageResource () ... phù hợp với tôi.
arlomedia

tôi muốn cả hai hình ảnh và màu nền trong một nút ... này làm việc như một nét duyên dáng
Abhishek Chauhan

Nó hoạt động chính xác hơn đối với tôi (ý tôi là - "layout_centerVertical", chẳng hạn).
Maxim Firsoff

11

Tôi đang sử dụng ImageView trong RelativeLayout phủ lên bố cục thông thường của tôi. Không cần mã. Nó định kích thước hình ảnh bằng toàn bộ chiều cao của màn hình (hoặc bất kỳ bố cục nào khác mà bạn sử dụng) và sau đó cắt hình ảnh sang trái và phải để vừa với chiều rộng. Trong trường hợp của tôi, nếu người dùng xoay màn hình, hình ảnh có thể hơi quá nhỏ. Do đó, tôi sử dụng match_parent, nó sẽ làm cho hình ảnh bị kéo dài theo chiều rộng nếu quá nhỏ.

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

Đây thực sự là một giải pháp dễ dàng hơn nhiều cho một vấn đề mà không nên tồn tại
Ákos Nikházy

6

Tôi gặp vấn đề tương tự: bạn chỉ nên sử dụng hình ảnh 9 bản vá (.9.png) thay vì hình ảnh gốc của bạn.

Serge


5

Sử dụng draw9patch ... có trong các công cụ SDK của Android Studio. Bạn có thể xác định các vùng có thể co giãn của hình ảnh của bạn. Các phần quan trọng bị hạn chế và hình ảnh trông không bị cong vênh. Một bản demo tốt về dra9patch là TẠI ĐÂY

Sử dụng draw9patch để thay đổi splash.png hiện có của bạn thành new_splash.9.png, kéo new_splash.9.png vào thư mục dự án drawable-hdpi đảm bảo AndroidManifest và styles.xml phù hợp như bên dưới:

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

Tôi đã có một hình nền, kích thước không lớn, nhưng có kích thước kỳ lạ - do đó kéo dài và hiệu suất kém. Tôi đã tạo một phương thức với các tham số Context, View và một ID có thể kéo được (int) sẽ phù hợp với kích thước màn hình thiết bị. Sử dụng điều này trong ví dụ như một Fragment onCreateView để đặt nền.

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

Đây là phiên bản câu trả lời của Santosh dành cho các nút được tạo theo chương trình, không cần cấu hình XML riêng:

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

Tôi đã bao gồm dòng ColorFilter vì nó hoạt động hơi khác so với các nút có hình nền bình thường.


1

Bạn có thể sử dụng a FrameLayoutvới một ImageViewlàm con đầu tiên, sau đó sử dụng bố cục bình thường của bạn làm con thứ hai:

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

Điều quan trọng là đặt có thể vẽ được làm hình ảnh của nút, không phải làm nền. Như thế này:

rb.setButtonDrawable(R.drawable.whatever_drawable);

Đây là một phương thức của CompoundButton nhưng không phải của Button.
arlomedia

0

Người ta có thể sử dụng ImageView đơn giản trong xml của mình và làm cho nó có thể nhấp được (android: clickable = "true") không? Bạn chỉ phải sử dụng như src một hình ảnh có hình dạng giống như một nút tức là các góc tròn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.