วิธีการเพิ่มมุมมองไปยังมุมมองโดยทางโปรแกรม


179

สมมติว่าฉันมีLinearLayoutและฉันต้องการเพิ่มมุมมองในโปรแกรมของฉันจากรหัส Java วิธีนี้ใช้สำหรับอะไร? ฉันไม่ได้ถามว่ามันทำใน XML ซึ่งฉันรู้ได้อย่างไร แต่ฉันจะทำอะไรตามบรรทัดของโค้ดตัวอย่างนี้ได้อย่างไร

(One View).add(Another View)

เช่นเดียวกับใน Swing

คำตอบ:


248

การโทรaddViewเป็นคำตอบที่ถูกต้อง แต่คุณต้องทำมากกว่านั้นเพื่อให้ทำงานได้

หากคุณสร้างมุมมองผ่านตัวสร้าง (เช่นButton myButton = new Button();) คุณจะต้องเรียกsetLayoutParamsใช้มุมมองที่สร้างขึ้นใหม่ส่งผ่านอินสแตนซ์ของคลาสภายใน LayoutParams ของมุมมองพาเรนต์ก่อนที่คุณจะเพิ่มลูกที่สร้างขึ้นใหม่ลงในมุมมองพาเรนต์

ตัวอย่างเช่นคุณอาจมีรหัสต่อไปนี้ในonCreate()ฟังก์ชั่นของคุณสมมติว่า LinearLayout ของคุณมีรหัสR.id.main:

LinearLayout myLayout = findViewById(R.id.main);

Button myButton = new Button(this);
myButton.setLayoutParams(new LinearLayout.LayoutParams(
                                     LinearLayout.LayoutParams.MATCH_PARENT,
                                     LinearLayout.LayoutParams.MATCH_PARENT));

myLayout.addView(myButton);

การตั้งค่า LayoutParams เป็นสิ่งสำคัญ ทุกมุมมองต้องการพารามิเตอร์ layout_width อย่างน้อยและพารามิเตอร์ layout_height การได้รับคลาสภายในที่เหมาะสมก็เป็นสิ่งสำคัญเช่นกัน ฉันต่อสู้กับการเพิ่ม Views ให้กับ TableRow เพื่อแสดงอย่างถูกต้องจนกระทั่งฉันพบว่าฉันไม่ได้ส่งตัวอย่างของ TableRow.LayoutParams ไปยัง setLayoutParams ของมุมมองเด็ก


5
คุณจะสร้างมุมมองโดยทางโปรแกรม แต่โดยใช้ไฟล์เลย์เอาต์ XML ที่คุณเขียนเป็นพิเศษสำหรับมุมมองใหม่นี้
SK9

9
@ SK9 คุณจะใช้ LayoutInflater ซึ่งคุณสามารถได้รับจากบริบทซึ่งโดยปกติจะเป็นกิจกรรมปัจจุบัน บางสิ่งที่ชอบ: LayoutInflater myInflater = getLayoutInflater; ดู myView = myInflater.inflate (R.layout.myLayout, parent, false);
Brian Cooley

1
ที่จริง getLayoutInflater () มาจากคลาส Window (ไม่ใช่บริบท) และเป็นวิธีการอำนวยความสะดวกในกิจกรรม
Brian Cooley

2
ในฐานะที่เป็นแนวทางปฏิบัติในการเข้ารหัสบน findViewById ส่งไปยัง ViewGroup หรือเป็นรูปแบบทั่วไปที่สุดของวัตถุเสมอดังนั้นหากเปลี่ยนจาก LinearLayout เป็น RelativeLayout คุณไม่มีการปรับโครงสร้างใหม่
Joel Teply

1
รายละเอียดเหล่านี้คือ: D
Vivek Solanki

51

สำหรับทุกคนที่สนใจ:

วิธีที่ดีที่สุดที่ฉันพบคือใช้วิธีขยายแบบคงที่ของมุมมอง

View inflatedView = View.inflate(context, yourViewXML, yourLinearLayout);

โดยที่ yourViewXML นั้นคล้ายกับ R.layout.myView

โปรดสังเกตว่าคุณต้องการ ViewGroup เพื่อเพิ่มมุมมอง (ซึ่งเป็นเลย์เอาต์ที่คุณนึกถึง)

เพื่อเป็นตัวอย่างให้สมมติว่าคุณมีส่วนที่มันดูแล้วพองและคุณรู้ว่ามุมมองรากเป็นเค้าโครงและคุณต้องการเพิ่มมุมมอง:

    View view = getView(); // returns base view of the fragment
    if (view == null)
        return;
    if (!(view instanceof ViewGroup))
        return;

    ViewGroup viewGroup = (ViewGroup) view;
    View popup = View.inflate(viewGroup.getContext(), R.layout.someView, viewGroup);

