AndroidBottomSheet效果的两种实现⽅式本⽂介绍了Android BottomSheet效果的两种实现⽅式,分享给⼤家,具体如下:
BottomSheet效果
BottomSheet的效果是指从屏幕底部向上滑的效果,是MaterialDesign风格的⼀种,视觉效果如下:
BottomSheet效果
实现这种效果有⼏种不同的⽅式,如果是在⼀个固定的页⾯上添加这种效果,可以在该页⾯布局中添加BoottomSheet相关的控件。如果是作为通⽤控件来提供给不同页⾯使⽤,则可以使⽤BottomSheetDialog实现,本⽂将对两种⽅法进⾏讲解,其中会讲到⼀些使⽤上的细节,处理不好这些细节,会出现⾮常怪异的效果。
单页⾯添加BottomSheet效果
android layout布局⾸先引⼊依赖包:
compile 'com.android.support:design:27.1.1'
页⾯布局如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="schemas.android/apk/res/android"
xmlns:app="schemas.android/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/customActionWebView"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="⽂本⼀"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="⽂本⼆"/>
</LinearLayout>
<android.support.v4.widget.NestedScrollView
android:id="@+id/nested_scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:behavior_hideable="true"
app:behavior_peekHeight="150dp"
android:layout_gravity="bottom"
app:layout_behavior="@string/bottom_sheet_behavior">
<WebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</WebView>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
根布局需要使⽤CoordinatorLayout,同时在其直接⼦布局——这⾥是NestedScrollView——⾥添加behavior
app:layout_behavior = "@string/bottom_sheet_behavior" 。很多⽂章说指定behavior的控件必须是NestedScrollView,这是错误的,实际上任何view或viewgroup都可以。该behavior配合CoordinateLayout就可以实现behavior所在控件的上滑效果。如果需要上滑的布局展⽰的时候先漏出⼀部分,如上⾯视频所⽰,可以通过设置 app:behavior_peekHeight 实现,它⽤来指定漏出的⾼度。
在代码部分,⾸先获取NestedScrollView的behavior,然后通过behavior控制底部卡⽚什么时候弹出,同时会有⼀些状态回调函数可供调⽤。
public class BrowserActivity extends AppCompatActivity {
private NestedScrollView nestedScrollView;
private BottomSheetBehavior behavior;
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.browser_layout);
nestedScrollView = (NestedScrollView) findViewById(sted_scroll_view);
behavior = BottomSheetBehavior.from(nestedScrollView);
behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
//这⾥是bottomSheet 状态的改变
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
//这⾥是拖拽中的回调,根据slideOffset可以做⼀些动画
}
});
}
public void showBottomSheet() {
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
}
通过这种⽅式可以在特定的页⾯添加底部上滑的效果。
BottomSheetDialog实现通⽤效果
BottomSheetDialog是BottomSheet效果实现的⼀种更加通⽤的⽅法,⽐如我们需要在不同的页⾯实现长按⽂本弹出卡⽚列表效果,下⾯给出实现。
我们集成BottomSheetDialog实现⾃定义的Dialog,其布局如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="schemas.android/apk/res/android"
xmlns:app="schemas.android/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<view class="io.tensordemo.CustomBottomSheetDialogForWebView$NestViewEmbeddedListView"
android:id="@+id/card_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@color/transparent"
android:scrollbars="none"
android:dividerHeight="15dp"
android:layout_margin="20dp">
</view>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
注意,这⾥最外层布局需要是 NestedScrollView ,⽽不能是CoordinateLayout ,因为BottomSheetDialog本⾝已经有个CoordinateLayout根布局,它会把你的布局⽂件包裹起来,如果你在⾃⼰的布局⾥把最外层布局写成CoordinateLayout,会导致底部上滑的卡⽚,在下滑消失后屏幕依旧变暗的问题,这是因为整个布局变成了两个CoordinateLayout嵌套,下滑的时候⾥⾯的CoordinateLayout滑出屏幕,但外层的CoordinateLayout仍然在展⽰。通过查阅BottomSheetDialog源码可以看出,它是这样包裹你的布局⽂件的:
public class BottomSheetDialog extends AppCompatDialog {
...
@Override
public void setContentView(@LayoutRes int layoutResId) {
super.setContentView(wrapInBottomSheet(layoutResId, null, null));
}
private View wrapInBottomSheet(int layoutResId, View view, ViewGroup.LayoutParams params) {
final FrameLayout container = (FrameLayout) View.inflate(getContext(),
R.layout.design_bottom_sheet_dialog, null);
final CoordinatorLayout coordinator =
(CoordinatorLayout) container.findViewById(dinator);
if (layoutResId != 0 && view == null) {
view = getLayoutInflater().inflate(layoutResId, coordinator, false);
}
FrameLayout bottomSheet = (FrameLayout) coordinator.findViewById(R.id.design_bottom_sheet);
mBehavior = BottomSheetBehavior.from(bottomSheet);
mBehavior.setBottomSheetCallback(mBottomSheetCallback);
mBehavior.setHideable(mCancelable);
if (params == null) {
bottomSheet.addView(view);
} else {
bottomSheet.addView(view, params);
}
// We treat the CoordinatorLayout as outside the dialog though it is technically inside
coordinator.findViewById(uch_outside).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mCancelable && isShowing() && shouldWindowCloseOnTouchOutside()) {
cancel();
}
}
});
...
return container;
}
...
}
所以,BottomSheetDialog本⾝的布局实际如下:
BottomSheetDialog页⾯布局
我们可以看到最外层是FrameLayout,⾥⾯有个CoordinateLayout,CoordinateLayout⾥⾯有个直接⼦布局FrameLayout,该CoordinateLayout指定了Behavior,最⾥⾯才是⽤户⾃定义的布局,所以不应该在⾃定义布局⾥再添加CoordinateLayout,也不应该再次指定Behavior,直接摆放你的内容就⾏。
我们的⾃定义布局如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="schemas.android/apk/res/android"
xmlns:app="schemas.android/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<view class="io.tensordemo.CustomBottomSheetDialogForWebView$NestViewEmbeddedListView"
android:id="@+id/card_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@color/transparent"
android:scrollbars="none"
android:dividerHeight="15dp"
android:layout_margin="20dp">
</view>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。