Development Tip

XML 레이아웃에서 조각을 선언하는 경우 번들을 어떻게 전달합니까?

yourdevel 2020. 12. 4. 21:01
반응형

XML 레이아웃에서 조각을 선언하는 경우 번들을 어떻게 전달합니까?


조각으로 대체 한 활동이 있습니다. 활동은 활동이 표시해야하는 데이터에 대한 추가 정보가있는 인 텐트를 사용했습니다.

이제 내 활동이 동일한 작업을 수행하는 Fragment를 둘러싼 래퍼 일 뿐이므로 태그를 사용하여 XML로 조각을 선언하면 해당 번들을 Fragment로 가져 오려면 어떻게해야합니까?

FragmentTransaction을 사용하여 Fragment를 ViewGroup에 넣으면이 정보를 Fragment 생성자에 전달할 수 있지만 XML로 조각이 정의 된 상황이 궁금합니다.


이제 내 활동이 동일한 작업을 수행하는 Fragment를 둘러싼 래퍼 일 뿐이므로 태그를 사용하여 XML로 조각을 선언하면 해당 번들을 Fragment로 가져 오려면 어떻게해야합니까?

당신은 할 수 없습니다.

그러나를 호출 findFragmentById()하여 FragmentManager인플레이션 후 조각을 검색 한 다음 조각에서 일부 메서드를 호출하여 데이터를 연결할 수 있습니다. 분명히이 될 수는 없지만 setArguments(), 당신의 조각은 다른 방법에 의한 구성 변경 과거 데이터에 (자신을 개최 준비 수 onSaveInstanceState(), setRetainInstance(true)등).


캡슐화 된 방식은 아니지만 부모 활동에서 번들을 "끌어 당기"는 결과를 얻었습니다.

Bundle bundle = getActivity().getIntent().getExtras();

또 다른 옵션은 XML에서 조각을 선언하지 않는 것입니다. 나는 그것이 당신이 원하는 것이 정확히 아니라는 것을 압니다. 그러나 다음과 같이보기에서 간단한 레이아웃을 선언 할 수 있습니다.

    <LinearLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" />

그런 다음 Activity클래스 에서 프로그래밍 방식으로 조각으로 레이아웃을 확장합니다. 이렇게하면 args를 사용하여 매개 변수를 전달할 수 있습니다.

 FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    MyFragment fragment = MyFragment.newInstance();
    Bundle args = new Bundle();
    args.putInt(Global.INTENT_INT_ROLE, 1);
    fragment.setArguments(args);
    fragmentTransaction.add(R.id.fragment_container, fragment, "MyActivity");
    fragmentTransaction.commit();

이 접근 방식은 xml에서 선언하는 것만 큼 깨끗하고 간단하지는 않지만 조각에 대해 훨씬 더 많은 제어를 제공하므로 이동했습니다.


Bundle은 전달할 수 없지만 XML을 통해 매개 변수 (또는 속성)를 조각으로 전달할 수 있습니다.

이 프로세스는 사용자 정의 속성보기를 정의하는 방법 과 유사 합니다 . AndroidStudio (현재)를 제외하고는 프로세스를 지원하지 않습니다.

이것이 인수를 사용하는 조각이라고 가정합니다 (kotlin을 사용하지만 Java에서도 완전히 작동합니다).

class MyFragment: Fragment() {

    // your fragment parameter, a string
    private var screenName: String? = null

    override fun onAttach(context: Context?) {
        super.onAttach(context)
        if (screenName == null) {
            screenName = arguments?.getString("screen_name")
        }
    }
}

그리고 다음과 같이하고 싶습니다.

<fragment
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/myFragment"
    android:name="com.example.MyFragment"
    app:screen_name="@string/screen_a"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

참고 app:screen_name="@string/screen_a"

작동하게하려면 값 파일에 다음을 추가하십시오 ( fragment_attrs.xml또는 원하는 이름을 선택하십시오).

<!-- define your attribute name and type -->
<attr name="screen_name" format="string|reference"/>

<!-- define a bunch of constants you wanna use -->
<string name="screen_a" translatable="false">ScreenA</string>
<string name="screen_b" translatable="false">ScreeenB</string>

<!-- now define which arguments your fragment is gonna have (can be more then one) -->
<!-- the convention is "FragmentClassName_MembersInjector" -->
<declare-styleable name="MyFragment_MembersInjector">
    <attr name="screen_name"/>
</declare-styleable>

거의 완료되었습니다. 조각에서 읽기만하면되므로 메서드를 추가하세요.

override fun onInflate(context: Context?, attrs: AttributeSet?, savedInstanceState: Bundle?) {
    super.onInflate(context, attrs, savedInstanceState)
    if (context != null && attrs != null && screenName == null) {
        val ta = context.obtainStyledAttributes(attrs, R.styleable.MyFragment_MembersInjector)
        if (ta.hasValue(R.styleable.MyFragment_MembersInjector_screen_name)) {
            screenName = ta.getString(R.styleable.MyFragment_MembersInjector_screen_name)
        }
        ta.recycle()
    }
}

et voilá, 조각의 XML 속성 :)

제한 사항 :

  • Android Studio (as of now) do not autocomplete such arguments in the layout XML
  • You can't pass Parcelable but only what can be defined as Android Attributes

The only solution I see is to not use the arguments as data exchange channel. Instead, make your fragment to obtain the necessary information from elsewhere. Call back to get the proper activity, consult a temporary storage memory, a Singleton object, etc..

Another solution that can be helpful is to employ frameworks that allow unrelated objects to exchange messages via Mediator design pattern, as Otto.

참고URL : https://stackoverflow.com/questions/13034746/if-i-declare-a-fragment-in-an-xml-layout-how-do-i-pass-it-a-bundle

반응형