Dan*_*son 12 android android-layout android-fragments android-view android-styles
我的应用程序有一个活动,每个部分都有不同的片段.我最近通过设置fitSystemWindows为状态栏半透明,将true其设置为应用程序的背景颜色.这适用于具有工具栏的片段,颜色匹配,如下所示:

然而,我的一个片段有一张照片和一个半透明的工具栏,所以我想让照片占据状态栏的空间,而不是背景颜色.
我认为,解决的办法是设置fitSystemWindows到false了只有片段,并手动添加填充到半透明的工具栏.以编程方式执行此操作似乎没有任何效果,我可能做错了什么?
这是我的主要活动布局:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_parent_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true">
<!-- Container for various fragment layouts, including nav drawer and tool bar -->
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
从我的片段的onCreateView()中:
RelativeLayout daddyLayout = (RelativeLayout)getActivity().findViewById(R.id.main_parent_view);
daddyLayout.setFitsSystemWindows(false);
daddyLayout.invalidate();
Run Code Online (Sandbox Code Playgroud)
这似乎没有效果,如下:

如果我在中设置fitSystemWindows为false main_parent_view,状态栏填充消失了它可以工作,但显然会影响每个片段.
azi*_*ian 12
那么,你是在那里左右为难的境地,因为一方面你需要申请插图(因为Toolbar要正确填充),而在另一方面,你应该不适用的插图(因为你想ImageView在状态栏绘制).
事实证明,该案例框架提供了一个很好的API:
ViewCompat.setOnApplyWindowInsetsListener(toolbar, (v, insets) -> {
((ViewGroup.MarginLayoutParams) v.getLayoutParams()).topMargin =
insets.getSystemWindowInsetTop();
return insets.consumeSystemWindowInsets();
});
Run Code Online (Sandbox Code Playgroud)
假设你的根布局有android:fitsSystemWindows="true",现在适当的插图将应用于你的Toolbar 唯一,而不是ImageView.
但是,有一个问题.
问题是您的根布局是RelativeLayout,它不会向子代发送有关insets的任何信息.它的兄弟布局(LinearLayout,FrameLayout)也没有.
如果您将根布局作为"物质化"布局(CoordinatorLayout,DrawerLayout)之一,则会向子节点分派这些窗口插件.
另一种选择是手动子类化RelativeLayout和分派WindowInsets给子项.
@TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
int childCount = getChildCount();
for (int index = 0; index < childCount; index++)
getChildAt(index).dispatchApplyWindowInsets(insets); // let children know about WindowInsets
return insets;
}
Run Code Online (Sandbox Code Playgroud)
您可以通过完全相同的要求查看此答案以获得详细说明.
我已经在4.4中解决了这个问题
if(test){
Log.d(TAG, "fit true ");
relativeLayout.setFitsSystemWindows(true);
relativeLayout.requestFitSystemWindows();
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}else {
Log.d(TAG, "fit false");
relativeLayout.setFitsSystemWindows(false);
relativeLayout.requestFitSystemWindows();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
Run Code Online (Sandbox Code Playgroud)
您可以使用 aCoordinatorLayout作为您的活动根视图,然后setFitsSystemWindows(boolean)就可以使用了。
这是因为,在本作解释的博客帖子,DrawerLayout并CoordinatorLayout都对如何不同的规则fitsSystemWindows适用于他们-他们都使用它来插页他们的孩子的意见,但也呼吁dispatchApplyWindowInsets()对每个孩子,让他们获得了fitsSystemWindows="true"财产。
这与布局的默认行为不同,例如FrameLayout当您使用时fitsSystemWindows="true"消耗所有插图,盲目应用填充而不通知任何子视图(这是博客文章的“深度优先”部分)。
看到同样的问题.通过从活动声明中删除fitSystemWindows并将paddingTop添加到片段,解决了我在我的应用程序中的问题.显然不是一个理想的解决方案,但似乎工作.
| 归档时间: |
|
| 查看次数: |
20426 次 |
| 最近记录: |