Tham số LayoutInflater AttachToRoot có nghĩa là gì?


201

Các LayoutInflater.inflatetài liệu hướng dẫn là không chính xác rõ ràng với tôi về mục đích của attachToRoottham số.

Đính kèm : liệu hệ thống phân cấp bị thổi phồng có nên được gắn vào tham số gốc không? Nếu sai, root chỉ được sử dụng để tạo lớp con chính xác của LayoutParams cho chế độ xem gốc trong XML.

Ai đó có thể vui lòng giải thích chi tiết hơn, cụ thể là chế độ xem gốc là gì và có thể hiển thị ví dụ về thay đổi hành vi giữa truefalsecác giá trị không?



Câu trả lời:


157

NGAY BÂY GIỜ

Sự khác biệt chính giữa tham số "thứ ba" Đính kèm là đúng hoặc sai là đây.

Khi bạn đặt Đính kèm

true: thêm chế độ xem con vào cha mẹ NGAY BÂY GIỜ
sai: thêm chế độ xem con vào cha mẹ KHÔNG NGAY BÂY GIỜ .
Thêm nó sau. `

Khi nào thì muộn hơn ?

Đó là sau khi bạn sử dụng ví dụ parent.addView(childView)

Một quan niệm sai lầm phổ biến là, nếu tham số Đính kèmRoot là sai thì chế độ xem con sẽ không được thêm vào cha mẹ. SAI
Trong cả hai trường hợp, chế độ xem con sẽ được thêm vào ParentView. Nó chỉ là vấn đề thời gian .

inflater.inflate(child,parent,false);
parent.addView(child);   

tương đương với

inflater.inflate(child,parent,true);

MỘT KHÔNG CÓ KHÔNG LỚN
Bạn không bao giờ nên vượt qua Đính kèm là đúng khi bạn không chịu trách nhiệm thêm chế độ xem con vào cha mẹ.
Ví dụ: khi thêm Fragment

public View onCreateView(LayoutInflater inflater,ViewGroup parent,Bundle bundle)
  {
        super.onCreateView(inflater,parent,bundle);
        View view = inflater.inflate(R.layout.image_fragment,parent,false);
        .....
        return view;
  }

nếu bạn vượt qua tham số thứ ba là đúng, bạn sẽ nhận được IllegalStateException vì anh chàng này.

getSupportFragmentManager()
      .beginTransaction()
      .add(parent, childFragment)
      .commit();

Vì bạn đã thêm đoạn con trong onCreateView () do nhầm lẫn. Gọi thêm sẽ cho bạn biết rằng chế độ xem con đã được thêm vào cha mẹ Do đó IllegalStateException .
Ở đây bạn không chịu trách nhiệm thêm childView, FragmentManager chịu trách nhiệm. Vì vậy, luôn luôn vượt qua sai trong trường hợp này.

LƯU Ý: Tôi cũng đã đọc rằng ParentView sẽ không nhận được childView touchEvents nếu Đính kèm là sai. Nhưng tôi đã không kiểm tra nó mặc dù.


6
Rất hữu ích, đặc biệt là phần liên quan đến FragmentManager, cảm ơn bạn!
CybeX

94

Nếu được đặt thành true thì khi bố trí của bạn bị thổi phồng, nó sẽ tự động được thêm vào cấu trúc phân cấp khung nhìn của Viewgroup được chỉ định trong tham số thứ 2 khi còn nhỏ. Ví dụ: nếu tham số gốc là mộtLinearLayout chế độ xem bị thổi phồng của bạn sẽ được tự động thêm vào dưới dạng con của chế độ xem đó.

Nếu nó được đặt thành false thì bố cục của bạn sẽ bị thổi phồng nhưng sẽ không được gắn với bất kỳ bố cục nào khác (vì vậy nó sẽ không được vẽ, nhận các sự kiện chạm, v.v.).


17
Tôi bối rối. Tôi đã nhận được một "đứa trẻ rõ đã có một lỗi cha mẹ” cho đến khi tôi đọc câu trả lời này , mà đạo diễn của tôi để sử dụng falsecho attachToRoottrong Fragment của tôi onCreateView. Đây đã giải quyết được vấn đề và chưa bố trí của đoạn có thể nhìn thấy và hoạt động, mặc dù câu trả lời của bạn. Chuyện gì xảy ra đây?
Jeff Axelrod

67
Bởi vì một mảnh tự động đính kèm bố cục được trả về từ onCreateView. Vì vậy, nếu bạn đính kèm thủ công trong onCreateView thì chế độ xem của bạn sẽ được gắn vào 2 cha mẹ (điều này tạo ra lỗi bạn đề cập).
Joseph Earl

11
Tôi hơi bối rối ở đây, @JosephEarl bạn đã nói nếu được đặt thành true, chế độ xem được gắn với tham số thứ 2 container, nhưng sau đó bạn nói đoạn được tự động đính kèm từ đó onCreateView(), vì vậy theo hiểu biết của tôi, tham số thứ ba là vô dụng và nên được đặt falseluôn luôn?
unmultimedio

5
Bạn trả về chế độ xem trong lượt xem, điều này sau đó được tự động đính kèm. Nếu bạn đặt đính kèm thành true, một lỗi sẽ được đưa ra. Tuy nhiên, khi bạn tăng chế độ xem trong tình huống độc lập, bạn có thể chọn tự động gắn chế độ xem vào vùng chứa của nó bằng cách đặt thành đúng. Tôi hầu như không bao giờ được đặt thành đúng mặc dù tôi luôn tự thêm quan điểm.
sương giá

7
@unmultimedio nó chỉ vô dụng đối với chế độ xem gốc được trả về onCreateView. Nếu bạn tăng các bố cục tiếp theo vào chế độ xem gốc hoặc bạn đang thổi phồng trong một bối cảnh khác (ví dụ: trong một Hoạt động) thì điều đó rất hữu ích.
Joseph Earl

36

Có vẻ như rất nhiều văn bản trong các câu trả lời nhưng không có mã, đó là lý do tại sao tôi quyết định làm sống lại câu hỏi cũ này bằng một ví dụ về mã, trong một số câu trả lời mà mọi người đã đề cập:

Nếu được đặt thành true thì khi bố trí của bạn bị thổi phồng, nó sẽ tự động được thêm vào cấu trúc phân cấp khung nhìn của Viewgroup được chỉ định trong tham số thứ 2 khi còn nhỏ.

Điều thực sự có nghĩa trong mã (điều mà hầu hết các lập trình viên hiểu) là:

public class MyCustomLayout extends LinearLayout {
    public MyCustomLayout(Context context) {
        super(context);
        // Inflate the view from the layout resource and pass it as child of mine (Notice I'm a LinearLayout class).

        LayoutInflater.from(context).inflate(R.layout.child_view, this, true);
    }
}

Lưu ý rằng mã trước đó đang thêm bố cục R.layout.child_viewlà con của MyCustomLayoutattachToRootparam là truevà gán các tham số bố cục của cha mẹ chính xác theo cùng một cách như tôi sẽ sử dụng theo addViewchương trình, hoặc như tôi đã làm điều này trong xml:

<LinearLayout>
   <View.../>
   ...
</LinearLayout>

Các mã sau đây giải thích kịch bản khi đi qua attachRootnhư false:

LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setLayoutParams(new LayoutParams(
    LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
linearLayout.setOrientation(LinearLayout.VERTICAL);
    // Create a stand-alone view
View myView = LayoutInflater.from(context)
    .inflate(R.layout.ownRootView, null, false);
linearLayout.addView(myView);

Trong mã trước đó, bạn xác định rằng bạn muốn myViewtrở thành đối tượng gốc của chính nó và không đính kèm nó với bất kỳ cha mẹ nào, sau này chúng tôi đã thêm nó như là một phần củaLinearLayout nhưng trong một khoảnh khắc, nó là chế độ xem độc lập (không có cha mẹ).

Điều tương tự cũng xảy ra với Fragment, bạn có thể thêm chúng vào một nhóm đã tồn tại và là một phần của nó hoặc chỉ truyền các tham số:

Inflater.inflate (R.layout.fragment, null, false);

Để xác định rằng nó sẽ là root riêng của nó.


1
Trong tất cả, đây là hữu ích nhất.
Wahib Ul Haq

26

Tài liệu và hai câu trả lời trước là đủ, chỉ cần một vài suy nghĩ từ tôi.

Các inflatephương pháp được sử dụng để thổi phồng các file layout. Với những bố trí bị thổi phồng, bạn có khả năng gắn chúng trực tiếp với cha mẹViewGroup hoặc chỉ thổi phồng cấu trúc khung nhìn từ tệp bố cục đó và làm việc với nó bên ngoài hệ thống phân cấp chế độ xem bình thường.

Trong trường hợp đầu tiên, attachToRoottham số sẽ phải được đặt thành true(hoặc đơn giản là sử dụng inflatephương thức lấy tệp bố cục và gốc cha ViewGroup(không null)). Trong trường hợp này, Viewtrả về chỉ đơn giản ViewGrouplà đã được truyền trong phương thức,ViewGroup hệ thống phân cấp khung nhìn bị thổi phồng sẽ được thêm vào.

Đối với tùy chọn thứ hai, trả về Viewlà gốc ViewGrouptừ tệp bố trí. Nếu bạn nhớ cuộc thảo luận cuối cùng của chúng tôi từ include-mergecâu hỏi cặp thì đây là một trong những lý do cho mergegiới hạn của (khi tệp bố cục với mergegốc bị thổi phồng, bạn phải cung cấp cho cha mẹ và attachedToRootphải được đặt thành true). Nếu bạn có một tệp bố cục với mergethẻ gốc và attachedToRootđược đặt thành falsethì inflatephương thức sẽ không có gì để trả về vì mergekhông có tương đương. Ngoài ra, như tài liệu nói, inflatephiên bản attachToRootđược đặt thànhfalse quan trọng vì bạn có thể tạo cấu trúc phân cấp chế độ xem với chính xácLayoutParamstừ cha mẹ Điều này rất quan trọng trong một số trường hợp, đáng chú ý nhất với trẻ em AdapterView, một lớp con của các phương thức không được hỗ trợ. Tôi chắc rằng bạn nhớ lại bằng cách sử dụng dòng này trong phương thức:ViewGroup , mà cácaddView()getView()

convertView = inflater.inflate(R.layout.row_layout, parent, false);

Dòng này đảm bảo rằng R.layout.row_layouttệp bị thổi phồng có chính xác LayoutParamstừ AdapterViewlớp con được đặt trên thư mục gốc của nó ViewGroup. Nếu bạn không làm điều này, bạn có thể gặp một số vấn đề với tệp bố cục nếu gốc là a RelativeLayout. Điều này TableLayout/TableRowcũng có một số đặc biệt và quan trọng LayoutParamsvà bạn nên chắc chắn rằng quan điểm trong đó có chính xác LayoutParams.


18

Bản thân tôi cũng bị nhầm lẫn về là gì mục đích thực sự của attachToRoottrong inflatephương pháp. Sau một chút nghiên cứu về UI, cuối cùng tôi cũng có câu trả lời:

cha mẹ:

trong trường hợp này là widget / layout bao quanh các đối tượng view mà bạn muốn thổi phồng bằng findViewById ().

Đính kèm:

đính kèm các khung nhìn với cha mẹ của chúng (bao gồm chúng trong cấu trúc phân cấp cha mẹ), do đó, bất kỳ sự kiện chạm nào mà các khung nhìn nhận được cũng sẽ được chuyển sang dạng xem cha mẹ. Bây giờ tùy thuộc vào phụ huynh cho dù họ muốn giải trí những sự kiện đó hoặc bỏ qua chúng. nếu được đặt thành false, chúng không được thêm dưới dạng con trực tiếp của cha mẹ và cha mẹ không nhận được bất kỳ sự kiện chạm nào từ các chế độ xem.

Hy vọng điều này sẽ xóa sự nhầm lẫn


Câu trả lời của bạn đã được cung cấp tại đây: stackoverflow.com/questions/22326314/ từ
Chiến tranh neon 30/11/2015

11

Tôi đã viết câu trả lời này bởi vì ngay cả sau khi đi qua một số trang StackOverflow tôi vẫn không thể nắm bắt rõ ràng ý nghĩa của Đính kèm. Dưới đây là phương thức Inflate () trong lớp LayoutInflater.

View inflate (int resource, ViewGroup root, boolean attachToRoot)

Hãy nhìn vào activity_main.xml tập tin, button.xml bố trí và MainActivity.java tập tin tôi tạo ra.

Activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

</LinearLayout>

button.xml

<Button xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

MainActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    LayoutInflater inflater = getLayoutInflater();
    LinearLayout root = (LinearLayout) findViewById(R.id.root);
    View view = inflater.inflate(R.layout.button, root, false);
}

Khi chúng tôi chạy mã, chúng tôi sẽ không thấy nút trong bố cục. Điều này là do bố trí nút của chúng tôi không được thêm vào bố trí hoạt động chính vì Đính kèm được đặt thành sai.

Tuyến tính có một phương thức addView (Chế độ xem) có thể được sử dụng để thêm Chế độ xem vào Tuyến tính. Điều này sẽ thêm bố cục nút vào bố trí hoạt động chính và làm cho nút hiển thị khi bạn chạy mã.

root.addView(view);

Chúng ta hãy xóa dòng trước đó và xem điều gì sẽ xảy ra khi chúng ta đặt tệp đính kèm là đúng.

View view = inflater.inflate(R.layout.button, root, true);

Một lần nữa chúng ta thấy rằng bố trí nút có thể nhìn thấy. Điều này là do Đính kèm trực tiếp gắn bố cục bị thổi phồng vào cha mẹ được chỉ định. Mà trong trường hợp này là rootLayout gốc. Ở đây chúng ta không phải thêm các khung nhìn theo cách thủ công như chúng ta đã làm trong trường hợp trước với phương thức addView (Chế độ xem).

Tại sao mọi người lại nhận được IllegalStateException khi cài đặt Đính kèm là đúng cho một mảnh.

Điều này là do đối với một đoạn bạn đã chỉ định nơi đặt bố cục đoạn trong tệp hoạt động của mình.

FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
    .add(R.id.root, fragment)
    .commit();

Các bổ sung (int Parent, Fragment Fragment) thêm phần có bố cục của nó vào bố trí cha. Nếu chúng tôi đặt Đính kèm là đúng, bạn sẽ nhận được IllegalStateException: Đứa trẻ được chỉ định đã có cha mẹ. Vì bố cục đoạn đã được thêm vào bố trí cha trong phương thức add ().

Bạn phải luôn luôn chuyển sai cho Đính kèm khi bạn đang thổi phồng Mảnh vỡ. Công việc của FragmentManag là thêm, xóa và thay thế Fragment.

Quay lại ví dụ của tôi. Nếu chúng ta làm cả hai.

View view = inflater.inflate(R.layout.button, root, true);
root.addView(view);

Trong dòng đầu tiên, LayoutInflater gắn bố cục nút vào bố trí gốc và trả về một đối tượng View giữ bố cục nút tương tự. Trong dòng thứ hai, chúng ta thêm cùng một đối tượng View vào bố trí gốc cha. Điều này dẫn đến cùng một IllegalStateException mà chúng ta đã thấy với Fragment (Đứa trẻ được chỉ định đã có cha mẹ).

Hãy nhớ rằng có một phương thức Inflate () quá tải khác, nó đặt Đính kèm theo đúng theo mặc định.

View inflate (int resource, ViewGroup root)

Giải thích đơn giản và rõ ràng, chỉ là những gì tôi đang tìm kiếm!
FlyingAssistant

10

Có rất nhiều nhầm lẫn về chủ đề này do tài liệu cho phương thức Inflate ().

Nói chung, nếu AttachToRoot được đặt thành true, thì tệp bố cục được chỉ định trong tham số đầu tiên sẽ bị thổi phồng và được gắn vào Viewgroup được chỉ định trong tham số thứ hai tại thời điểm đó. Khi AttachToRoot sai, tệp bố cục từ tham số đầu tiên bị thổi phồng và được trả về dưới dạng View và bất kỳ tệp đính kèm View nào xảy ra vào một thời điểm khác.

Điều này có lẽ không có ý nghĩa nhiều trừ khi bạn thấy rất nhiều ví dụ. Khi gọi LayoutInflater.inflate () bên trong phương thức onCreateView của Fragment, bạn sẽ muốn chuyển sai thành tệp đính kèm vì Activity hoạt động với Fragment đó thực sự chịu trách nhiệm thêm chế độ xem của Fragment đó. Nếu bạn đang thổi phồng thủ công và thêm Chế độ xem vào Chế độ xem khác vào một thời điểm sau, chẳng hạn như với phương thức addView (), bạn sẽ muốn chuyển sai thành tệp đính kèm vì phần đính kèm xuất hiện vào thời điểm muộn hơn.

Bạn có thể đọc về một số ví dụ độc đáo khác liên quan đến Hộp thoại và Chế độ xem tùy chỉnh trên một bài đăng trên blog tôi đã viết về chính chủ đề này.

https://www.bignerdranch.com/blog/under Hiểu-androids-layoutinflater-inflate /


4

attachToRootđược đặt thành true nghĩa là inflatedViewsẽ được thêm vào cấu trúc phân cấp của khung nhìn cha. Do đó, người dùng có thể có thể "nhìn thấy" và cảm nhận các sự kiện chạm (hoặc bất kỳ hoạt động UI nào khác). Mặt khác, nó chỉ được tạo, không được thêm vào bất kỳ hệ thống phân cấp xem nào và do đó không thể nhìn thấy hoặc xử lý các sự kiện chạm.

Đối với các nhà phát triển iOS mới sử dụng Android, attachToRootđược đặt thành true có nghĩa là bạn gọi phương thức này:

[parent addSubview:inflatedView];

Nếu đi xa hơn bạn có thể hỏi: Tại sao tôi phải vượt qua chế độ xem phụ huynh nếu tôi đặt attachToRootthành false? Đó là bởi vì phần tử gốc trong cây XML của bạn cần chế độ xem chính để tính toán một số LayoutParams (như đối sánh cha mẹ).


0

Khi bạn xác định cha mẹ, tệp đính kèm sẽ xác định xem bạn có muốn thực sự gắn nó vào phụ huynh hay không. Trong một số trường hợp, điều này gây ra sự cố, như trong ListAd CHƯƠNG, nó sẽ gây ra ngoại lệ vì danh sách cố gắng thêm chế độ xem vào danh sách nhưng thông báo cho biết nó đã được đính kèm. Trong các trường hợp khác, nơi bạn chỉ tự thổi phồng khung nhìn để thêm vào Hoạt động, nó có thể hữu ích và giúp bạn tiết kiệm một dòng mã.


1
không đưa ra một hình ảnh rõ ràng mà một câu trả lời tốt sẽ cung cấp.
Prakhar1001

0

Ví dụ, chúng ta có một ImageView, a LinearLayoutvà a RelativeLayout. Tuyến tính là con của RelativeLayout. Chế độ xem phân cấp sẽ là.

RelativeLayout
           ------->LinearLayout

và chúng tôi có một tệp bố cục riêng cho ImageView

image_view_layout.xml

Đính kèm vào root:

//here container is the LinearLayout

    View v = Inflater.Inflate(R.layout.image_view_layout,container,true);
  1. Ở đây v chứa tham chiếu của bố trí vùng chứa, ví dụ như linearLayout.and nếu bạn muốn đặt các tham số như setImageResource(R.drawable.np);ImageView, bạn sẽ phải tìm nó bằng tham chiếu của cha mẹ tức làview.findById()
  2. Phụ huynh của v sẽ là FrameLayout.
  3. LayoutParams sẽ là của FrameLayout.

Không đính kèm với root:

//here container is the LinearLayout
    View v = Inflater.Inflate(R.layout.image_view_layout,container,false);
  1. Ở đây v không chứa bố cục vùng chứa tham chiếu nhưng tham chiếu trực tiếp đến ImageView được tăng cường để bạn có thể đặt tham số của nó như thế nào view.setImageResource(R.drawable.np);mà không cần tham chiếu như thế nào findViewById. Nhưng bộ chứa được chỉ định để ImageView có được LayoutParams của bộ chứa để bạn có thể nói rằng tham chiếu của bộ chứa chỉ dành cho LayoutParams chứ không có gì khác.
  2. Vì vậy, trong trường hợp cụ thể Cha mẹ sẽ là null.
  3. LayoutParams sẽ là của linearLayout.

0

Đính kèm Đặt thành đúng:

Nếu AttachToRoot được đặt thành true, thì tệp bố cục được chỉ định trong tham số đầu tiên được thổi phồng và được gắn vào Viewgroup được chỉ định trong tham số thứ hai.

Hãy tưởng tượng chúng ta đã chỉ định một nút trong tệp bố cục XML với chiều rộng bố cục và chiều cao bố cục của nó được đặt thành match_parent.

<Button xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/custom_button">
</Button>

Bây giờ chúng tôi muốn lập trình thêm Nút này vào Tuyến tính trong một Đoạn hoặc Hoạt động. Nếu linearLayout của chúng tôi đã là một biến thành viên, mLinearLayout, chúng tôi chỉ cần thêm nút bằng cách sau:

inflater.inflate(R.layout.custom_button, mLinearLayout, true);

Chúng tôi đã chỉ định rằng chúng tôi muốn thổi phồng Nút từ tệp tài nguyên bố cục của nó; sau đó chúng tôi nói với LayoutInflater rằng chúng tôi muốn đính kèm nó vào mLinearLayout. Các tham số bố trí của chúng tôi được vinh danh vì chúng tôi biết Nút được thêm vào Tuyến tính. Kiểu tham số bố trí của Nút phải là linearLayout.LayoutParams.

AttachToRoot Đặt thành false (không bắt buộc phải sử dụng false)

Nếu AttachToRoot được đặt thành false, thì tệp bố cục được chỉ định trong tham số đầu tiên bị thổi phồng và không được đính kèm với Viewgroup được chỉ định trong tham số thứ hai nhưng chế độ xem bị thổi phồng đó có được LayoutParams của cha mẹ , cho phép khung nhìn đó khớp chính xác với cha mẹ.


Chúng ta hãy xem khi nào bạn muốn đặt Đính kèm thành sai. Trong trường hợp này, Chế độ xem được chỉ định trong tham số đầu tiên của Inflate () không được đính kèm với Viewgroup trong tham số thứ hai tại thời điểm này.

Nhớ lại ví dụ về Nút của chúng tôi từ trước đó, nơi chúng tôi muốn đính kèm Nút tùy chỉnh từ tệp bố cục vào mLinearLayout. Chúng tôi vẫn có thể đính kèm Nút của mình vào mLinearLayout bằng cách chuyển thành false cho tệp đính kèm, chúng tôi chỉ cần tự thêm nó vào nút.

Button button = (Button) inflater.inflate(R.layout.custom_button,    mLinearLayout, false);
mLinearLayout.addView(button);

Hai dòng mã này tương đương với những gì chúng ta đã viết trước đó trong một dòng mã khi chúng ta chuyển thành true cho AttachToRoot. Bằng cách chuyển sai, chúng tôi nói rằng chúng tôi chưa muốn đính kèm Chế độ xem của mình vào Viewgroup gốc. Chúng tôi đang nói rằng nó sẽ xảy ra tại một số thời điểm khác. Trong ví dụ này, thời điểm khác chỉ đơn giản là phương thức addView () được sử dụng ngay bên dưới lạm phát.

Ví dụ Đính kèm sai giả yêu cầu thêm một chút công việc khi chúng tôi thêm Chế độ xem theo cách thủ công vào Viewgroup.

AttachToRoot Đặt thành false (Bắt buộc sai)

Khi thổi phồng và trả về Chế độ xem của Fragment trong onCreateView (), hãy chắc chắn chuyển thành false cho Đính kèmRoot. Nếu bạn vượt qua đúng, bạn sẽ nhận được IllegalStateException vì đứa trẻ được chỉ định đã có cha mẹ. Bạn nên chỉ định nơi chế độ xem Mảnh vỡ của bạn sẽ được đặt lại trong Hoạt động của bạn. Công việc của FragmentManag là thêm, xóa và thay thế Fragment.

FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragment =  fragmentManager.findFragmentById(R.id.root_viewGroup);

if (fragment == null) {
fragment = new MainFragment();
fragmentManager.beginTransaction()
    .add(R.id.root_viewGroup, fragment)
    .commit();
}

Bộ chứa root_viewgroup sẽ giữ Fragment của bạn trong Activity là tham số Viewgroup được cung cấp cho bạn trong onCreateView () trong Fragment của bạn. Đây cũng là Viewgroup mà bạn chuyển vào LayoutInflater.inflate (). Tuy nhiên, FragmentManager sẽ xử lý việc đính kèm Chế độ xem của Fragment của bạn vào Viewgroup này. Bạn không muốn đính kèm hai lần. Đặt AttachToRoot thành false.

public View onCreateView(LayoutInflater inflater, ViewGroup  parentViewGroup, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout,     parentViewGroup, false);

return view;
}

Tại sao chúng tôi lại cho Viewgroup cha mẹ của Fragment ở vị trí đầu tiên nếu chúng tôi không muốn đính kèm nó trong onCreateView ()? Tại sao phương thức Inflate () yêu cầu một Viewgroup gốc?

Hóa ra, ngay cả khi chúng tôi không ngay lập tức thêm Chế độ xem mới được tăng cường vào Viewgroup mẹ của nó, chúng tôi vẫn nên sử dụng LayoutParams của cha mẹ để Chế độ xem mới xác định kích thước và vị trí của nó bất cứ khi nào cuối cùng được gắn vào.

Liên kết: https://youtu.be/1Y0LlmTCOkM?t=409


0

Chỉ chia sẻ một số điểm mà tôi gặp phải khi làm việc về chủ đề này,

Ngoài câu trả lời được chấp nhận, tôi muốn một số điểm có thể giúp ích.

Vì vậy, khi tôi sử dụng AttachToRoot là true, chế độ xem được trả về là kiểu Viewgroup, tức là Viewgroup gốc của cha mẹ, được truyền làm tham số cho phương thức Inflate (layoutResource, Viewgroup, AttachToRoot) , không phải kiểu bố trí được truyền nhưng trên Đính kèm như sai chúng tôi nhận được loại chức năng trả lại rằng gốc layoutResource của ViewGroup .

Hãy để tôi giải thích với một ví dụ:

Nếu chúng ta có một linearLayout làm bố cục gốc và sau đó chúng ta muốn thêm TextView trong nó thông qua chức năng lạm phát .

sau đó về việc sử dụng attachToRoot như đúng chức năng thổi phồng trả về một Xem kiểu LinearLayout

trong khi sử dụng attachToRoot như sai chức năng thổi phồng trả về một Xem kiểu TextView

Hy vọng phát hiện này sẽ giúp ích được ...

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.