片段是透明的并显示在下面的活动中。

40
我的Android应用启动进入BeginActivity,它是SherlockFragmentActivity的子类,并使用以下代码展示第一个视图:
@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getSupportFragmentManager().findFragmentById(android.R.id.content) == null) {
            Fragment f = LoginFragment.newInstance();

            getSupportFragmentManager()
                    .beginTransaction()
                    .add(android.R.id.content, f, "loginfragment")
                    .attach(f)
                    .commit();
        }
}

LoginFragment 显示的视图如下:

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

        // Get pointers to text views
        usernameField = (EditText) v.findViewById(R.id.usernameLog);
        passwordField = (EditText) v.findViewById(R.id.passwordLog);
        progressBar = (ProgressBar) v.findViewById(R.id.progressBarLog);
        // Set button click listeners for both buttons
        Button b = (Button) v.findViewById(R.id.loginButton);
        b.setOnClickListener(this);

        return v;
    }

点击登录后,我会显示以下这样的列表视图:
BeginActivity top = (BeginActivity) getActivity();
Fragment f = OfferListFragment.newInstance();
        top.getSupportFragmentManager()
                .beginTransaction()
                .add(android.R.id.content, f, "offerList")
                .addToBackStack(f.getClass().getSimpleName())
                .commit();

最后,OfferListFragment通过以下方式显示其视图:

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

        return v;
    }

现在我遇到的问题是,最终的OfferListFragment似乎是透明的,我可以看到它下面的登录屏幕。我正在使用具有黑色背景的Theme.Sherlock主题。我应该手动设置视图的背景为黑色吗?还是主题中的黑色可以由系统上的用户自定义?(我不是Android用户。)

谢谢。


你是否想要在显示OfferListFragment时,彻底将LoginFragmentBeginActivity中移除? - Mehul Joisar
不需要特别处理。用户应该能够点击“返回”按钮回到之前的页面。 - Darren
好的兄弟。我不确定,但是你尝试使用“FragmentTransaction”类的replace(int, android.app.Fragment)方法了吗? - Mehul Joisar
不,我会尝试一下的。但是点击“返回”按钮会如何运作呢? - Darren
1
在使用replace方法之后,您需要使用FragmentTransaction类的addToBackStack方法,最后在结尾处使用commit方法。 - Mehul Joisar
5个回答

87

依据我个人意见,我不同意这个答案。

你可能想要替换你的片段,或者你可能想要添加它。

例如,假设你在一个由网络请求检索到的列表片段中,如果你用detailFragment替换该片段,并将其添加到backStack中。

当你返回时,你的片段将重新进行网络查询,当然你可以缓存它,但为什么呢?它是回到了先前的状态,所以使用add方法时,最后一个片段将完全处于相同的状态,没有任何代码。

片段默认是透明的背景,因为它们可以被用来只绘制屏幕的一小部分,但如果你的片段是match_parent,请将其背景设置为颜色并继续在fragmentTransaction上使用add。

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scrollView1"
android:background="@android:color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content" >

那将成为片段布局XML上的根元素,可以是linear等等,

交易代码是:

YourFragment detail = YourFragment.newInstance(Id);
ft.add(R.id.contentHolder, detail);
ft.addToBackStack(TAG);
ft.commit();
希望这能帮助那些想知道如何看到实心背景而不改变通常并不是最好的情况下的添加或替换。 致敬。

3
确实,这应该是正确的答案,因为前面的答案需要明确使用“替换”函数,而不能保持实现独立。 - HBN
32
在片段视图的顶层元素上设置android:background="?android:attr/windowBackground"可能会更有帮助。这样可以使用默认背景,而不是一些可能不适合您主题的白色背景。 - Paul Woitaschek
11
“Fragments are transparent backgrounded by default” 的意思是“片段默认具有透明的背景”。这一点对我来说已足够。虽然我并不认为文档中提到了这一点。 - George Daramouskas
3
在根元素上添加背景将会触发一个 lint 警告:“可能出现过度绘制:根元素绘制了背景”。在这种情况下可以忽略这个警告吗? - Much Overflow
2
内存使用情况怎么样?! - codename_47
显示剩余7条评论

41

尝试使用FragmentTransaction类来replace片段而不仅仅是添加。

说明:

每个事务都是一组您想要同时执行的更改。您可以使用add()remove()replace()等方法为给定的事务设置要执行的所有更改。然后,要将事务应用于活动,您必须调用commit()

但在调用commit()之前,您可能希望调用addToBackStack(),以便将事务添加到片段事务的后退栈中。此后退栈由活动管理,并允许用户通过按返回按钮返回到上一个片段状态。

例如,以下是如何替换一个片段并在后退栈中保留先前状态的示例:

示例:

// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();

参考资料:请查看管理Fragment

希望对你有所帮助!


1
你太棒了。这解决了我许多问题,包括这个:http://stackoverflow.com/questions/16594352/listener-for-when-a-fragment-becomes-visible。谢谢你。 - Darren
1
并不总是最好的解决方案只是替换一个片段,大多数人需要添加回退堆栈实现,我们可以讨论一下 :) 请查看我的答案。 - Goofyahead
1
@Goofyahead:如果你看一下Darren在问题中提供的代码,他已经使用了添加片段而不是替换的机制。但问题在于,他能够看到一次登录后就没有意义的“登录片段”。因此,我建议使用OfferListFragment片段的替换来摆脱它。 - Mehul Joisar

6

我使用了许多技巧,但都没有什么效果。最终通过向容器或片段布局添加背景来解决了问题,如下所示:

android:background="@android:color/white"    

你只需要将它添加到布局或片段的容器视图中 希望这有所帮助

仍然不起作用,仍然透明。 - m0skit0
1
它应该可以工作,如果它不能工作,那么你的代码中可能有其他问题,或者你没有按照所需/正确的方式使用上述代码。 - Sultan Ali

1

好的,仅仅给片段设置背景并不总是足够的。例如,如果您的背景活动或片段包含按钮,则我们应该为FragmentLayout设置高度,以便我们的片段出现在其他元素之上。类似这样:

    <FrameLayout
    android:elevation="5dp"
    ... />

然后在我们的片段布局中,我们应该设置背景并将可点击属性设置为true,以防止在背景活动或片段中工作的按钮。就像这样:

<androidx.constraintlayout.widget.ConstraintLayout
...
android:background="@android:color/darker_gray"
android:clickable="true">

0
没有人提到,如果你给你的Fragment添加了一个背景色,但仍然出现透明背景,你需要检查一下你的XML中FrameLayout是否是最后一个视图。
因为在Android中,z-index是通过XML位置计算的,层级结构中最低的视图具有最高的z-index。
例如,我最近通过将FrameLayout移动到此处来解决了这个问题:
<androidx.coordinatorlayout.widget.CoordinatorLayout
  ...>

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

    <RelativeLayout
      ...>
    </RelativeLayout>

    <RelativeLayout
      ...>
    </RelativeLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

到这里:

<androidx.coordinatorlayout.widget.CoordinatorLayout
  ...>

    <RelativeLayout
      ...>
    </RelativeLayout>

    <RelativeLayout
      ...>
    </RelativeLayout>

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

</androidx.coordinatorlayout.widget.CoordinatorLayout>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接