Cách lập trình Thêm lượt xem vào lượt xem


179

Giả sử tôi có một LinearLayoutvà tôi muốn thêm Chế độ xem vào nó, trong chương trình của tôi từ mã Java. Phương pháp nào được sử dụng cho việc này? Tôi không hỏi làm thế nào nó được thực hiện trong XML, mà tôi biết, nhưng thay vào đó, làm thế nào tôi có thể làm gì đó dọc theo dòng mã mẫu này?

(One View).add(Another View)

Giống như người ta có thể làm trong Swing.

Câu trả lời:


248

Gọi addViewlà câu trả lời chính xác, nhưng bạn cần phải làm nhiều hơn thế để làm cho nó hoạt động.

Nếu bạn tạo Chế độ xem thông qua hàm tạo (ví dụ Button myButton = new Button();:), bạn sẽ cần gọi setLayoutParamschế độ xem mới được xây dựng, chuyển qua một thể hiện của lớp bên trong LayoutParams của khung nhìn cha mẹ, trước khi bạn thêm con mới được xây dựng vào dạng xem cha.

Ví dụ: bạn có thể có đoạn mã sau trong onCreate()hàm giả sử tuyến tínhLayout của bạn có id 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);

Đảm bảo đặt LayoutParams là rất quan trọng. Mỗi chế độ xem cần ít nhất một layout_ thong và tham số layout_height. Ngoài ra nhận được đúng lớp bên trong là quan trọng. Tôi đã vật lộn với việc thêm Lượt xem vào TableRow để hiển thị chính xác cho đến khi tôi nhận ra rằng tôi đã không chuyển một thể hiện của TableRow.LayoutParams sang setLayoutParams của khung nhìn con.


5
Làm thế nào bạn có thể tạo chế độ xem theo chương trình nhưng bằng cách sử dụng tệp bố cục XML mà bạn đã viết cụ thể cho chế độ xem mới này?
SK9

9
@ SK9 Bạn sẽ sử dụng LayoutInflater, mà bạn có thể nhận được từ Ngữ cảnh, thường là Hoạt động hiện tại. Một cái gì đó như: LayoutInflater myInflater = getLayoutInflater; Xem myView = myInflater.inflate (R.layout.myLayout, cha mẹ, sai);
Brian Cooley

1
Trên thực tế getLayoutInflater () đến từ lớp Window (không phải Ngữ cảnh) và đó là một phương thức tiện lợi trong Activity.
Brian Cooley

2
Như một cách thực hành mã hóa, trên findViewById, chuyển sang Viewgroup hoặc luôn là dạng chung nhất của một đối tượng để nếu nó thay đổi từ linearLayout thành RelativeLayout, bạn không có cấu trúc lại.
Joel Teply

1
Đây là một số chi tiết: D
Vivek Solanki

51

cho bất cứ ai quan tâm:

cách tốt nhất tôi tìm thấy là sử dụng phương thức tĩnh của View.

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

trong đóViewView của bạn giống như R.layout.myView

vui lòng lưu ý rằng bạn cần có Viewgroup để thêm chế độ xem (đó là bất kỳ bố cục nào bạn có thể nghĩ đến)

vì vậy, như một ví dụ cho phép bạn có một đoạn mà nó xem đã bị thổi phồng và bạn biết rằng khung nhìn gốc là một bố cục và bạn muốn thêm một khung nhìn vào nó:

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

Bạn cũng có thể viết một phương thức tĩnh, một cái gì đó giống như addView(View v){ // your code after get view }sẽ có một khung nhìn được tìm thấy bằng cách sử dụng findViewById(int resourceID)hoặc thổi phồng như inflatedView... chỉ để mở rộng trên ví dụ phân đoạn của bạn.
zgc7009

22

Điều này là muộn nhưng điều này có thể giúp được ai đó :) :) Để thêm chế độ xem theo chương trình, hãy thử như

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

Điều này sẽ tạo ra toàn bộ khung nhìn của bạn theo chương trình. Bạn có thể thêm bất kỳ số lượng xem như nhau. Hy vọng điều này có thể giúp đỡ. :)



3

Thêm một cách để thêm chế độ xem từ Hoạt động

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

0

Ý tưởng về các ràng buộc thiết lập theo chương trình có thể gây mệt mỏi. Giải pháp dưới đây sẽ hoạt động cho mọi bố cục cho dù là ràng buộc, tuyến tính, v.v. Cách tốt nhất là đặt một trình giữ chỗ tức là FrameLayout với các ràng buộc thích hợp (hoặc đặt đúng vị trí trong bố cục khác như tuyến tính) tại vị trí mà bạn mong đợi ở chế độ xem được lập trình có.

Tất cả những gì bạn cần làm là tăng cường chế độ xem theo chương trình và nó như một đứa trẻ đối với FrameLayout bằng cách sử dụng addChild()phương thức. Sau đó, trong thời gian chạy, khung nhìn của bạn sẽ bị thổi phồng và được đặt đúng vị trí. Theo khuyến nghị của Android, bạn chỉ nên thêm một childView vào FrameLayout [link] .

Đây là mã của bạn sẽ trông như thế nào, giả sử bạn muốn tạo TextView theo chương trình tại một vị trí cụ thể:

Bước 1:

Trong bố cục của bạn sẽ chứa chế độ xem bị thổi phồng, hãy đặt FrameLayout ở vị trí chính xác và đặt cho nó một id, giả sử, "container".

Bước 2 Tạo bố cục với phần tử gốc là dạng xem bạn muốn tăng trong thời gian chạy, gọi tệp bố cục là "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, đặt các tham số bố cục của frameLayout của bạn thành quấn_content luôn, bố cục khung sẽ trở nên lớn như cha mẹ tức là hoạt động tức là màn hình điện thoại.

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

Nếu không được đặt, theo mặc định, chế độ xem con của khung sẽ đi về phía trên bên trái của bố cục khung, do đó, chế độ xem của bạn sẽ chỉ đơn giản bay lên trên cùng bên trái của màn hình.

Bước 3

Trong phương pháp oncreate của bạn, làm điều này:

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

(Lưu ý rằng cài đặt tham số cuối cùng của findViewByIdđể nullvà thêm điểm bằng cách gọi addView()vào xem container (frameLayout) là giống như chỉ đơn giản là gắn các quan điểm lạm phát bằng cách đi qua truetrong tham số thứ 3 của findViewById(). Để biết thêm, xem này .)


0

Các bạn cũng nên đảm bảo rằng khi bạn ghi đè, onLayoutbạn phải gọi super.onLayoutvới tất cả các thuộc tính, hoặc chế độ xem sẽ không bị thổi phồng!

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.