Android片段被另一个片段覆盖

huangapple go评论73阅读模式
英文:

Android fragment get covered by another fragment

问题

使用事务来尝试在我的Activity中更改片段,但是先前的片段保持在原位置,而新的片段覆盖它:

这是我更改片段的方式:

WorkoutDetailFragment details = new WorkoutDetailFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
details.setWorkout(id);
ft.replace(R.id.stopwatch_container, details);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(null);
ft.commit();

如何防止这种情况发生?

更新:以下是activity_main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:padding="16dp"
    tools:context=".StopwatchFragment" >

    <fragment
        android:id="@+id/fragment2"
        android:name="com.example.workout.WorkoutListFragment"
        android:layout_width="160dp"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <FrameLayout
        android:id="@+id/stopwatch_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toEndOf="@+id/fragment2"
        app:layout_constraintTop_toTopOf="parent">

        <fragment
            android:id="@+id/fragment3"
            android:name="com.example.workout.WorkoutDetailFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

更新2:我已经找到了解决方案。我只是将片段视图嵌套在了FrameLayout中。而不是使用片段事务,我在代码中直接将片段添加到了FrameLayout中。

英文:

Using transactions I try to change a fragment in my Activity, but the previous fragment stays as where it was and a new one covers it:
Android片段被另一个片段覆盖

This is how I change the fragments:

WorkoutDetailFragment details = new WorkoutDetailFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
details.setWorkout(id);
ft.replace(R.id.stopwatch_container, details);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(null);
ft.commit();

How can I prevent it?

UPD: Here's acivity_main.xml file:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:orientation=&quot;horizontal&quot;
    android:padding=&quot;16dp&quot;
    tools:context=&quot;.StopwatchFragment&quot; &gt;

    &lt;fragment
        android:id=&quot;@+id/fragment2&quot;
        android:name=&quot;com.example.workout.WorkoutListFragment&quot;
        android:layout_width=&quot;160dp&quot;
        android:layout_height=&quot;wrap_content&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot; /&gt;

    &lt;FrameLayout
        android:id=&quot;@+id/stopwatch_container&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        app:layout_constraintStart_toEndOf=&quot;@+id/fragment2&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;&gt;

        &lt;fragment
            android:id=&quot;@+id/fragment3&quot;
            android:name=&quot;com.example.workout.WorkoutDetailFragment&quot;
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;match_parent&quot; /&gt;
    &lt;/FrameLayout&gt;
&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;

UPD2: I've found the solution. I just kept the fragment view nested in a frame layout. Instead, having used fragment transactions I added the fragment directly into frame layout in code.

答案1

得分: 2

以下是翻译的内容:

getSupportFragmentManager()

可以从Activity中调用,或者仅使用Activity的引用来调用,例如 requireActivity().getSupportFragmentManager()

  • 这将返回用于与Activity关联的Fragment的FragmentManager。

getChildFragmentManager()

如果你在Activity中:你不能直接从Activity中调用它,甚至不能使用requireActivity()
如果你在Fragment中:你可以调用它,因为它要求你在Fragment中。当你在第一个Fragment中时,现在它变成了父Fragment。现在父Fragment可以拥有子Fragment,但Activity不能拥有子Fragment。通常在使用ViewPagers、嵌套ViewPager或嵌套Fragment时会看到这些情况。

  • 这返回一个私有的FragmentManager,用于放置和管理此Fragment内的Fragments。

我认为我们不需要写关于getParentFragmentManager()

让我从Activity容器开始。

activity_main

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

MainActivity

如果需要,请添加过渡或后退堆栈。

我正在调用getSupportFragmentManager(),因为我们在Activity中。如果在Fragment中调用,则会有所不同。

WorkoutDetailFragment fragment = new WorkoutDetailFragment();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.stopwatch_container, fragment);
transaction.commit();

现在你正试图从WorkoutDetailFragment中调用另一个Fragment,让我们调用HomeFragment

HomeFragment fragment = HomeFragment.newInstance();
FragmentManager manager = requireActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.stopwatch_container, fragment);
transaction.addToBackStack(null);
transaction.commit();

要从现有的Fragment中调用一个Fragment,请获取对父Activity的引用requireActivity(),然后在其上调用getSupportFragmentManager()

英文:

How fragment terminology works:

getSupportFragmentManager()

This can be called from Activity or only using the reference of activity like
requireActivity().getSupportFragmentManager()

  • This returns the FragmentManager for interacting with fragments associated with the activity.

getChildFragmentManager()

If you are in Activity : you cannot call this directly from activity or even using requireActivity()
If you are in Fragment : you can call this because it requires you to be in fragment. When you are in first fragment, now this becomes parent fragment. Now the parent fragment can have child fragments but activity cannot have child frgament.
These are usually seen when using ViewPagers or Nested ViewPager or in nested fragments.

  • This returns a private FragmentManager for placing and managing Fragments inside of this Fragment.

I think we need not to write about getParentFragmentManager().

Let me start from activity container then.

activity_main

&lt;FrameLayout
    android:id=&quot;@+id/stopwatch_container&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot; &gt;

&lt;/FrameLayout&gt;

MainActivity

Please add transitions or back stack if needed.

I am calling getSupportFragmentManager() because we are in activity. If calling inside a fragment then differs.

WorkoutDetailFragment fragment = new WorkoutDetailFragment();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.stopwatch_container, fragment);
transaction.commit();

Now you are trying to call another fragment from WorkoutDetailFragment let's call HomeFragment

HomeFragment fragment = new HomeFragment.newInstance();
FragmentManager manager = requireActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.stopwatch_container, fragment);
transaction.addToBackStack(null);
transaction.commit();

To call a fragment from existing fragment get reference to parent activity requireActivity() and call getSupportFragmentManager() upon it.

huangapple
  • 本文由 发表于 2020年9月21日 20:10:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/63992032.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定