问题描述
活动布局具有DrawerLayout
,其中FrameLayout
作为Fragment
的内容,而LinearLayout
由抽屉打开和关闭.用于内容的片段具有带有fitsSystemWindows
标志的FrameLayout
和Toolbar
.
The activity layout has a DrawerLayout
with a FrameLayout
as content to Fragment
and a LinearLayout
to be opened and closed by drawer. The fragment used on content has a FrameLayout
with fitsSystemWindows
flag and a Toolbar
.
如果我在onCreate()
处插入片段,则所有片段均按预期发生,FrameLayout
从位置0开始,而Toolbar
从状态栏下方开始.但是在onCreate()
之外,相同的代码会失败,fitsSystemWindows
不能与FrameLayout
一起使用.
If I insert the fragment at onCreate()
all occurs as expected, the FrameLayout
starts on position 0 and the Toolbar
starts below the statusbar. But outside the onCreate()
the same code fails, the fitsSystemWindows
not works with FrameLayout
.
重要的一点是,我需要在Fragment
而不是Activity
上使用Toolbar
和fitsSystemWindows
标志.
An important point, I need the Toolbar
and fitsSystemWindows
flag on Fragment
and not on Activity
.
如何获得在onCreate()
时刻看到的相同行为?
How to get the same behavior seen at onCreate()
moment?
主要活动
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
window.setStatusBarColor(Color.TRANSPARENT);
}
setContentView(R.layout.activity);
findViewById(R.id.item).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Out of onCreate fails
replaceFragment();
}
});
// With onCreate all OK
replaceFragment();
}
private void replaceFragment() {
getSupportFragmentManager().beginTransaction()
.replace(R.id.content, new MainFragment())
.commit();
}
}
主要布局
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer"
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">
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<LinearLayout
android:layout_width="256dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#ff0000"
android:orientation="vertical"
tools:layout_gravity="">
<View
android:layout_width="match_parent"
android:layout_height="168dp"
android:layout_marginBottom="16dp"
android:background="#00ffff"/>
<TextView
android:id="@+id/item"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="#ff00ff"
android:gravity="center"
android:text="Click me"/>
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
片段
public class MainFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment, container, false);
}
}
片段布局:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00ff00"
android:fitsSystemWindows="true">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="#0000ff"/>
</FrameLayout>
</RelativeLayout>
示例
要打开的LinearLayout
为红色.带有fitsSystemWindows
标志的FrameLayout
为绿色,工具栏为蓝色,青色视图始终处于工作状态,它需要从y位置0开始.期望是第一次的绿色和蓝色,但是第二次是唯一的蓝色.
Example
The LinearLayout
to be opened is in red. The FrameLayout
with the fitsSystemWindows
flag is in green and the toolbar is in blue, the cyan view is working all the time, it need start at y position 0. The expected is Green and blue like the first time, but in the second time the blue is the unique viewed.
推荐答案
因此,问题是,当内容更改时,系统将不再将这些插图分配给视图层次结构.
So, the problem is, that the when the content is being changed, system will no longer dispatch those insets to the view hierarchy.
可以使用 ViewCompat.requestApplyInsets(View)
API.这将迫使系统再次调度WindowInsets
.
因此,在您的示例中执行此更改将导致预期的行为:
So, in your example performing this changes would result in expected behavior:
private void replaceFragment() {
getSupportFragmentManager().beginTransaction()
.replace(R.id.content, new MainFragment())
// NOTE, we are performing `commitNow()` instead of ordinary `commit()`,
// Because we want this commit to happen sychronously/immediately
.commitNow();
// Ask the framework to dispatch window insets once more to the root of your view hierarchy
ViewCompat.requestApplyInsets(findViewById(R.id.drawer));
}
这篇关于fitsSystemWindows上的Fragment,Activity和DrawerLayout组合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!