กำหนดขนาดที่วาดได้โดยทางโปรแกรม


92

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

ฉันต้องทำอย่างไร

Button button = new Button(this);
button.setText(apiEventObject.getTitle());
button.setOnClickListener(listener);

/*
 * set clickable id of button to actual event id
 */
int id = Integer.parseInt(apiEventObject.getId());
button.setId(id);

button.setLayoutParams(new LayoutParams(
        android.view.ViewGroup.LayoutParams.FILL_PARENT,
        android.view.ViewGroup.LayoutParams.WRAP_CONTENT));

Drawable drawable = LoadImageFromWebOperations(apiSizeObject.getSmall());
//?resize drawable here? drawable.setBounds(50, 50, 50, 50);
button.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);

คุณพบวิธีการปรับขนาดที่วาดได้ (Bitmap) หรือไม่?
Zelimir

2
สาย แต่สงสัยว่าทำไมคุณไม่โทรsetCompoundDrawables()? ที่แท้จริงหมายถึงขนาดของภาพต้นฉบับในสถานที่อื่น ๆ ที่อยู่ใน Android Drawable.getIntrinsicHeight()เช่น
William T. Mallard

คำตอบ:


160

setBounds()วิธีการไม่ทำงานสำหรับประเภทของภาชนะทุก (ไม่ทำงานสำหรับบางส่วนของฉันImageView's อย่างไร)

ลองใช้วิธีการด้านล่างเพื่อปรับขนาดที่ดึงได้เอง:

// Read your drawable from somewhere
Drawable dr = getResources().getDrawable(R.drawable.somedrawable);
Bitmap bitmap = ((BitmapDrawable) dr).getBitmap();
// Scale it to 50 x 50
Drawable d = new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bitmap, 50, 50, true));
// Set your new, scaled drawable "d"

สำหรับฉันปัญหาที่นี่คือมันวาดสี่เหลี่ยมผืนผ้าสีขาวรอบ ๆ ภาพที่วาดได้
noloman

8
ตัวสร้าง BitmapDrawable (บิตแมป) เลิกใช้งานแล้ว ใช้: Drawable d = BitmapDrawable ใหม่ (getResources (), Bitmap.createScaledBitmap (บิตแมป, 50, 50, จริง));
Andy

1
สิ่งนี้จะสร้างพิกเซลเมื่อปรับขนาด drawables แม้ว่าจะเป็นแบบเวกเตอร์ที่วาดได้ก็ตาม
Sanket Berde

อาจต้องการใช้ContextCompat.getDrawable(context, resourceid)
ปิแอร์

ตามบันทึกข้างคุณสามารถสร้างStateListDrawableprogrammitically และการใช้addStateวิธีการที่มี "แปลง drawable" เพื่อให้การทำงานสำหรับขนาดที่ใช้ในการselector's item setPasswordVisibilityToggleDrawable
ผลไม้

31

ระบุขนาดด้วยsetBounds()เช่นสำหรับการใช้งานขนาด 50x50

drawable.setBounds(0, 0, 50, 50);

โมฆะสาธารณะ setBounds (int left, int top, int right, int bottom)


2
หลังจากขนาด SetBounds ยังคงเท่าเดิม อาจจำเป็นต้องใช้บางส่วนที่ไม่ถูกต้อง?
Kostadin

6
จริงๆแล้ว setBounds ใช้ได้กับ GradientDrawables มันใช้ไม่ได้กับ Image Drawables
gregm

มันใช้ได้ผลสำหรับฉันเมื่อฉันวางภาพลงในปุ่ม แต่ไม่ใช่เมื่อฉันใส่ลงใน ImageView OP ใช้ปุ่ม แต่ยังเรียกรสชาติที่แท้จริงของsetCompoundDrawables()ฟังก์ชัน
William T. Mallard

@gregm น่าสนใจคุณยังสามารถกำหนดขนาดสำหรับ GradientDrawable โดยใช้ setSize ()
6rchid

12

