XML 레이아웃에서 조각을 선언하는 경우 번들을 전달하려면 어떻게 해야 합니까?
파편으로 대체한 활동이 있어요활동은 활동이 어떤 데이터를 표시해야 하는지에 대한 추가 정보가 있는 의도를 취했습니다.
내 활동은 동일한 작업을 수행하는 조각 주위의 포장지에 불과하므로 태그와 함께 XML로 조각을 선언하면 번들을 어떻게 조각으로 가져올 수 있습니까?
FragmentTransaction을 사용하여 Fragment를 ViewGroup에 넣는다면 Fragment 생성기에서 이 정보를 전달할 기회가 있겠지만, Fragment가 XML에 정의되어 있는 상황이 궁금합니다.
내 활동은 동일한 작업을 수행하는 조각 주위의 포장지에 불과하므로 태그와 함께 XML로 조각을 선언하면 번들을 어떻게 조각으로 가져올 수 있습니까?
그럴수는 없어요.
ㅇ, ㅇㅇ로 .findFragmentById()
에에FragmentManager
인플레 이후의 프래그먼트를 검색한 다음 프래그먼트에 대한 메소드를 호출하여 데이터를 연관시킵니다.그것은 분명히 있을 수 없지만,setArguments()
를 구성 할 수 (, 의 으로 를 하도록 할 은 할 하도록 ( )onSaveInstanceState()
,setRetainInstance(true)
).
캡슐화된 방식은 아니지만, 상위 활동에서 번들을 "풀어"냈습니다.
Bundle bundle = getActivity().getIntent().getExtras();
번들을 전달할 수는 없지만 XML을 통해 매개 변수(또는 속성)를 전달할 수는 있습니다.
이 프로세스는 View 사용자 지정 특성을 정의하는 방법과 유사합니다.Android Studio(현재)를 제외하고는 프로세스에 도움이 되지 않습니다.
이것이 인수를 사용하는 당신의 프래그먼트라고 가정합니다. (코틀린을 사용하겠지만 자바에서도 완전히 작동합니다.)
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 voila, 조각에 XML 속성 포함 :)
제한 사항:
- Android Studio는 레이아웃 XML에서 이러한 인수를 자동으로 완료하지 않습니다.
- 당신은 통과할 수 없습니다.
Parcelable
로 할 수 합니다.
또 다른 옵션은 XML에 fragment를 선언하지 않는 것입니다. 정확히 당신이 원하는 것이 아니라는 것을 압니다.그러나 보기에서 다음과 같이 간단한 레이아웃을 선언할 수 있습니다.
<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();
그 조각에서,
if (getArguments() != null) {
int role = getArguments().getInt(Global.INTENT_INT_ROLE); }
이 접근법은 xml에 선언하는 것만큼 깨끗하고 간단하지는 않지만 프래그먼트에 대한 통제력이 훨씬 더 높아지기 때문에 이동했습니다.
너무 늦은 답변인건 알지만 누군가가 필요할거 같아요 :)
override onAttachFragment()
@Override
public void onAttachFragment(Fragment fragment)
{
super.onAttachFragment(fragment);
if (fragment.getId() == R.id.frgBlank)
{
Bundle b = new Bundle();
b.putString("msg", "Message");
fragment.setArguments(b);
}
}
CreateView 메서드의 조각에 표시됩니다.
Bundle b = getArguments();
if (b != null)
{
Toast.makeText(getBaseContext(), b.getString("msg"), Toast.LENGTH_SHORT).show();
}
제가 볼 수 있는 유일한 해결책은 인수를 데이터 교환 채널로 사용하지 않는 것입니다.대신 다른 곳에서 필요한 정보를 얻기 위해 조각을 만듭니다.다시 전화를 걸어 적절한 활동을 얻고 임시 저장 메모리, 싱글톤 개체 등을 확인합니다.
도움이 될 수 있는 또 다른 해결책은 Otto와 같이 Mediator 디자인 패턴을 통해 관련 없는 개체가 메시지를 교환할 수 있는 프레임워크를 사용하는 것입니다.
이 방법은 저에게 효과가 있었습니다.
Anywhere에서 온 번들을 전달하지 않고 대신 조각 자체에서 onAttach 메서드에서 인수를 설정할 수 있습니다.
프래그먼트의 라이프사이클 메소드 나중에 번들 인수를 사용할 수 있습니다.
override fun onAttach(context: Context) {
super.onAttach(context)
if(arguments == null){
val bundle = Bundle()
bundle.putString("mykey", "myvalue")
arguments = bundle
}
}
누구나 사용 가능한 장소에서 값을 직접 사용할 수 있는데 왜 프래그먼트에 인수를 설정해야 하는지 질문할 수 있습니다.맞는 말이지만, 이 방법은 다른 클래스에 이러한 주장을 전달할 때도 사용할 수 있습니다. 예를 들어 어떤 보기 모델이든 말이죠.
예를들면
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
/*
Here I am passing these arguments to a viewmodel
*/
viewModel.prepareData(arguments)
--------
--------
--------
}
감사해요.
Androidx.fragment 모듈의 v1.3.0(2021년 2월) 이후로, 그들은 더 이상 사용하지 않습니다.onAttachFragment()
FragmentManager에 첨부된 FragmentOnAttachListener를 사용하는 것을 선호하여 콜백합니다.그래서 너의 안에FragmentActivity
의onCreate
, 당신은 다음과 같은 것을 할 수 있습니다.
getSupportFragmentManager().addFragmentOnAttachListener((fragmentManager, fragment) -> {
if (fragment instanceof MyFragment) {
Bundle args = getIntent().getExtras();
fragment.setArguments(args);
}
}
다음에 불이 붙습니다.setContentView()
사용하는 경우<fragment>
당신의 XML에서, 그러나 만약 당신이 a를 사용했다면 나중에 발생합니다.<FragmentContainerView>
.
구성 변경으로 인해 기존의 조각이 내부에 다시 부착될 수 있으므로 주의해야 합니다.super.onCreate
, 따라서 이 시점 전에 청취자를 추가할 필요가 있었습니다. (그렇기는 하지만 통과를 위해서는 필요하지 않습니다.Bundle
args, 그렇지 않으면 SaveInstanceState()에서 먼저 사용을 시도해야 합니다.)
덧붙여서 "onAttach"를 듣는 것도 필요한 경우 프래그먼트 보기 라이프사이클의 관찰자를 추가할 수 있는 편리한 장소가 될 수 있습니다. 프래그먼트 보기가 인스턴스화된 후 액티비티에서 작업을 수행해야 하는 경우 예를 들어 다음을 추가합니다.
LiveData<LifecycleOwner> liveData = fragment.getViewLifecycleOwnerLiveData();
// Let this observer be constrained to the fragment's lifecycle.
liveData.observe(fragment, new Observer<LifecycleOwner>() {
@Override
public void onChanged(LifecycleOwner lifecycleOwner) {
// ...do work...
// If you don't need to listen anymore, can clean ourselves up early.
liveData.removeObserver(this);
}
});
또는 Activity에서 Fragment의 보기 라이프사이클을 관찰하는 대신(ActivityCreated()) Fragment에서 Activity의 Lifecycle을 관찰하는 대신, Fragment에서 Activity의 Lifecycle을 들을 수도 있습니다!첨부(context) 콜백에 있는 Fragments에서 Create(@NonNull LifecycleOwner)에 구현하는 자신의 관찰자를 추가합니다.re: onActivityCreated가 더 이상 사용되지 않습니다. LifecycleOver를 제대로 사용하는 방법은 무엇입니까?
언급URL : https://stackoverflow.com/questions/13034746/if-i-declare-a-fragment-in-an-xml-layout-how-do-i-pass-it-a-bundle
'programing' 카테고리의 다른 글
리스트 스타일 이미지 위치를 조정하시겠습니까? (0) | 2023.09.13 |
---|---|
IE9에서 이진 데이터를 읽는 방법? (0) | 2023.09.13 |
유연한 배열 부재로 구조를 초기화하는 방법 (0) | 2023.09.13 |
펫클리닉보다 더 큰 오픈소스 스프링 샘플 프로젝트가 있습니까? (0) | 2023.09.13 |
Android 응용 프로그램에서 텍스트 뷰의 첫 글자를 대문자로 쓰는 방법 (0) | 2023.09.13 |