【问题标题】:Replace child Fragment dynamically from Child Fragment itself从子片段本身动态替换子片段
【发布时间】:2017-06-07 13:46:18
【问题描述】:

我正在使用一个自然包含片段的 Viewpager。 在其中一个片段中我有一个子片段(子片段) 每个子片段都包含一个按钮,该按钮调用以下内容来替换子片段本身

FragmentManager manager = getChildFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.containerProfileDetails, new ProfileDetailsAddressFragment());
transaction.commit();

只是为了让它更直观:

1) 是父片段

2) 是子片段。 我需要通过按下子片段本身内的按钮来替换子片段

┌--------┐
|   1    |
| ┌-----┐|
| | 2   ||
| |     ||
| └-----┘|
└--------┘

注意:我知道可以使用这种方法替换片段,但是,似乎无法对子片段执行此操作,因为它会引发以下错误。

java.lang.IllegalArgumentException: No view found for id 0x7f0f0104 (com.example.app:id/containerProfileDetails) for fragment ProfileDetailsAddressFragment

更新

父片段 XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context="com.example.app.fragments.ProfileDetailsFragment">

<TextView
    android:id="@+id/lbl_page"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:textSize="42sp"
    tools:text="2"
    android:visibility="gone"/>

<FrameLayout
    android:id="@+id/containerProfileDetails"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    ></FrameLayout>
</LinearLayout>

子片段 XML:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.app.fragments.ProfileDetailsUserFragment">

<TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="Fragment Profile User Details" />

<Button
    android:id="@+id/btnProfileDetailsUserNext"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|center"/>

</FrameLayout>

父片段 Java:

 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_profile_details, container, false);
    lblPage = (TextView) view.findViewById(R.id.lbl_page);

    FragmentManager manager = getChildFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.add(R.id.containerProfileDetails, new ProfileDetailsUserFragment());
    transaction.commit();
    return view;
}

子片段 Java:

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.fragment_profile_details_user, container, false);

    Button _btnProfileDetailsUserNext = (Button) v.findViewById(R.id.btnProfileDetailsUserNext);
    _btnProfileDetailsUserNext.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FragmentManager manager = getChildFragmentManager();
            FragmentTransaction transaction = manager.beginTransaction();
            transaction.replace(R.id.containerProfileDetails, new ProfileDetailsAddressFragment());
            transaction.commit();
        }
    });
    return v;
}

【问题讨论】:

  • 通常查看寻呼机没有容器,您将哪个 id 作为 R.id.containerProfileDetails 传递?
  • @AniruddhParihar 我使用transaction.add(R.id.containerProfileDetails, new firstchildfragment()); 在父片段中添加第一个子片段
  • 可以分享一下你的xml布局代码吗?
  • @AniruddhParihar 我假设发生了一些事情并且 R.id,containerProfileDetails 没有返回相同的 ID。
  • 是的,我也一样,但我必须先了解你的设计结构。

标签: android android-fragments


【解决方案1】:

将您的父片段和子片段代码替换为以下

Parent_Fragment.Java

 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_profile_details, container, false);
    lblPage = (TextView) view.findViewById(R.id.lbl_page);

    FragmentManager manager = getChildFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.add(R.id.containerProfileDetails, new ProfileDetailsUserFragment());
    transaction.commit();
    return view;
}

Child_Fragment.Java

 public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.fragment_profile_details_user, container, false);

    Button _btnProfileDetailsUserNext = (Button) v.findViewById(R.id.btnProfileDetailsUserNext);
    _btnProfileDetailsUserNext.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FragmentManager manager = getFragmentManager();
            FragmentTransaction transaction = manager.beginTransaction();
            transaction.replace(R.id.containerProfileDetails, new ProfileDetailsAddressFragment());
            transaction.commit();
        }
    });
    return v;
}

我没有测试代码,它可能会产生一些编译错误,但实现方式是正确的。

【讨论】:

  • 但是创建public static FragmentManager manager 是个好主意吗?创建回调并从父片段替换子片段不是更好吗?
  • 我认为 getFragmentManager() 也可以代替 Child_Fragment.java 的 getChildFragmentManager() 工作,如果它有效,那么我也会更新我的答案。
  • @Aniruddh Parihar 你是对的!我不明白为什么,但它的工作。你有这方面的参考吗?我将不胜感激更多细节。如果您更新帖子,我会将其标记为答案
  • 我已经更新了我的答案...您可以欣赏我的回答,就像投票和正确的标志一样...我会向您发送有关它的详细信息链接。
  • 这里有更多关于它的细节.....developer.android.com/reference/android/app/Fragment.html
【解决方案2】:

这将不起作用,因为在子片段中,片段事务正在寻找 id 为 R.id.containerProfileDetails 的容器。这个容器不在 Child Fragment 中,但在 Parent Fragment 中。

您需要做的是创建从子片段到父片段的回调。在子片段的 Onclick 中,调用父片段的回调,然后在父片段中,将子片段替换为所需的片段。

【讨论】:

  • 我不明白你在说什么。但我一直在寻找更好的方法。所以你说没有办法从内部替换子片段。因为没有办法在子片段本身中获取对父的 childefragmentmanager() 的引用?
  • 不,除非您要将父母 FragmentManager 保留在静态变量中,如下面的答案,但我个人更喜欢回调方法。
  • 他在 cmets 中的第二个建议确实有效。你觉得有什么缺点吗?或可能的问题?他还更新了答案。基本上使用普通的片段管理器可以替换片段。
  • 我没想到,它会起作用的。缺点是您在子片段的代码中更改了父片段的 UI。过多的这些结构可能会导致代码不清晰。你会理解它,因为你做了它,但其他需要处理你的代码的人也会理解它吗?
  • 是的,我理解你的观点。但许多人坚持减少回调。感谢您的回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-21
相关资源
最近更新 更多