ก่อนใช้. setBounds (.. ) ให้ลองแปลง Drawable ปัจจุบันเป็น ScaleDrawable

drawable = new ScaleDrawable(drawable, 0, width, height).getDrawable();

หลังจากนั้น

drawable.setBounds(0, 0, width, height);

จะทำงาน


2
เหตุใดจึงจำเป็นต้องมีขั้นตอนนี้ การห่อแบบใดScaleDrawableให้ทางเลือกในการไม่ห่อ?
azizbekian

10

ฉันไม่มีเวลาขุดว่าทำไมเมธอด setBounds () ไม่ทำงานบนบิตแมปที่วาดได้ตามที่คาดไว้ แต่ฉันมีโซลูชัน @ androbean-studio ที่ปรับแต่งเล็กน้อยเพื่อทำสิ่งที่ setBounds ควรทำ ...

/**
 * Created by ceph3us on 23.05.17.
 * file belong to pl.ceph3us.base.android.drawables
 * this class wraps drawable and forwards draw canvas
 * on it wrapped instance by using its defined bounds
 */
public class WrappedDrawable extends Drawable {

    private final Drawable _drawable;
    protected Drawable getDrawable() {
        return _drawable;
    }

    public WrappedDrawable(Drawable drawable) {
        super();
        _drawable = drawable;
    }

    @Override
    public void setBounds(int left, int top, int right, int bottom) {
        //update bounds to get correctly
        super.setBounds(left, top, right, bottom);
        Drawable drawable = getDrawable();
        if (drawable != null) {
            drawable.setBounds(left, top, right, bottom);
        }
    }

    @Override
    public void setAlpha(int alpha) {
        Drawable drawable = getDrawable();
        if (drawable != null) {
            drawable.setAlpha(alpha);
        }
    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {
        Drawable drawable = getDrawable();
        if (drawable != null) {
            drawable.setColorFilter(colorFilter);
        }
    }

    @Override
    public int getOpacity() {
        Drawable drawable = getDrawable();
        return drawable != null
                ? drawable.getOpacity()
                : PixelFormat.UNKNOWN;
    }

    @Override
    public void draw(Canvas canvas) {
        Drawable drawable = getDrawable();
        if (drawable != null) {
            drawable.draw(canvas);
        }
    }

    @Override
    public int getIntrinsicWidth() {
        Drawable drawable = getDrawable();
        return drawable != null
                ? drawable.getBounds().width()
                : 0;
    }

    @Override
    public int getIntrinsicHeight() {
        Drawable drawable = getDrawable();
        return drawable != null ?
                drawable.getBounds().height()
                : 0;
    }
}

การใช้งาน:

// get huge drawable 
final Drawable drawable = resources.getDrawable(R.drawable.g_logo);
// create our wrapper           
WrappedDrawable wrappedDrawable = new WrappedDrawable(drawable);
// set bounds on wrapper 
wrappedDrawable.setBounds(0,0,32,32); 
// use wrapped drawable 
Button.setCompoundDrawablesWithIntrinsicBounds(wrappedDrawable ,null, null, null);

ผล

ก่อน: ป้อนคำอธิบายภาพที่นี่ หลัง:ป้อนคำอธิบายภาพที่นี่


จะเพิ่มช่องว่างด้านซ้ายได้อย่างไร?
reegan29

8

ใช้

textView.setCompoundDrawablesWithIntrinsicBounds()

minSdkVersion ของคุณควรเป็น 17 ใน build.gradle

    defaultConfig {
    applicationId "com.example..."
    minSdkVersion 17
    targetSdkVersion 25
    versionCode 1
    versionName "1.0"
}

ในการเปลี่ยนขนาดที่วาดได้:

    TextView v = (TextView)findViewById(email);
    Drawable dr = getResources().getDrawable(R.drawable.signup_mail);
    Bitmap bitmap = ((BitmapDrawable) dr).getBitmap();
    Drawable d = new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bitmap, 80, 80, true));

    //setCompoundDrawablesWithIntrinsicBounds (image to left, top, right, bottom)
    v.setCompoundDrawablesWithIntrinsicBounds(d,null,null,null);

