วิธีใช้ Android: พื้นหลังที่ไม่ยืด?


100

ฉันพบกระทู้ที่ยอดเยี่ยมนี้อธิบายถึงวิธี "กินเค้กและมีมันด้วย" เช่นใช้รูปภาพButtonแทนImageButton(ซึ่งไม่อนุญาตให้SetText()ปรับขนาด ฯลฯ )

สิ่งนี้ทำได้โดยใช้แอตทริบิวต์ View:

android:background="@drawable/bgimage"

ปัญหาเดียวในเรื่องนี้คือการขยายภาพให้พอดีกับขนาดปุ่ม

ไม่มีการเข้ารหัสขนาดปุ่มคงที่ (เป็นพิกเซล!) มีวิธีที่จะบอก Android ว่าอย่ายืดภาพพื้นหลังเลยและครอบตัดหรือวางหรือไม่?

คำตอบ:


29

คุณควรใช้ImageViewถ้าคุณไม่ต้องการให้มันยืด ภาพพื้นหลังจะยืดออกเพื่อให้พอดีกับมุมมองเสมอ คุณต้องตั้งค่าเป็น Drawable เพื่อบังคับลักษณะภาพไปที่วัตถุ

มิฉะนั้นหากคุณยึดติดกับแนวคิดปุ่มคุณจะต้องบังคับให้ปรับขนาดในปุ่มเพื่อป้องกันไม่ให้ภาพยืดออก

รหัส:

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ดูน่าสนใจ ผมสังเกตเห็นก็มีแอตทริบิวต์ที่ไม่ได้อยู่ใน:Button android:cropToPaddingฉันไม่รังเกียจที่จะใช้ ImageView แทนตราบใดที่มันมีsetOnClickListener()- ซึ่งมันทำได้ ฉันจะสูญเสียอะไรเมื่อเปลี่ยนจากButtonเป็นImageView?
ef2011

1
BTW วิธีที่ 2 ที่คุณแนะนำยังคงยืดภาพ
ef2011

ฉันลงเอยด้วยการใช้ขนาดปุ่มคงที่ (เป็นพิกเซล!) แต่ฉันยอมรับคำตอบของคุณเพราะคำแนะนำแรกดูเหมือนเป็นทางเลือกอื่นที่ใช้งานได้
ef2011

1
@ ef2011 สำหรับ ImageView อย่าตั้งเป็นภาพพื้นหลังคุณต้องตั้งเป็นภาพพื้นsetDrawableResourceหลังจากนั้นตรวจสอบให้แน่ใจว่าsetAdjustViewBoundsได้ตั้งค่าเป็นจริง
Dr.J

9
โหวตลงสำหรับวิธีแก้ปัญหาที่ง่อย วิธีแก้ไขที่ถูกต้องที่นี่: stackoverflow.com/a/9362168/145046
Aleks N.

261

คุณสามารถสร้างบิตแมป 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


3
การใช้ ImageViews เป็นวิธีแก้ปัญหาซึ่งไม่ใช่ทางเลือกที่เป็นไปได้เสมอไป - ฉันเชื่อว่านี่เป็นวิธีแก้ปัญหาที่เหมาะสม :)
JakeP

3
ฉันกำลังตั้งค่าพื้นหลังในขณะทำงาน มีวิธีแก้ปัญหาในการสร้างบิตแมปในขณะทำงานหรือไม่?
Vivek Kumar Srivastava

1
สำหรับฉันนี่เป็นทางออกที่ดีที่สุด แต่ลบแอตทริบิวต์ "แรงโน้มถ่วง" ซึ่งทำให้ตรงกับค่าเริ่มต้น "เติม" วิธีนี้จะช่วยให้ปรับขนาดภาพได้พอดีกับหน้าจอ ศึกษาลิงก์ @Santosh สำหรับข้อมูลเพิ่มเติม ขอบคุณ!
Hugo