นอกจากนี้คุณยังสามารถเขียนวิธีการคงที่สิ่งaddView(View v){ // your code after get view }ที่จะใช้มุมมองที่พบโดยใช้findViewById(int resourceID)หรือพองตัวเช่นinflatedView... ของคุณเพียงเพื่อขยายตัวอย่างชิ้นส่วนของคุณ
zgc7009

22

นี่สาย แต่สิ่งนี้อาจช่วยให้ใครบางคน :) :) สำหรับการเพิ่มมุมมองลองโดยทางโปรแกรม

LinearLayout rlmain = new LinearLayout(this);      
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);          
LinearLayout   ll1 = new LinearLayout (this);

ImageView iv = new ImageView(this);
iv.setImageResource(R.drawable.logo);              
LinearLayout .LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);

iv.setLayoutParams(lp);
ll1.addView(iv);
rlmain.addView(ll1);              
setContentView(rlmain, llp);

สิ่งนี้จะสร้างมุมมองทั้งหมดของคุณในเชิงโปรแกรม คุณสามารถเพิ่มจำนวนการดูได้เช่นเดียวกัน หวังว่ามันจะช่วยได้ :)



3

อีกวิธีหนึ่งในการเพิ่มมุมมองจากกิจกรรม

ViewGroup rootLayout = findViewById(android.R.id.content);
rootLayout.addView(view);

0

แนวคิดของการตั้งค่าข้อ จำกัด ทางโปรแกรมอาจเป็นเรื่องน่าเบื่อ วิธีการแก้ปัญหาด้านล่างนี้จะใช้ได้กับเลย์เอาต์ใด ๆ ไม่ว่าจะเป็นข้อ จำกัด เชิงเส้น ฯลฯ วิธีที่ดีที่สุดคือการตั้งค่าตัวยึดตำแหน่งเช่น FrameLayout ที่มีข้อ จำกัด ที่เหมาะสม (หรือวางในรูปแบบอื่น ๆ เช่นเชิงเส้น เพื่อที่จะมี.

สิ่งที่คุณต้องทำคือขยายมุมมองโดยทางโปรแกรมและเป็นลูกไปยัง FrameLayout โดยใช้addChild()วิธีการ จากนั้นในระหว่างรันไทม์มุมมองของคุณจะสูงเกินจริงและวางในตำแหน่งที่เหมาะสม ต่อข้อเสนอแนะ Android ของคุณควรเพิ่มเพียงหนึ่ง childView เพื่อ FrameLayout [ลิงค์]

นี่คือลักษณะของรหัสของคุณหากคุณต้องการสร้าง TextView โดยทางโปรแกรมในตำแหน่งที่ต้องการ:

ขั้นตอนที่ 1:

ในเลย์เอาต์ของคุณซึ่งจะมีมุมมองที่สูงเกินจริงให้วาง FrameLayout ในตำแหน่งที่ถูกต้องแล้วตั้งรหัสให้พูดว่า "คอนเทนเนอร์"

ขั้นตอนที่ 2 สร้างเลย์เอาต์ที่มีองค์ประกอบรูทเป็นมุมมองที่คุณต้องการขยายระหว่างรันไทม์ให้เรียกไฟล์เลย์เอาต์เป็น "textview.xml":

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">

</TextView>

BTW ตั้งค่าเลย์เอาต์เค้าโครงของ frameLayout ของคุณเป็น wrap_content เสมอเลย์เอาต์ของเฟรมจะใหญ่พอ ๆ กับพาเรนต์เช่นกิจกรรมเช่นหน้าจอโทรศัพท์

android:layout_width="wrap_content"
android:layout_height="wrap_content"

หากไม่ได้ตั้งค่าเนื่องจากมุมมองลูกของเฟรมโดยค่าเริ่มต้นจะไปที่ด้านบนซ้ายของเลย์เอาต์เฟรมดังนั้นมุมมองของคุณจะบินไปด้านบนซ้ายของหน้าจอ

ขั้นตอนที่ 3

ในวิธีการสร้างของคุณให้ทำสิ่งนี้:

FrameLayout frameLayout = findViewById(R.id.container);
                TextView textView = (TextView) View.inflate(this, R.layout.textview, null);
                frameLayout.addView(textView);

(โปรดทราบว่าการตั้งค่าพารามิเตอร์สุดท้ายของfindViewByIdถึงnullและเพิ่มมุมมองโดยเรียกaddView()ใช้มุมมองคอนเทนเนอร์ (frameLayout) เหมือนกับการแนบมุมมองที่สูงเกินจริงโดยส่งผ่านtrueพารามิเตอร์ที่ 3 ของfindViewById()ดูเพิ่มเติมได้ที่นี่ )


0

พวกคุณควรให้แน่ใจว่าเมื่อคุณแทนที่onLayoutคุณจะต้องโทรหาsuper.onLayoutคุณสมบัติทั้งหมดมิฉะนั้นมุมมองจะไม่พองเกินจริง!

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