3

ใช้วิธีการโพสต์เพื่อให้ได้เอฟเฟกต์ที่ต้องการ:

{your view}.post(new Runnable()
    {
        @Override
        public void run()
        {
            Drawable image = context.getResources().getDrawable({drawable image resource id});
            image.setBounds(0, 0, {width amount in pixels}, {height amount in pixels});
            {your view}.setCompoundDrawables(image, null, null, null);
        }
    });

3

อาจจะสายหน่อย แต่นี่คือทางออกที่ได้ผลสำหรับฉันในทุกสถานการณ์

แนวคิดคือการสร้างที่วาดได้เองโดยมีขนาดภายในคงที่และส่งต่องานวาดไปยังต้นฉบับที่วาดได้

Drawable icon = new ColorDrawable(){
        Drawable iconOrig = resolveInfo.loadIcon(packageManager);

        @Override
        public void setBounds(int left, int top, int right, int bottom){
            super.setBounds(left, top, right, bottom);//This is needed so that getBounds on this class would work correctly.
            iconOrig.setBounds(left, top, right, bottom);
        }

        @Override
        public void draw(Canvas canvas){
            iconOrig.draw(canvas);
        }

        @Override
        public int getIntrinsicWidth(){
            return  mPlatform.dp2px(30);
        }

        @Override
        public int getIntrinsicHeight(){
            return  mPlatform.dp2px(30);
        }
    };

mPlatform คืออะไร?
batsheva

@batsheva เป็นเพียงสิ่งที่เขาใช้สำหรับการแปลงจาก dp เป็น px ...
นักพัฒนา android

2

คำตอบ jkhouw1 เป็นคำตอบที่ถูกต้อง แต่ขาดรายละเอียดบางประการดูด้านล่าง:

มันง่ายกว่ามากสำหรับอย่างน้อย API> 21 สมมติว่าเรามี VectorDrawable จากทรัพยากร (โค้ดตัวอย่างเพื่อดึงข้อมูล):

val iconResource = context.resources.getIdentifier(name, "drawable", context.packageName)
val drawable = context.resources.getDrawable(iconResource, null)

สำหรับ VectorDrawable นั้นให้กำหนดขนาดที่ต้องการ:

drawable.setBounds(0, 0, size, size)

และแสดงปุ่ม drawable ใน:

button.setCompoundDrawables(null, drawable, null, null)

แค่นั้นแหละ. แต่โปรดทราบว่าให้ใช้ setCompoundDrawables (ไม่ใช่รุ่น Intrinsic)!


1

ทำให้สิ่งนี้ทำงานได้โดยใช้ LayerDrawable:

fun getResizedDrawable(drawable: Drawable, scale: Float) =
    LayerDrawable(arrayOf(drawable)).also { it.setLayerSize(0, (drawable.intrinsicWidth * scale).toInt(), (drawable.intrinsicHeight * scale).toInt()) }

fun getResizedDrawable(drawable: Drawable, scalex: Float, scaleY: Float) =
    LayerDrawable(arrayOf(drawable)).also { it.setLayerSize(0, (drawable.intrinsicWidth * scalex).toInt(), (drawable.intrinsicHeight * scaleY).toInt()) }

fun getResizedDrawableUsingSpecificSize(drawable: Drawable, newWidth: Int, newHeight: Int) =
    LayerDrawable(arrayOf(drawable)).also { it.setLayerSize(0, newWidth, newHeight) }

ตัวอย่าง:

val drawable = AppCompatResources.getDrawable(this, android.R.drawable.sym_def_app_icon)!!
val resizedDrawable = getResizedDrawable(drawable, 3f)
textView.setCompoundDrawablesWithIntrinsicBounds(resizedDrawable, null, null, null)
imageView.setImageDrawable(resizedDrawable)

0

คุณสามารถสร้างคลาสย่อยของชนิดมุมมองและแทนที่เมธอด onSizeChanged