12
ฉันเห็นปัญหาเดียวกับแนวทางนี้ หากแหล่งข้อมูลที่วาดได้มีขนาดใหญ่กว่าคอนเทนเนอร์อยู่แล้วสิ่งนี้จะตัดภาพ (ตามแรงโน้มถ่วง) แทนที่จะปรับขนาดโดยรักษาอัตราส่วนภาพให้พอดีกับคอนเทนเนอร์
Shashwat Black

1
ดูเหมือนวันนี้เล็กน้อย ใช้ได้กับบิตแมปเท่านั้นและใช้ไม่ได้กับ Vector drawables
The_Sympathizer

25

เพียงแค่ใช้ImageButtonแทนการButtonแก้ไขปัญหา

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

และคุณสามารถตั้งค่า

android:background="@null"

เพื่อลบพื้นหลังของปุ่มถ้าคุณต้องการ

แก้ไขด่วน !! :-)


1
จากนั้นตั้งค่ารูปภาพด้วยเมธอด setImageResource () ... ที่ได้ผลสำหรับฉัน
arlomedia

ฉันต้องการทั้งภาพและสีพื้นหลังในปุ่ม ... สิ่งนี้ได้ผลอย่างมีเสน่ห์
Abhishek Chauhan

มันทำงานได้แม่นยำกว่าสำหรับฉัน (ฉันหมายถึง - "layout_centerVertical" เป็นต้น)
Maxim Firsoff

12

ฉันใช้ ImageView ใน RelativeLayout ที่ซ้อนทับกับเลย์เอาต์ปกติของฉัน ไม่ต้องใช้รหัส มันปรับขนาดภาพให้เต็มความสูงของหน้าจอ (หรือเค้าโครงอื่น ๆ ที่คุณใช้) จากนั้นครอบตัดรูปภาพทางซ้ายและขวาเพื่อให้พอดีกับความกว้าง ในกรณีของฉันถ้าผู้ใช้เปลี่ยนหน้าจอรูปภาพอาจจะเล็กไปหน่อย ดังนั้นฉันจึงใช้ 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>

นี่เป็นวิธีแก้ปัญหาที่ง่ายกว่ามากสำหรับปัญหาที่ไม่ควรเกิดขึ้น
ÁkosNikházy

6

ฉันมีปัญหาเดียวกัน: คุณควรใช้เฉพาะรูปภาพ 9 แพตช์ (.9.png) แทนรูปภาพต้นฉบับของคุณ

เสิร์จ


5

ใช้draw9patch ... รวมอยู่ในเครื่องมือ SDK ของ Android Studio คุณสามารถกำหนดพื้นที่ที่ยืดได้ของรูปภาพของคุณ ชิ้นส่วนที่สำคัญมีข้อ จำกัด และภาพดูไม่บิดเบี้ยวทั้งหมด การสาธิตที่ดีบน 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

ฉันมีภาพพื้นหลังขนาดไม่ใหญ่ แต่มีขนาดแปลก ๆ - ดังนั้นการยืดและประสิทธิภาพที่ไม่ดี ฉันสร้างเมธอดด้วยพารามิเตอร์บริบทมุมมองและรหัสที่วาดได้ (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

คุณสามารถใช้ a FrameLayoutกับImageViewลูกคนแรกจากนั้นเค้าโครงปกติของคุณเป็นลูกคนที่สอง:

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

กุญแจสำคัญคือการตั้งค่า drawable เป็นภาพของปุ่มไม่ใช่เป็นพื้นหลัง แบบนี้:

rb.setButtonDrawable(R.drawable.whatever_drawable);

นี่เป็นวิธีการของ CompoundButton แต่ไม่ใช่ของ Button
arlomedia

0

หนึ่งสามารถใช้ ImageView ธรรมดาใน xml ของเขาและทำให้คลิกได้ (android: clickable = "true")? คุณต้องใช้เป็น src ภาพที่มีรูปร่างเหมือนปุ่มเช่นมุมกลม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.