LayoutInflater attachToRoot 매개 변수는 무엇을 의미합니까? attachToRoot : 팽창 된 계층 구조를

LayoutInflater.inflate문서는 정확하게의 목적에 대해 나에게 분명하지 않다 attachToRoot매개 변수입니다.

attachToRoot : 팽창 된 계층 구조를 루트 매개 변수에 첨부 해야하는지 여부 false 인 경우 root는 XML에서 루트 뷰에 대한 올바른 LayoutParams 서브 클래스를 작성하는 데만 사용됩니다.

누군가가 구체적으로 루트 뷰가 무엇인지 자세히 설명 true하고 false값 사이의 동작 변화의 예를 보여 줄 수 있습니까?



답변

지금 또는 지금

“third”매개 변수 attachToRoot가 true 또는 false 인 것의 주요 차이점은 이것입니다.

attachToRoot를 넣을 때

true : 상위 뷰에 하위 뷰 추가 RIGHT NOW
false : 하위 뷰를 상위 NOT NOW에 추가합니다 .
나중에 추가하십시오. `

때 즉 나중에 ?

나중에 당신이 예를 들어 사용할 때입니다 parent.addView(childView)

일반적인 오해는 attachToRoot 매개 변수가 다음 아이 뷰는 부모에 추가되지 않습니다 false 인 경우이다. 잘못된
경우 두 경우 모두 하위 뷰가 parentView에 추가됩니다. 시간 문제 일뿐 입니다.

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

에 해당

inflater.inflate(child,parent,true);

큰 아니오 아니오
하위 뷰를 상위에 추가 할 책임이없는 경우 attachToRoot를 true로 전달해서는 안됩니다.
예를 들어 조각을 추가 할 때

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

세 번째 매개 변수를 true로 전달하면이 사람으로 인해 IllegalStateException이 발생합니다.

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

실수로 onCreateView ()에 하위 조각을 이미 추가했기 때문에. add를 호출하면 자식 뷰가 이미 부모 IllegalStateException에 추가되었음을 알 수 있습니다 .
여기에서는 childView를 추가 할 책임이 없으며 FragmentManager가 책임집니다. 따라서이 경우 항상 false를 전달하십시오.

참고 : attachToRoot가 false 인 경우 parentView가 childView touchEvents를 얻지 못한다는 것을 읽었습니다. 그러나 나는 그것을 테스트하지 않았습니다.


답변

true로 설정하면 레이아웃이 팽창 될 때 두 번째 매개 변수에 지정된 ViewGroup의 뷰 계층 구조에 하위 항목으로 자동 추가됩니다. 예를 들어 루트 매개 변수가 인 경우 LinearLayout팽창 된 뷰가 해당 뷰의 하위로 자동 추가됩니다.

false로 설정하면 레이아웃이 팽창하지만 다른 레이아웃에 첨부되지 않습니다 (그리기, 터치 이벤트 수신 등).


답변

응답에 많은 텍스트가있는 것처럼 보이지만 코드는 없기 때문에 사람들이 언급 한 여러 응답 에서이 예제를 코드 예제와 함께 부활 시키기로 결정했습니다.

true로 설정하면 레이아웃이 팽창 될 때 두 번째 매개 변수에 지정된 ViewGroup의 뷰 계층 구조에 하위 항목으로 자동 추가됩니다.

코드에서 실제로 의미하는 것 (대부분의 프로그래머가 이해하는 것)은 다음과 같습니다.

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

이전 코드는 param R.layout.child_view으로 MyCustomLayout인해 레이아웃 을 자식으로 추가하고 있으며 프로그래밍 방식 으로 사용 하는 것처럼 또는 xml에서이를 수행 하는 것처럼 정확히 동일한 방식으로 부모의 레이아웃 매개 변수를 할당합니다 .attachToRoottrueaddView

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

전달할 때 다음 코드는 시나리오를 설명 attachRoot으로 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);

이전 코드에서는 myView자신의 루트 객체가되고 싶었고 부모에게 연결하지 않기로 지정했습니다. 나중에이 객체의 일부로 추가 LinearLayout했지만 잠시 동안 독립형 (부모 없음)보기였습니다.

Fragments에서도 동일한 일이 발생합니다. 기존 그룹에 추가하여 그룹에 속하거나 매개 변수를 전달할 수 있습니다.

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

그것이 자신의 루트가되도록 지정합니다.


답변

문서와 이전의 두 가지 대답으로 충분할 것입니다.

inflate방법은 레이아웃 파일을 팽창시키는 데 사용됩니다. 팽창 된 레이아웃을 사용하면 레이아웃을 부모에 직접 첨부 ViewGroup하거나 해당 레이아웃 파일에서 뷰 계층을 팽창시켜 일반 뷰 계층 외부에서 작업 할 수 있어야합니다.

첫 번째 경우 attachToRoot매개 변수는로 설정해야합니다 true(또는 inflate레이아웃 파일과 상위 루트 ViewGroup(non null)를 사용하는 방법을 훨씬 간단하게 사용 ). 이 경우 View반환 된 값은 단순히 ViewGroup메소드에서 전달 된 ViewGroup것입니다. 부풀려진 뷰 계층 구조가 추가됩니다.

두 번째 옵션의 경우 레이아웃 파일 View의 루트가 반환 ViewGroup됩니다. include-merge쌍 질문에 대한 마지막 토론을 기억한다면 이것이 merge제한 의 이유 중 하나입니다 ( merge루트로 레이아웃 파일 이 팽창 할 때 부모를 제공 attachedToRoot해야하고로 설정해야합니다 true). 루트와 레이아웃 파일을 가지고 있다면 merge태그와 attachedToRoot로 설정 false한 다음 inflate방법으로 반환 할 것도 없을 것이다 merge동등한를하지 않습니다. 또한 설명서에서 알 수 있듯이 inflateattachToRoot설정된 버전 false은 중요합니다.LayoutParams부모로부터. 이것은의 아이들과 함께 가장 주목할만한, 경우에 중요하다 AdapterView,의 서브 클래스 ViewGroup하는, addView()방법 세트가 지원되지 않습니다. 나는 당신이 getView()방법 에서이 줄을 사용하여 기억합니다 :

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

팽창이 줄을 보장하지만 R.layout.row_layout파일이 올바른 가지고 LayoutParams로부터 AdapterView루트에 서브 클래스 세트를 ViewGroup. 이 작업을 수행하지 않으면 루트가이면 레이아웃 파일에 문제가있을 수 있습니다 RelativeLayout. 는 TableLayout/TableRow또한 몇 가지 특별하고 중요한을 가지고 LayoutParams당신은 확실히 그들의 견해가 올바른가 확인해야합니다 LayoutParams.


답변

나 자신도의 진짜 목적은 무엇인지에 대해 혼란스러워하고 attachToRoot있는 inflate방법. 약간의 UI 연구 후에 마침내 대답을 얻었습니다.

부모의:

이 경우 findViewById ()를 사용하여 팽창하려는 뷰 객체를 둘러싼 위젯 / 레이아웃입니다.

attachToRoot :

뷰를 상위에 연결하여 (부모 계층에 포함) 뷰를 수신하는 모든 터치 이벤트도 상위 뷰로 전송됩니다. 이제 이벤트를 즐겁게하거나 무시할 것인지는 부모에게 달려 있습니다. false로 설정하면 부모의 직계 자식으로 추가되지 않으며 부모는 뷰에서 터치 이벤트를받지 않습니다.

이것이 혼란을 없애기를 바랍니다.


답변

이 답변은 여러 StackOverflow 페이지를 거친 후에도 attachToRoot의 의미를 명확하게 파악할 수 없었기 때문에 작성되었습니다. 아래는 LayoutInflater 클래스의 inflate () 메서드입니다.

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

activity_main.xml 파일, button.xml 레이아웃 및 내가 만든 MainActivity.java 파일을 살펴보십시오 .

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

코드를 실행하면 레이아웃에 버튼이 표시되지 않습니다. attachToRoot가 false로 설정되어 있기 때문에 버튼 레이아웃이 기본 활동 레이아웃에 추가되지 않기 때문입니다.

LinearLayout에는 LinearLayout 에 뷰를 추가하는 데 사용할 수 있는 addView (View view) 메소드가 있습니다. 이렇게하면 버튼 레이아웃이 기본 활동 레이아웃에 추가되고 코드를 실행할 때 버튼이 표시됩니다.

root.addView(view);

이전 행을 제거하고 attachToRoot를 true로 설정하면 어떻게되는지 봅시다.

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

다시 버튼 레이아웃이 보입니다. attachToRoot가 팽창 된 레이아웃을 지정된 상위에 직접 첨부하기 때문입니다. 이 경우 루트 LinearLayout입니다. addView (View view) 메소드로 이전과 같이 수동으로 뷰를 추가 할 필요가 없습니다.

Fragment에 대해 attachToRoot를 true로 설정할 때 사람들이 IllegalStateException을 얻는 이유는 무엇입니까?

조각의 경우 활동 파일에서 조각 레이아웃을 배치 할 위치를 이미 지정했기 때문입니다.

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

추가 (INT 부모, 조각 조각은) 부모 레이아웃에 그것의 레이아웃이 조각을 추가합니다. attachToRoot를 true로 설정하면 IllegalStateException이 발생합니다. 지정된 자식에 이미 부모가 있습니다. add () 메서드에서 조각 레이아웃이 이미 부모 레이아웃에 추가 되었기 때문에

프래그먼트를 부 풀릴 때 attachToRoot에 대해 항상 false를 전달해야합니다. FragmentManager를 추가, 제거 및 교체하는 것은 FragmentManager의 작업입니다.

내 예로 돌아 가기 우리 둘 다하면 어떡해?

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

첫 번째 줄에서 LayoutInflater는 버튼 레이아웃을 루트 레이아웃에 연결하고 동일한 버튼 레이아웃을 보유하는 View 객체를 반환합니다. 두 번째 줄에서는 부모 뷰에 동일한 View 객체를 추가합니다. 결과적으로 Fragments와 동일한 IllegalStateException이 발생합니다 (지정된 자식에는 이미 부모가 있습니다).

기본적으로 attachToRoot를 true로 설정하는 또 다른 오버로드 된 inflate () 메소드가 있습니다.

View inflate (int resource, ViewGroup root)


답변

inflate () 메소드에 대한 문서로 인해이 주제에 대해 많은 혼동이 있습니다.

일반적으로 attachToRoot가 true로 설정되면 첫 번째 매개 변수에 지정된 레이아웃 파일이 팽창되어 해당 순간 두 번째 매개 변수에 지정된 ViewGroup에 첨부됩니다. attachToRoot가 false이면 첫 번째 매개 변수의 레이아웃 파일이 팽창되어 View로 리턴되며 다른 시점에 View 첨부 파일이 발생합니다.

예를 많이 보지 않으면 의미가 없습니다. Fragment의 onCreateView 메소드 내에서 LayoutInflater.inflate ()을 호출 할 때 해당 Fragment와 연관된 활동이 실제로 해당 Fragment의보기를 추가해야하기 때문에 attachToRoot에 대해 false를 전달하려고합니다. addView () 메소드와 같이 나중에 특정 시점에 다른보기에보기를 수동으로 부풀리고 추가하는 경우 첨부 파일이 나중에 제공되므로 attachToRoot에 대해 false로 전달하려고합니다.

이 주제에 대해 쓴 블로그 게시물에서 대화 상자 및 사용자 정의보기와 관련된 몇 가지 다른 고유 예제를 읽을 수 있습니다.

https://www.bignerdranch.com/blog/understanding-androids-layoutinflater-inflate/