LayoutInflater attachToRoot 매개 변수는 무엇을 의미합니까?


201

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

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

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



답변:


157

지금 또는 지금

"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를 얻지 못한다는 것을 읽었습니다. 그러나 나는 그것을 테스트하지 않았습니다.


6
특히 도움이되는 부분에 대해 매우 FragmentManager감사합니다!
CybeX

94

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

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


17
혼란 스러워요. 나는 내가 읽은 때까지 "지정된 아이가 이미 부모 오류가"지고 있다고 이 답변 내 사용할 감독 false에 대한 attachToRoot나의 조각의 동안 onCreateView.이 문제와 아직 단편의 레이아웃이 당신의 대답에도 불구하고, 볼 수와 활성을 해결합니다. 무슨 일이야을 여기에?
제프 악셀로드

67
Fragment는 onCreateView에서 반환 된 레이아웃을 자동으로 연결하기 때문입니다. 따라서 onCreateView에서 수동으로 첨부하면 뷰가 2 개의 부모에 첨부됩니다 (이러한 오류가 발생합니다).
Joseph Earl

11
내가 조금 여기 혼란 스러워요, @JosephEarl 당신이 세트를 할 경우 말했다 true,보기는이다 두번째 매개 변수에 연결되어 container있지만, 다음 단편 자동에서 연결되어 말을 onCreateView()나의 이해, 세 번째 매개 변수는 쓸모 및 설정해야합니다 false항상?
unmultimedio

5
oncreateview에서 뷰를 반환하면 자동으로 첨부됩니다. attach를 true로 설정하면 오류가 발생합니다. 그러나 독립형 상황에서보기를 팽창시킬 때 true로 설정하여보기를 컨테이너에 자동으로 첨부하도록 선택할 수 있습니다. 항상보기를 직접 추가함에 따라 나는 거의 참으로 설정하지 않았습니다.
frostymarvelous

7
@unmultimedio는에서 반환 한 루트 뷰에만 쓸모가 없습니다 onCreateView. 추가 레이아웃을 해당 루트보기로 팽창 시키거나 다른 컨텍스트 (예 : 활동)에서 팽창하는 경우 유용합니다.
Joseph Earl

36

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

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

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


1
무엇보다도 이것이 가장 도움이되었습니다.
Wahib Ul Haq 2016

26

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

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.


18

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

부모의:

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

attachToRoot :

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

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


당신은 이미 여기에 답변을 제공합니다 : stackoverflow.com/questions/22326314/…
Neon Warge

11

이 답변은 여러 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)

간단하고 명확한 설명, 내가 찾던 것!
flyingAssistant

10

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/


4

attachToRoottrue로 설정 inflatedView하면 상위 뷰의 계층 구조에 추가됩니다. 따라서 사용자가 "보거나"터치 이벤트 (또는 다른 UI 조작)를 감지 할 수 있습니다. 그렇지 않으면 뷰 계층 구조에 추가되지 않고 생성되어 터치 이벤트를 보거나 처리 할 수 ​​없습니다.

Android를 처음 사용하는 iOS 개발자의 attachToRoot경우 true로 설정하면이 메소드를 호출합니다.

[parent addSubview:inflatedView];

더가는 경우에 당신은 요청할 수 있습니다 : 내가 설정 한 경우 이유는 부모 뷰가 통과해야 attachToRootfalse? XML 트리의 루트 요소는 일부 부모 (예 : 부모 일치)를 계산하기 위해 부모보기가 필요하기 때문입니다.


0

부모를 정의 할 때 attachToRoot는 팽창기가 실제로 부모에 부착시킬 것인지를 결정합니다. 경우에 따라 ListAdapter에서와 같이 문제가 발생하여 목록에보기를 목록에 추가하려고하지만 이미 연결되어 있기 때문에 예외가 발생합니다. 다른 경우에는 액티비티에 추가하기 위해 직접 뷰를 부 풀리는 경우 편리하고 코드 줄을 저장할 수 있습니다.


1
좋은 답변이 제공해야 할 명확한 그림을 제공하지 않습니다.
Prakhar1001

0

예를 들어 ImageView, a LinearLayout및 a가 RelativeLayout있습니다. LinearLayout은 RelativeLayout의 자식입니다. 뷰 계층이됩니다.

RelativeLayout
           ------->LinearLayout

ImageView를위한 별도의 레이아웃 파일이 있습니다

image_view_layout.xml

루트에 연결하십시오.

//here container is the LinearLayout

    View v = Inflater.Inflate(R.layout.image_view_layout,container,true);
  1. 여기에 v는 컨테이너 레이아웃의 참조, 즉 LinearLayout을 포함하고 setImageResource(R.drawable.np);ImageView 와 같은 매개 변수를 설정하려면 부모의 참조로 찾아야합니다.view.findById()
  2. v의 부모는 FrameLayout이됩니다.
  3. LayoutParams는 FrameLayout입니다.

루트에 첨부하지 마십시오 :

//here container is the LinearLayout
    View v = Inflater.Inflate(R.layout.image_view_layout,container,false);
  1. 여기에 v에는 참조 컨테이너 레이아웃이 없지만 팽창 된 ImageView에 대한 직접 참조가 포함되어 있으므로 참조 view.setImageResource(R.drawable.np);하지 않고 매개 변수를 설정할 수 있습니다 findViewById. 그러나 컨테이너는 ImageView가 컨테이너의 LayoutParams를 가져 오도록 지정되어 있으므로 컨테이너의 참조는 LayoutParams에 대한 것입니다.
  2. 따라서 특히 Parent는 null이됩니다.
  3. LayoutParams는 LinearLayout입니다.