ฉันต้องการปรับขนาดการวาดสารประกอบในมุมมองข้อความของฉันที่ไม่ต้องการให้ฉันยุ่งกับการกำหนดบิตแมป drawables ใน xml ฯลฯ และทำด้วยวิธีนี้:

public class StatIcon extends TextView {

    private Bitmap mIcon;

    public void setIcon(int drawableId) {
    mIcon = BitmapFactory.decodeResource(RIApplication.appResources,
            drawableId);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        if ((w > 0) && (mIcon != null))
            this.setCompoundDrawablesWithIntrinsicBounds(
                null,
                new BitmapDrawable(Bitmap.createScaledBitmap(mIcon, w, w,
                        true)), null, null);

        super.onSizeChanged(w, h, oldw, oldh);
    }

}

(โปรดทราบว่าฉันใช้ w สองครั้งไม่ใช่ h เนื่องจากในกรณีนี้ฉันวางไอคอนไว้เหนือข้อความดังนั้นไอคอนจึงไม่ควรมีความสูงเท่ากับมุมมองข้อความ)

สิ่งนี้สามารถนำไปใช้กับภาพวาดพื้นหลังหรือสิ่งอื่น ๆ ที่คุณต้องการปรับขนาดให้สัมพันธ์กับขนาดมุมมองของคุณ onSizeChanged () ถูกเรียกในครั้งแรกที่มีการสร้าง View ดังนั้นคุณไม่จำเป็นต้องมีกรณีพิเศษใด ๆ ในการเริ่มต้นขนาด


0

button.requestLayout()คุณสามารถลอง เมื่อขนาดพื้นหลังเปลี่ยนไปจำเป็นต้องมีการวัดและการจัดวางใหม่ แต่จะไม่ทำ


-1

คุณสามารถใช้ LayerDrawable จากเลเยอร์เดียวและเมธอด setLayerInset:

Drawable[] layers = new Drawable[1];
layers[0] = application.getResources().getDrawable(R.drawable.you_drawable);

LayerDrawable layerDrawable = new LayerDrawable(layers);
layerDrawable.setLayerInset(0, 10, 10, 10, 10);

-1

เป็นเวลานานแล้วที่คำถามถูกถาม
แต่ก็ยังไม่มีความชัดเจนว่าจะทำสิ่งง่ายๆนี้อย่างไร

มันค่อนข้างง่ายในกรณีนี้เมื่อคุณใช้ Drawable เป็นสารประกอบที่วาดได้บน TextView (ปุ่ม)

มี 2 ​​สิ่งที่คุณต้องทำ:

1. กำหนดขอบเขต:

drawable.setBounds(left, top, right, bottom)

2. ตั้งค่า drawable ให้เหมาะสม (โดยไม่ต้องใช้ขอบเขตที่แท้จริง):

button.setCompoundDrawablesRelative(drawable, null, null, null)
  • ไม่จำเป็นต้องใช้ Bitmaps
  • ไม่มีวิธีแก้ปัญหาเช่นScaleDrawable ColorDrawableหรือLayerDrawable (สิ่งที่สร้างขึ้นเพื่อวัตถุประสงค์อื่นอย่างแน่นอน)
  • ไม่จำเป็นต้องใช้ drawables ที่กำหนดเอง!
  • ไม่มีวิธีแก้ปัญหาด้วย post
  • เป็นวิธีแก้ปัญหาแบบเนทีฟและเรียบง่ายตามที่ Android คาดหวังให้คุณทำ

-43
Button button = new Button(this);
Button = (Button) findViewById(R.id.button01);

ใช้Button.setHeight()หรือButton.setWeight()และตั้งค่า


9
ที่กำหนดความสูงของปุ่มไม่ใช่ความสูงของปุ่มที่ดึงได้ ฉันต้องการตั้งค่าความกว้าง / ความสูงของสิ่งที่ดึงได้ (โดยเฉพาะอย่างยิ่งหากมีขนาดใหญ่กว่าความสูงของปุ่มที่ตั้งไว้)

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