วิธีการปรับขนาดมุมมองที่กำหนดเองโดยทางโปรแกรม


164

ฉันกำลังเข้ารหัสมุมมองที่กำหนดเองซึ่งขยายจาก RelativeLayout และฉันต้องการปรับขนาดมุมมองแบบเป็นโปรแกรมฉันจะทำอย่างไร

คลาสมุมมองที่กำหนดเองมีลักษณะดังนี้:

public ActiveSlideView(Context context, AttributeSet attr){
        super(context, attr);
        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if(inflater != null){       
            inflater.inflate(R.layout.active_slide, this);
        }

คำตอบ:


253

Android โยนข้อยกเว้นถ้าคุณล้มเหลวในการผ่านความสูงหรือความกว้างของมุมมอง แทนที่จะสร้างวัตถุ LayoutParams ใหม่ให้ใช้อันเดิมเพื่อให้พารามิเตอร์ชุดอื่น ๆ ทั้งหมดถูกเก็บไว้ โปรดทราบว่าประเภทของ LayoutParams ที่ส่งคืนโดย getLayoutParams เป็นของโครงร่างหลักไม่ใช่มุมมองที่คุณกำลังปรับขนาด

RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) someLayout.getLayoutParams();
params.height = 130;
someLayout.setLayoutParams(params);

2
@HerbertD กล่าวถึงฉันยังได้รับข้อผิดพลาดในการทำเช่นนี้ยกเว้นว่าฉันใช้ LinearLayout.LayoutParams แม้จะเป็น RelativeLayout ที่ฉันกำลังปรับขนาด
Martin Belcher - AtWrk

6
@Eigo ตามเอกสารของ Android LayoutParams จะถูกส่งไปยังมุมมองหลักเนื่องจากนี่เป็นมุมมองที่รับผิดชอบในการจัดวาง
sstn

1
ควรแปลงค่า in เป็นค่า dp หรือไม่
Dory

สิ่งนี้ยังเป็นที่นิยมมากกว่าเนื่องจากหลีกเลี่ยงการสร้างอินสแตนซ์ของวัตถุ LayoutParams ใหม่โดยไม่จำเป็น
Stephen Kidson

129
this.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, theSizeIWant));

แก้ไขปัญหา!

หมายเหตุ: LayoutParamsโปรดใช้แม่เค้าโครงของ ของฉันคือLinearLayout.LayoutParams!


3
wut ทำไมคุณจะไม่ใช้RelativeLayout.LayoutParams?
nmr

1
สิ่งนี้ไม่ได้ผลสำหรับฉันฉันได้รับการยกเว้นในชั้นเรียน
Tapan Thaker

4
@Tapan Thanker ใช้ LayoutParams ของเลย์เอาต์หลัก และเลย์เอาต์หลักของฉันคือ LinearLayout
herbertD

10
ฉันเขียนเวอร์ชันทั่วไปเพิ่มเติมของนี้: private void resizeView(View view, int newWidth, int newHeight) { try { Constructor<? extends LayoutParams> ctor = view.getLayoutParams().getClass().getDeclaredConstructor(int.class, int.class); view.setLayoutParams(ctor.newInstance(newWidth, newHeight)); } catch (Exception e) { e.printStackTrace(); } }
atroutt

2
สิ่งนี้จะรีเซ็ตพารามิเตอร์อื่น ๆ ทั้งหมดเป็นค่าเริ่มต้น @smisiewicz คำตอบดีกว่า
Fran Marzoa

66

สิ่งนี้ใช้ได้กับฉัน:

ViewGroup.LayoutParams params = layout.getLayoutParams();
params.height = customHeight;
layout.requestLayout();

7
นี่เป็นคำตอบที่ดีกว่าคำตอบอื่น ๆ เพราะรหัสนี้ไม่จำเป็นต้องทราบประเภทที่แน่นอนของ ViewGroup หลัก
Bart Burg

1
คุณรู้หรือไม่ว่าอะไรคือความแตกต่างระหว่างการเรียก requestLayout () และการเรียก setLayoutParams (params)
voghDev

2
setLayoutParams (params) รวมถึง requestLayout ()
illusionJJ

44

สำหรับสิ่งที่คุ้มค่าสมมติว่าคุณต้องการปรับขนาดมุมมองเป็นพิกเซลอิสระของอุปกรณ์ ( dp ): -

คุณต้องใช้วิธีการที่เรียกapplyDimensionว่าเป็นสมาชิกของคลาสTypedValueเพื่อแปลงจากพิกเซลเป็น dps ดังนั้นถ้าฉันต้องการตั้งความสูงเป็น 150 dp (พูด) - จากนั้นฉันสามารถทำได้