0

attachToRoot true로 설정하십시오.

attachToRoot가 true로 설정되면 첫 번째 매개 변수에 지정된 레이아웃 파일이 팽창되어 두 번째 매개 변수에 지정된 ViewGroup에 첨부됩니다.

레이아웃 너비와 레이아웃 높이가 match_parent로 설정된 XML 레이아웃 파일에 버튼을 지정했다고 상상해보십시오.

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

이제이 버튼을 프로그래밍 방식으로 Fragment 또는 Activity 내부의 LinearLayout에 추가하려고합니다. LinearLayout이 이미 mLinearLayout의 멤버 변수 인 경우 다음과 같이 간단히 버튼을 추가 할 수 있습니다.

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

레이아웃 리소스 파일에서 Button을 팽창 시키도록 지정했습니다. 그런 다음 LayoutInflater에 mLinearLayout에 연결하고 싶다고 알려줍니다. 버튼이 LinearLayout에 추가되는 것을 알고 있기 때문에 레이아웃 매개 변수가 적용됩니다. 버튼의 레이아웃 매개 변수 유형은 LinearLayout.LayoutParams 여야합니다.

attachToRoot false로 설정 (false를 사용할 필요는 없음)

attachToRoot가 false로 설정되면 첫 번째 매개 변수에 지정된 레이아웃 파일이 팽창 되어 두 번째 매개 변수에 지정된 ViewGroup에 첨부 되지 않지만 팽창 된 뷰는 부모의 LayoutParams획득 하여 해당보기를 부모에 올바르게 맞출 수 있습니다.


attachToRoot를 false로 설정하려는시기를 살펴 보겠습니다. 이 시나리오에서 inflate ()의 첫 번째 매개 변수에 지정된 View는이 시점에서 두 번째 매개 변수의 ViewGroup에 연결되지 않습니다.

레이아웃 파일에서 mLinearLayout에 사용자 정의 버튼을 첨부하려는 이전의 Button 예제를 상기하십시오. attachToRoot에 대해 false를 전달하여 Button을 mLinearLayout에 계속 연결할 수 있습니다. 나중에 수동으로 직접 추가하면됩니다.

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

이 두 줄의 코드는 attachToRoot에 대해 true로 전달 될 때 한 줄의 코드로 앞서 작성한 것과 동일합니다. 거짓으로 전달함으로써 우리는 뷰를 루트 ViewGroup에 아직 첨부하고 싶지 않다고 말합니다. 우리는 그것이 다른 시점에 일어날 것이라고 말하고 있습니다. 이 예제에서 다른 시점은 단순히 인플레이션 바로 아래에 사용되는 addView () 메서드입니다.

false attachToRoot 예제에서는 View를 ViewGroup에 수동으로 추가 할 때 약간의 작업이 더 필요합니다.

attachToRoot false로 설정 (false는 필수)

onCreateView ()에서 Fragment 's View를 팽창시키고 반환 할 때 attachToRoot에 대해 false를 전달해야합니다. true로 전달하면 지정된 자식에 이미 부모가 있으므로 IllegalStateException이 발생합니다. 조각보기가 활동에서 다시 배치 될 위치를 지정해야합니다. FragmentManager를 추가, 제거 및 교체하는 것은 FragmentManager의 작업입니다.

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

활동에서 프래그먼트를 보유 할 root_viewGroup 컨테이너는 프래그먼트의 onCreateView ()에서 제공되는 ViewGroup 매개 변수입니다. 또한 LayoutInflater.inflate ()에 전달하는 ViewGroup입니다. 그러나 FragmentManager는 조각의 뷰를이 ViewGroup에 첨부하는 것을 처리합니다. 두 번 첨부하고 싶지 않습니다. attachToRoot를 false로 설정하십시오.

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

return view;
}

onCreateView ()에 Fragment의 부모 ViewGroup을 첨부하지 않으려는 이유는 무엇입니까? 왜 inflate () 메소드가 루트 ViewGroup을 요청합니까?

새로 팽창 된 View를 부모 ViewGroup에 즉시 추가하지 않더라도 새 View가 결국 첨부 될 때마다 크기와 위치를 결정하기 위해 여전히 부모의 LayoutParams를 사용해야합니다.

링크 : https://youtu.be/1Y0LlmTCOkM?t=409


0

이 주제에 대해 작업하는 동안 발생한 몇 가지 사항 만 공유하면

허용 된 답변 외에도 도움이 될 수있는 몇 가지 사항을 원합니다.

따라서 attachToRoot 를 true로 사용하면 반환 된보기는 ViewGroup 유형이었습니다. 즉 부모의 루트 ViewGroup은 inflate (layoutResource, ViewGroup, attachToRoot) 메서드에 대한 매개 변수 로 전달 되었습니다. false로 우리는 해당 layoutResource의 루트 ViewGroup 의 함수 리턴 타입을 얻는다 .

예를 들어 설명하겠습니다.

우리는 경우 의 LinearLayout 는 AS 루트 레이아웃을 한 후 우리는 추가 할 텍스트 뷰를 통해에 부풀려 기능.

그런 다음 attachToRoottrue 팽창 함수로 사용하면 LinearLayout 유형 의 보기 를 반환합니다.

사용에 동안 attachToRoot을 같이 거짓 부풀려 기능 반환 보기 형식의 텍스트 뷰를

이 발견이 도움이 되길 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.