• 解决BottomSheetDialog横屏下不能展示完全问题


    项目开发中使用了谷歌推荐的实现类似网易云音乐的上弹对话框BottomSheetDialog控件,该控件在竖屏状态下显示没有问题,但是在横屏状态下弹窗只能显示一半,需要手动往上滑一下才能完全显示。在网上找了下解决方案,看到了https://www.jianshu.com/p/50c54d8e0d4a 相同的问题,但是这篇文章中只给了相应的解决方案,没有完整的代码,对于使用原生的BottomSheetDialog人员来说,根本就是个鸡肋。这里我结合源码和上述文章中的解决方案,整理成一个完整的自定义BottomSheetDialog供后来者使用,希望能帮助你们。

    特别注意:这里对应的布局文件和id对应的R文件直接引用你们项目中的R文件就可以,布局使用的是Android 自带的布局文件,只要使用Android studio进入BottomDialog的源码,点击下面图片中的位置即可使

    用。

    下载BottomSheetDialog布局文件和样式的位置

    下面是完整代码:

      1 import android.content.Context;
      2 import android.content.res.TypedArray;
      3 import android.os.Build;
      4 import android.os.Bundle;
      5 import android.support.annotation.LayoutRes;
      6 import android.support.annotation.NonNull;
      7 import android.support.annotation.StyleRes;
      8 import android.support.design.widget.BottomSheetBehavior;
      9 import android.support.design.widget.CoordinatorLayout;
     10 import android.support.v4.view.AccessibilityDelegateCompat;
     11 import android.support.v4.view.ViewCompat;
     12 import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
     13 import android.support.v7.app.AppCompatDialog;
     14 import android.util.TypedValue;
     15 import android.view.MotionEvent;
     16 import android.view.View;
     17 import android.view.ViewGroup;
     18 import android.view.Window;
     19 import android.widget.FrameLayout;
     20 
     21 
     22 public class BaseBottomSheetDialog extends AppCompatDialog {
     23     private BottomSheetBehavior<FrameLayout> behavior;
     24     boolean cancelable;
     25     private boolean canceledOnTouchOutside;
     26     private boolean canceledOnTouchOutsideSet;
     27     private BottomSheetBehavior.BottomSheetCallback bottomSheetCallback;
     28 
     29     public BaseBottomSheetDialog(@NonNull Context context) {
     30         this(context, 0);
     31     }
     32 
     33     public BaseBottomSheetDialog(@NonNull Context context, @StyleRes int theme) {
     34         super(context, getThemeResId(context, theme));
     35         this.cancelable = true;
     36         this.canceledOnTouchOutside = true;
     37         this.bottomSheetCallback = new NamelessClass_1();
     38         this.supportRequestWindowFeature(1);
     39     }
     40 
     41     protected BaseBottomSheetDialog(@NonNull Context context, boolean cancelable, OnCancelListener cancelListener) {
     42         super(context, cancelable, cancelListener);
     43         this.cancelable = true;
     44         this.canceledOnTouchOutside = true;
     45 
     46 
     47 
     48         this.bottomSheetCallback = new NamelessClass_1();
     49         this.supportRequestWindowFeature(1);
     50         this.cancelable = cancelable;
     51     }
     52 
     53     public void setContentView(@LayoutRes int layoutResId) {
     54         super.setContentView(this.wrapInBottomSheet(layoutResId, (View)null, (ViewGroup.LayoutParams)null));
     55     }
     56     class NamelessClass_1 extends BottomSheetBehavior.BottomSheetCallback {
     57         NamelessClass_1() {
     58         }
     59 
     60         public void onStateChanged(@NonNull View bottomSheet, int newState) {
     61             if (newState == 5) {
     62                 BaseBottomSheetDialog.this.cancel();
     63             }
     64 
     65         }
     66 
     67         public void onSlide(@NonNull View bottomSheet, float slideOffset) {
     68         }
     69     }
     70     protected void onCreate(Bundle savedInstanceState) {
     71         super.onCreate(savedInstanceState);
     72         Window window = this.getWindow();
     73         if (window != null) {
     74             if (Build.VERSION.SDK_INT >= 21) {
     75                 window.clearFlags(67108864);
     76                 window.addFlags(-2147483648);
     77             }
     78 
     79             window.setLayout(-1, -1);
     80         }
     81 
     82     }
     83 
     84     public void setContentView(View view) {
     85         super.setContentView(this.wrapInBottomSheet(0, view, (ViewGroup.LayoutParams)null));
     86     }
     87 
     88     public void setContentView(View view, ViewGroup.LayoutParams params) {
     89         super.setContentView(this.wrapInBottomSheet(0, view, params));
     90     }
     91 
     92     public void setCancelable(boolean cancelable) {
     93         super.setCancelable(cancelable);
     94         if (this.cancelable != cancelable) {
     95             this.cancelable = cancelable;
     96             if (this.behavior != null) {
     97                 this.behavior.setHideable(cancelable);
     98             }
     99         }
    100 
    101     }
    102 
    103     protected void onStart() {
    104         super.onStart();
    105         if (this.behavior != null) {
    106             this.behavior.setState(3);
    107         }
    108     }
    109 
    110     public void setCanceledOnTouchOutside(boolean cancel) {
    111         super.setCanceledOnTouchOutside(cancel);
    112         if (cancel && !this.cancelable) {
    113             this.cancelable = true;
    114         }
    115 
    116         this.canceledOnTouchOutside = cancel;
    117         this.canceledOnTouchOutsideSet = true;
    118     }
    119 
    120     private View wrapInBottomSheet(int layoutResId, View view, ViewGroup.LayoutParams params) {
    121         FrameLayout container = (FrameLayout)View.inflate(this.getContext(), R.layout.design_bottom_sheet_dialog, (ViewGroup)null);
    122         CoordinatorLayout coordinator = (CoordinatorLayout)container.findViewById(R.id.coordinator);
    123         if (layoutResId != 0 && view == null) {
    124             view = this.getLayoutInflater().inflate(layoutResId, coordinator, false);
    125         }
    126 
    127         FrameLayout bottomSheet = (FrameLayout)coordinator.findViewById(R.id.design_bottom_sheet);
    128         this.behavior = BottomSheetBehavior.from(bottomSheet);
    129         this.behavior.setBottomSheetCallback(this.bottomSheetCallback);
    130         this.behavior.setHideable(this.cancelable);
    131         if (params == null) {
    132             bottomSheet.addView(view);
    133         } else {
    134             bottomSheet.addView(view, params);
    135         }
    136         coordinator.findViewById(R.id.touch_outside).setOnClickListener(new View.OnClickListener() {
    137             @Override
    138             public void onClick(View v) {
    139                 if (BaseBottomSheetDialog.this.cancelable && BaseBottomSheetDialog.this.isShowing() && BaseBottomSheetDialog.this.shouldWindowCloseOnTouchOutside()) {
    140                     BaseBottomSheetDialog.this.cancel();
    141                 }
    142             }
    143         });
    144         ViewCompat.setAccessibilityDelegate(bottomSheet, new AccessibilityDelegateCompat() {
    145             public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
    146                 super.onInitializeAccessibilityNodeInfo(host, info);
    147                 if (BaseBottomSheetDialog.this.cancelable) {
    148                     info.addAction(1048576);
    149                     info.setDismissable(true);
    150                 } else {
    151                     info.setDismissable(false);
    152                 }
    153 
    154             }
    155 
    156             public boolean performAccessibilityAction(View host, int action, Bundle args) {
    157                 if (action == 1048576 &&BaseBottomSheetDialog.this.cancelable) {
    158                     BaseBottomSheetDialog.this.cancel();
    159                     return true;
    160                 } else {
    161                     return super.performAccessibilityAction(host, action, args);
    162                 }
    163             }
    164         });
    165         bottomSheet.setOnTouchListener((view1, event) -> true);
    166         return container;
    167     }
    168 
    169     boolean shouldWindowCloseOnTouchOutside() {
    170         if (!this.canceledOnTouchOutsideSet) {
    171             TypedArray a = this.getContext().obtainStyledAttributes(new int[]{16843611});
    172             this.canceledOnTouchOutside = a.getBoolean(0, true);
    173             a.recycle();
    174             this.canceledOnTouchOutsideSet = true;
    175         }
    176 
    177         return this.canceledOnTouchOutside;
    178     }
    179 
    180     private static int getThemeResId(Context context, int themeId) {
    181         if (themeId == 0) {
    182             TypedValue outValue = new TypedValue();
    183             if (context.getTheme().resolveAttribute(R.attr.bottomSheetDialogTheme, outValue, true)) {
    184                 themeId = outValue.resourceId;
    185             } else {
    186                 themeId = R.style.Theme_Design_Light_BottomSheetDialog;
    187             }
    188         }
    189 
    190         return themeId;
    191     }
    192 }
  • 相关阅读:
    对linux内核创建flash上的各分区源码进行分析
    如何调试ubifs文件系统
    如何打开linux内核中dev_dbg的开关
    配置linux内核输出所有的log信息
    uboot向linux传递输出任何log信息的方法
    redis:Invalid input of type: 'bool' type. Convert to a byte,string or number first
    dd命令参数解析
    shell脚本中使用什么工具进行计算
    openwrt的编译方法
    bootstraptable表格columns 隐藏方法
  • 原文地址:https://www.cnblogs.com/1925yiyi/p/13613505.html
Copyright © 2020-2023  润新知