float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 150, getResources().getDisplayMetrics());
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) someLayout.getLayoutParams();
params.height = (int) pixels;
someLayout.setLayoutParams(params);

โดยที่ expression: getResources().getDisplayMetrics()รับความหนาแน่นของหน้าจอ / ความละเอียด


6
แทนที่จะเขียนโค้ดอย่างหนักคุณยังสามารถใช้ความสูงเป็นพิกเซลได้:float pixels = context.getResources().getDimensionPixelSize(R.dimen.card_height);
Francois Dermu

คำตอบนี้เหมาะสมกว่าเป็นคำตอบที่ถูกต้อง! ขอบคุณ
Yunus Kulyyev


6

ลองอันนี้:

...
View view = inflater.inflate(R.layout.active_slide, this);
view.setMinimumWidth(200);

ขออภัยฉันไม่ได้โพสต์คำถามทั้งหมดตั้งแต่คุณตอบมัน นั่นคือคำถามทั้งหมด ขอบคุณ!
herbertD

6

นี่เป็นวิธีแก้ไขปัญหาทั่วไปที่ด้านบนจาก @herbertD:

private void resizeView(View view, int newWidth, int newHeight) { 
    try { 
        Constructor<? extends LayoutParams> ctor = view.getLayoutParams().getClass().getDeclaredConstructor(int.class, int.class); 
        view.setLayoutParams(ctor.newInstance(newWidth, newHeight));   
    } catch (Exception e) { 
        e.printStackTrace(); 
    }
}

@atroutt คุณช่วยชีวิตฉันไว้อย่างแท้จริง :)
Qasim

5

ฉันใช้วิธีนี้เพื่อเพิ่มความกว้างของมุมมองที่กำหนดเอง

customDrawingView.post(new Runnable() {
                            @Override
                            public void run() {
                                View view_instance = customDrawingView;
                                android.view.ViewGroup.LayoutParams params = view_instance
                                        .getLayoutParams();
                                int newLayoutWidth = customDrawingView
                                        .getWidth()
                                        + customDrawingView.getWidth();
                                params.width = newLayoutWidth;
                                view_instance.setLayoutParams(params);
                                screenWidthBackup = params.width;
                            }
                        });

4

ฉันแก้ไขมันด้วยวิธีนี้ .. ฉันมีมุมมองง่ายๆภายในไฟล์ xml

 View viewname = findViewById(R.id.prod_extra);
             prodExtra.getLayoutParams().height=64;

2
ฮ่าฮ่า, ไร้เดียงสามาก แต่ก็ใช้งานได้ดี, แต่ฉันแนะนำให้เรียก setLayoutParams () ในท้ายที่สุดเพื่อเผยแพร่การเปลี่ยนแปลงไปยังเด็ก ๆ ที่ซ้อนกันได้อย่างเหมาะสม, ดังนั้นหลังจากอัปเดต. bandwidth และ. high, call view.setLayoutParams (). พิมพ์ตัวพิสูจน์เสมอ
comeGetSome

@Bhargav Rao คุณสามารถช่วยฉันในหัวข้อนี้: https://stackoverflow.com/q/44259342/6596724
tux-world

2

หากคุณมีเพียงtwo or three condition(sizes)คุณสามารถใช้@Overide onMeasureเช่น

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
{
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

และเปลี่ยนขนาดของคุณสำหรับเงื่อนไขเหล่านี้ในคลาส CustomView ได้อย่างง่ายดาย


1

หากคุณกำลังเอาชนะonMeasureอย่าลืมอัพเดทขนาดใหม่

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(newWidth, newHeight);
}

1

นี่คือวิธีที่ฉันได้รับสิ่งนี้ ในSileriaตอบเขา / เธอทำต่อไปนี้:

ViewGroup.LayoutParams params = layout.getLayoutParams();
params.height = customHeight;
layout.requestLayout();

สิ่งนี้ถูกต้อง แต่คาดว่าเราจะให้ความสูงpixelsแต่ฉันต้องการให้dpความสูงนั้นเป็นสิ่งที่ฉันเพิ่ม:

public int convertDpToPixelInt(float dp, Context context) {
    return (int) (dp * (((float) context.getResources().getDisplayMetrics().densityDpi) / 160.0f));
}

ดังนั้นจะมีลักษณะเช่นนี้:

ViewGroup.LayoutParams params = layout.getLayoutParams();
params.height = convertDpToPixelInt(50, getContext());
layout.requestLayout();

0

นี่คือสิ่งที่ฉันทำ:

View myView;  
myView.getLayoutParams().height = 32;  
myView.getLayoutParams().width = 32;

หากมีกลุ่มมุมมองที่เป็นของมุมมองนี้คุณอาจต้องเรียกใช้ yourViewGroup.requestLayout () เพื่อให้มีผล

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