Android 底页景观问题
在横向模式下显示底部工作表对话框时出现错误行为。该问题发生在24.+版本的设计库中。 根据下图,仅在横向中,底部板材未正确显示。我正在使用BottomSheetDialog类,我正在遵循本教程:,在我发布的应用程序中,问题也会出现 我测试了25.+版本,但问题没有解决 横向24、25+库中的错误Android 底页景观问题,android,android-support-library,android-design-library,Android,Android Support Library,Android Design Library,在横向模式下显示底部工作表对话框时出现错误行为。该问题发生在24.+版本的设计库中。 根据下图,仅在横向中,底部板材未正确显示。我正在使用BottomSheetDialog类,我正在遵循本教程:,在我发布的应用程序中,问题也会出现 我测试了25.+版本,但问题没有解决 横向24、25+库中的错误 public class MainActivity extends AppCompatActivity { CoordinatorLayout coordinatorLayout; private Bo
public class MainActivity extends AppCompatActivity {
CoordinatorLayout coordinatorLayout;
private BottomSheetBehavior<View> mBottomSheetBehavior;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.main_content);
textView = (TextView) findViewById(R.id.textView);
View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);
//For your bottom sheet to be displayable, you need to create a BottomSheetBehavior.
//This is created by getting a reference to the container view and calling BottomSheetBehavior.from() on that container.
mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
switch (newState) {
case BottomSheetBehavior.STATE_DRAGGING:
break;
case BottomSheetBehavior.STATE_COLLAPSED:
mBottomSheetBehavior.setPeekHeight(0);
break;
case BottomSheetBehavior.STATE_EXPANDED:
break;
case BottomSheetBehavior.STATE_HIDDEN:
break;
case BottomSheetBehavior.STATE_SETTLING:
break;
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
/**
* For persistent bottom sheet to work, your layout should contain a coordinator layout,
* and then in any child view of your coordinator layout, you can make it as a persistent bottom sheet
* by adding a custom property app:layout_behavior and use behavior_peekHeight to define how much
* of the Bottom Sheet you want visible.
*/
textView.setText(R.string.dynamic_persistent_txt);
mBottomSheetBehavior.setPeekHeight(300);
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
break;
case R.id.button2:
/**
* You can also display a Dialog in place of a View in the bottom sheet.
* To do this, get the view from getLayoutInflater and pass it setContentView of the Dialog.
*/
View view = getLayoutInflater().inflate(R.layout.bottom_sheet_layout, null);
TextView textView = (TextView) view.findViewById(R.id.textView);
textView.setText(R.string.dialog_modal_txt);
BottomSheetDialog dialog = new BottomSheetDialog(this);
dialog.setContentView(view);
dialog.show();
break;
case R.id.button3:
/**
* You can also display a Fragment in place of a View in the bottom sheet.
* To do this, you class that extends BottomSheetDialogFragment.
*/
BottomSheetDialogFragment bottomSheetDialogFragment = new BottomSheetDialogFragmentExample();
bottomSheetDialogFragment.show(getSupportFragmentManager(), bottomSheetDialogFragment.getTag());
break;
}
}
23.+库中的相同示例
public class MainActivity extends AppCompatActivity {
CoordinatorLayout coordinatorLayout;
private BottomSheetBehavior<View> mBottomSheetBehavior;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.main_content);
textView = (TextView) findViewById(R.id.textView);
View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);
//For your bottom sheet to be displayable, you need to create a BottomSheetBehavior.
//This is created by getting a reference to the container view and calling BottomSheetBehavior.from() on that container.
mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
switch (newState) {
case BottomSheetBehavior.STATE_DRAGGING:
break;
case BottomSheetBehavior.STATE_COLLAPSED:
mBottomSheetBehavior.setPeekHeight(0);
break;
case BottomSheetBehavior.STATE_EXPANDED:
break;
case BottomSheetBehavior.STATE_HIDDEN:
break;
case BottomSheetBehavior.STATE_SETTLING:
break;
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
/**
* For persistent bottom sheet to work, your layout should contain a coordinator layout,
* and then in any child view of your coordinator layout, you can make it as a persistent bottom sheet
* by adding a custom property app:layout_behavior and use behavior_peekHeight to define how much
* of the Bottom Sheet you want visible.
*/
textView.setText(R.string.dynamic_persistent_txt);
mBottomSheetBehavior.setPeekHeight(300);
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
break;
case R.id.button2:
/**
* You can also display a Dialog in place of a View in the bottom sheet.
* To do this, get the view from getLayoutInflater and pass it setContentView of the Dialog.
*/
View view = getLayoutInflater().inflate(R.layout.bottom_sheet_layout, null);
TextView textView = (TextView) view.findViewById(R.id.textView);
textView.setText(R.string.dialog_modal_txt);
BottomSheetDialog dialog = new BottomSheetDialog(this);
dialog.setContentView(view);
dialog.show();
break;
case R.id.button3:
/**
* You can also display a Fragment in place of a View in the bottom sheet.
* To do this, you class that extends BottomSheetDialogFragment.
*/
BottomSheetDialogFragment bottomSheetDialogFragment = new BottomSheetDialogFragmentExample();
bottomSheetDialogFragment.show(getSupportFragmentManager(), bottomSheetDialogFragment.getTag());
break;
}
}
主要活动
public class MainActivity extends AppCompatActivity {
CoordinatorLayout coordinatorLayout;
private BottomSheetBehavior<View> mBottomSheetBehavior;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.main_content);
textView = (TextView) findViewById(R.id.textView);
View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);
//For your bottom sheet to be displayable, you need to create a BottomSheetBehavior.
//This is created by getting a reference to the container view and calling BottomSheetBehavior.from() on that container.
mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
switch (newState) {
case BottomSheetBehavior.STATE_DRAGGING:
break;
case BottomSheetBehavior.STATE_COLLAPSED:
mBottomSheetBehavior.setPeekHeight(0);
break;
case BottomSheetBehavior.STATE_EXPANDED:
break;
case BottomSheetBehavior.STATE_HIDDEN:
break;
case BottomSheetBehavior.STATE_SETTLING:
break;
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
/**
* For persistent bottom sheet to work, your layout should contain a coordinator layout,
* and then in any child view of your coordinator layout, you can make it as a persistent bottom sheet
* by adding a custom property app:layout_behavior and use behavior_peekHeight to define how much
* of the Bottom Sheet you want visible.
*/
textView.setText(R.string.dynamic_persistent_txt);
mBottomSheetBehavior.setPeekHeight(300);
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
break;
case R.id.button2:
/**
* You can also display a Dialog in place of a View in the bottom sheet.
* To do this, get the view from getLayoutInflater and pass it setContentView of the Dialog.
*/
View view = getLayoutInflater().inflate(R.layout.bottom_sheet_layout, null);
TextView textView = (TextView) view.findViewById(R.id.textView);
textView.setText(R.string.dialog_modal_txt);
BottomSheetDialog dialog = new BottomSheetDialog(this);
dialog.setContentView(view);
dialog.show();
break;
case R.id.button3:
/**
* You can also display a Fragment in place of a View in the bottom sheet.
* To do this, you class that extends BottomSheetDialogFragment.
*/
BottomSheetDialogFragment bottomSheetDialogFragment = new BottomSheetDialogFragmentExample();
bottomSheetDialogFragment.show(getSupportFragmentManager(), bottomSheetDialogFragment.getTag());
break;
}
}
public类MainActivity扩展了AppCompatActivity{
协调布局协调布局;
私人银行行为mBottomSheetBehavior;
私有文本视图文本视图;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinatorLayout=(coordinatorLayout)findViewById(R.id.main_内容);
textView=(textView)findViewById(R.id.textView);
视图底部工作表=坐标布局。findViewById(R.id.底部工作表);
//要使底部工作表可显示,需要创建底部工作表行为。
//这是通过获取对容器视图的引用并调用该容器上的BottomSheetBehavior.from()创建的。
mBottomSheetBehavior=底部板材行为。从(底部板材);
mBottomSheetBehavior.setBottomSheetCallback(新的BottomSheetBehavior.BottomSheetCallback(){
@凌驾
公共void onStateChanged(@NonNull View bottomSheet,int newState){
交换机(新闻状态){
case BottomSheetBehavior.STATE_拖动:
打破
case BottomSheetBehavior.STATE_已崩溃:
mBottomSheetBehavior.setpeek高度(0);
打破
case BottomSheetBehavior.STATE_已展开:
打破
case BottomSheetBehavior.STATE_隐藏:
打破
case.STATE_结算:
打破
}
}
@凌驾
幻灯片上的公共空白(@NonNull视图底页,浮动幻灯片偏移){
}
});
}
公共void onClick(视图v){
开关(v.getId()){
案例R.id.button1:
/**
*要使持久的底部工作表正常工作,您的布局应包含一个协调器布局,
*然后在协调器布局的任何子视图中,都可以将其作为持久的底部工作表
*通过添加自定义属性app:layout_behavior并使用behavior_peek height定义值
*要显示的底部图纸的。
*/
textView.setText(R.string.dynamic\u persistent\u txt);
mBottomSheetBehavior.setpeek高度(300);
mBottomSheetBehavior.setState(底部表单行为.STATE_扩展);
打破
案例R.id.按钮2:
/**
*也可以在底部图纸中显示对话框来代替视图。
*为此,从GetLayoutFlater获取视图,并将其传递给对话框的setContentView。
*/
视图=GetLayoutFlater()。充气(R.layout.bottom\u sheet\u layout,null);
TextView TextView=(TextView)view.findViewById(R.id.TextView);
textView.setText(R.string.dialog\u modal\u txt);
BottomSheetDialog=新建BottomSheetDialog(此);
setContentView(视图);
dialog.show();
打破
外壳R.id.按钮3:
/**
*也可以在底部图纸中显示片段以代替视图。
*要做到这一点,您需要扩展BottomSheetDialogFragment的类。
*/
BottomSheetDialogFragment BottomSheetDialogFragment=新的BottomSheetDialogFragmentExample();
show(getSupportFragmentManager(),bottomSheetDialogFragment.getTag());
打破
}
}
活动\u main.xml
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="24dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Dynamic BottomSheet" />
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="BottomSheetDialog" />
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="BottomSheetDialogFragment" />
</LinearLayout>
<LinearLayout
android:id="@+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="4dp"
android:minHeight="120dp"
android:orientation="vertical"
android:padding="@dimen/activity_vertical_margin"
app:behavior_peekHeight="120dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<include layout="@layout/bottom_sheet_layout" />
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/CreamyGreen"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/static_persistent_txt"
android:padding="16dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@android:color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:text="@string/ipsum"
android:textColor="@android:color/white"
android:textSize="16sp" />
</LinearLayout>
底部工作表布局.xml
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="24dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Dynamic BottomSheet" />
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="BottomSheetDialog" />
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="BottomSheetDialogFragment" />
</LinearLayout>
<LinearLayout
android:id="@+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="4dp"
android:minHeight="120dp"
android:orientation="vertical"
android:padding="@dimen/activity_vertical_margin"
app:behavior_peekHeight="120dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<include layout="@layout/bottom_sheet_layout" />
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/CreamyGreen"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/static_persistent_txt"
android:padding="16dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@android:color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:text="@string/ipsum"
android:textColor="@android:color/white"
android:textSize="16sp" />
</LinearLayout>
这是一种变通方法。(注意:此代码在活动中)
谷歌的家伙们按计划完成了这项工作,这里有一个解决办法 屏幕高度比有一个神奇的常数,它似乎是最小值(实际宽度,最大宽度),这显然不起作用 因此,使用手机景观,可以将其覆盖到更大的范围
<style name="Theme.Main.Reader">
...
<item name="bottomSheetDialogTheme">@style/ReaderBottomSheelDialog</item>
</style>
<style name="ReaderBottomSheelDialog" parent="Theme.Design.BottomSheetDialog">
<item name="bottomSheetStyle">@style/BottomSheetStyle</item>
</style>
<style name="BottomSheetStyle" parent="Widget.Design.BottomSheet.Modal">
<item name="behavior_peekHeight">512dp</item>
</style>
...
@样式/读卡器底部样式表
@样式/底片样式
512dp
要使BottomSheetDialogFragment始终完全打开(也在横向模式下),我执行以下操作
在onCreateDialog中创建BottomSheetDialog和视图。将此视图添加到BottomSheetDialog后,可以使用BottomSheetBehavior.from()中视图的父级来获取BottomSheetBehavior
然后在BottomSheetDialogFragment的onStart中,调用状态为展开的BottomSheetBehavior.setState
BottomSheetBehavior mBottomBehavior;
public Dialog onCreateDialog(Bundle savedInstanceState) {
BottomSheetDialog dialog = new BottomSheetDialog(getContext());
mBinding = SomeBinding.inflate(LayoutInflater.from(getContext()));
dialog.setContentView(mBinding.getRoot());
mBottomBehavior = BottomSheetBehavior.from((View) mBinding.getRoot().getParent());
return dialog;
}
public void onStart() {
super.onStart();
mBottomBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
我希望这对某人有所帮助。BottomSheetDialog;
BottomSheet行为BottomSheet行为
private void createBottomSheet() {
if (dialog == null){
dialog = new BottomSheetDialog(this);
final View view = LayoutInflater.from(this).inflate(R.layout.setting_dialog,
(ViewGroup)this.getWindow().getDecorView().getRootView(),false);
dialog.setContentView(view);
bottomSheetBehavior = BottomSheetBehavior.from((View)view.getParent());
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
bottomSheetBehavior.setPeekHeight(view.getHeight());
}
});
}
}
我个人选择解决这个问题是,在创建视图之后,您已经拥有BottomSheetDialogFragment的主视图 创建视图后,将执行onStart,因此您可以使用以下行为:
@Override
public void onStart() {
super.onStart();
//this expands the bottom sheet even after a config change
bottomSheetBehavior = BottomSheetBehavior.from((View) mainLayout.getParent());
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
然后,您将始终在androidX中展开底部工作表,底部工作表可按如下方式展开:
BottomSheetDialog bottomSheetDialog =
new BottomSheetDialog(requireContext());
bottomSheetDialog.setContentView(view);
bottomSheetDialog.show();
FrameLayout bottomSheet = (FrameLayout)
bottomSheetDialog.findViewById(com.google.android.material.R.id.design_bottom_sheeet);
BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
behavior.setPeekHeight(0);
在获取底部板材行为的同时,如果出现以下错误,这也会很有帮助:
“视图不是coordinatorlayout的子视图”这可以通过两行实现(Kotlin版本)
将此函数添加到类扩展DialogFragment的实现中,将完成必要的操作:
@Override
public void onStart() {
super.onStart();
BottomSheetBehavior.from((View) requireView().getParent()).setState(BottomSheetBehavior.STATE_EXPANDED);
// Opens the bottom sheet in expanded state even in landscape mode
BottomSheetBehavior.from((View) requireView().getParent()).setSkipCollapsed(true);
// Skips the peek view of the bottom sheet
}
尽管我同意这看起来是错误的