你如何实现底部工作表规范?http://www.google.com/design/spec/components/bottom-sheets.html
Google Drive的新更新通过Floating Action Button按下来显示此内容 ->
虽然规格说明中没有提到圆角,但是这是可以实现的,只是不确定如何去做。目前正在使用AppCompat库并将目标设置为21。
谢谢。
你如何实现底部工作表规范?http://www.google.com/design/spec/components/bottom-sheets.html
Google Drive的新更新通过Floating Action Button按下来显示此内容 ->
虽然规格说明中没有提到圆角,但是这是可以实现的,只是不确定如何去做。目前正在使用AppCompat库并将目标设置为21。
谢谢。
BottomSheet
现在是 android-support-library
的一部分。请参见约翰·谢利的答案。
不幸的是,目前没有官方的方法可以做到这一点(至少我不知道有)。
幸运的是,有一个名为"BottomSheet"(点击)的库,它模仿了BottomSheet
的外观和感觉,并支持 Android 2.1 及以上版本。
对于Drive应用程序,在这个库中的代码如下所示:
new BottomSheet.Builder(this, R.style.BottomSheet_Dialog)
.title("New")
.grid() // <-- important part
.sheet(R.menu.menu_bottom_sheet)
.listener(new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO
}
}).show();
menu_bottom_sheet(基本上是一个标准的/res/menu/*.xml资源)
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/folder"
android:title="Folder"
android:icon="@drawable/ic_action_folder" />
<item
android:id="@+id/upload"
android:title="Upload"
android:icon="@drawable/ic_action_file_upload" />
<item
android:id="@+id/scan"
android:title="Scan"
android:icon="@drawable/ic_action_camera_alt" />
</menu>
输出如下:
我认为这已经非常接近原版了。如果您对颜色不满意,您可以自定义它-点击此处(单击).
回答自己的问题,让开发人员知道新的支持库终于提供了这个功能!让我们向强大的谷歌致敬!
Android Developer's Blog中的一个例子:
// The View with the BottomSheetBehavior
View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);
BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
behavior.setBottomSheetCallback(new BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
// React to state change
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
// React to dragging events
}
});
@reVerse的上面的答案仍然是一个有效的选项,但知道Google支持的标准也很好。
根据博客文章:http://android-developers.blogspot.com/2016/02/android-support-library-232.html
我的 XML 最终看起来像这样:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/coordinator_layout"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:id="@+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="horizontal"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<ImageView
android:src="@android:drawable/ic_input_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
coordinatorLayout = (CoordinatorLayout)v.findViewById(R.id.coordinator_layout);
View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);
BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
behavior.setPeekHeight(100);
behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
// React to state change
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
// React to dragging events
}
});
setPeekHeight的默认值为0,因此如果您没有设置它,则无法看到您的视图。
com.google.android.material.bottomsheet.BottomSheetBehavior
。 - Ultimo_m现在您可以从Android支持库23.2中使用官方的BottomSheetBehavior
API。
以下是示例代码片段:
bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.bottomSheet));
case R.id.expandBottomSheetButton:
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
break;
case R.id.collapseBottomSheetButton:
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
break;
case R.id.hideBottomSheetButton:
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
break;
case R.id.showBottomSheetDialogButton:
new MyBottomSheetDialogFragment().show(getSupportFragmentManager(), "sample");
我会按照指南使用直角。至于实现方式,也许最好使用这个项目的想法:https://github.com/umano/AndroidSlidingUpPanel
我认为你可以直接使用它或者借鉴其实现思路。另外,还有一篇关于如何实现类似滑动面板的很棒的文章在这里:http://blog.neteril.org/blog/2013/10/10/framelayout-your-best-ui-friend/
bottom_sheet_layout.xml
布局文件bottom_sheet_background.xml
可绘制文件bottom_sheet_background.xml
可绘制文件设置为以下内容: <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/bottom_sheet_background"/>
<corners
android:topRightRadius="20dp"
android:topLeftRadius="20dp"/>
</shape>
你的bottom_sheet_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/bottom_Sheet"
android:background="@drawable/bottom_sheet_background"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="24dp"
android:paddingEnd="24dp"
android:paddingTop="16dp"
android:paddingBottom="42dp"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="@+id/rectangle_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="@drawable/rectangle_39"
/>
//add your design code here
</LinearLayout>
以及您的activity_main.xml
或片段
<androidx.coordinatorlayout.widget.CoordinatorLayout android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
//design your code here
//this is your bottom sheet layout included here
<include
android:id="@+id/bottom_sheet_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="com.google.android.material.
bottomsheet.BottomSheetBehavior"
layout="@layout/bottom_sheet_layout"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
最后,在您的 MainActivity
或 Fragment
类中添加代码。这里我将在您的 onCreate
或 onCreateView
中添加 Kotlin 代码。
BottomSheetBehavior.from(binding.bottomSheetLayout.bottomSheet).apply {
//peek height is default visible height
peekHeight = 200
this.state = BottomSheetBehavior.STATE_COLLAPSED
}
就是这样!
谷歌最近发布了Android Support Library 23.2,官方将底部工作表引入了Android Design Support Library。
现在随着Android Jetpack Compose的发布,这是Android的现代UI工具包,底部工作表可以更轻松地创建,而无需使用任何xml代码:
1.创建持久性底部工作表,用户可以在底部工作表范围之外访问内容:
val bottomSheetScaffoldState = rememberBottomSheetScaffoldState(
bottomSheetState = BottomSheetState(BottomSheetValue.Collapsed)
)
val coroutineScope = rememberCoroutineScope()
MaterialTheme {
Column {
BottomSheetScaffold(
modifier = Modifier.fillMaxSize(),
topBar = { TopAppBar(viewModel, onNavigateToRecipeListScreen, hideKeyBoard) },
content = {
CreateRecipeContent(
viewModel,
context,
readExternalStorage,
bottomSheetScaffoldState,
coroutineScope
)
},
scaffoldState = bottomSheetScaffoldState,
sheetContent = {
Column(
Modifier
.fillMaxWidth()
.height(200.dp)
.background(color = colorResource(id = R.color.colorPrimaryLight))
)
{
Text(
text = "SELECT PICTURE",
style = TextStyle(fontSize = 26.sp),
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(8.dp)
.align(Alignment.Start),
color = Color.Black
)
Spacer(modifier = Modifier.height(16.dp))
IconButton(onClick = {
when {
context.let { it1 ->
ContextCompat.checkSelfPermission(
it1,
Manifest.permission.READ_EXTERNAL_STORAGE
)
} == PackageManager.PERMISSION_GRANTED -> {
val takePictureIntent =
Intent(MediaStore.ACTION_IMAGE_CAPTURE)
launchCamera(takePictureIntent)
coroutineScope.launch {
bottomSheetScaffoldState.bottomSheetState.collapse()
}
}
else -> {
// You can directly ask for the permission.
// The registered ActivityResultCallback gets the result of this request.
viewModel.isCameraPermissionAsked = true
readExternalStorage()
coroutineScope.launch {
bottomSheetScaffoldState.bottomSheetState.collapse()
}
}
}
}, modifier = Modifier.fillMaxWidth()) {
Text(
text = "TAKE PHOTO",
style = TextStyle(fontSize = 20.sp),
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(8.dp)
.align(Alignment.Start),
textAlign = TextAlign.Left,
color = Color.Black
)
}
Spacer(modifier = Modifier.height(16.dp))
IconButton(onClick = {
when {
context.let { it1 ->
ContextCompat.checkSelfPermission(
it1,
Manifest.permission.READ_EXTERNAL_STORAGE
)
} == PackageManager.PERMISSION_GRANTED -> {
val galleryIntent = Intent(
Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
)
galleryIntent.type = "image/*"
launchGalley(galleryIntent)
coroutineScope.launch {
bottomSheetScaffoldState.bottomSheetState.collapse()
}
}
else -> {
// You can directly ask for the permission.
// The registered ActivityResultCallback gets the result of this request.
viewModel.isCameraPermissionAsked = false
readExternalStorage()
coroutineScope.launch {
bottomSheetScaffoldState.bottomSheetState.collapse()
}
}
}
}, modifier = Modifier.fillMaxWidth()) {
Text(
text = "CHOOSE FROM GALLERY",
style = TextStyle(fontSize = 20.sp),
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(8.dp)
.align(Alignment.Start),
textAlign = TextAlign.Left,
color = Color.Black
)
}
}
}, sheetPeekHeight = 0.dp
)
}
}
上述代码片段和屏幕截图来自该应用程序:
https://play.google.com/store/apps/details?id=com.bhuvnesh.diary
这个应用完全由我使用Jetpack Compose创建
创建模态底部表单,使用户无法访问底部表单范围之外的内容:
ModalBottomSheetLayout(
sheetState = modalBottomSheetState,
sheetElevation = 8.dp,
sheetContent = {
//表单内容
}
) {
...
//主要内容
}