Miu*_*ium 8 android material-design
https://material.io/design/components/backdrop.html
我在Material Design上找到了这个,但是找不到任何资源。考虑其布局,我认为它是由具有物料卡视图的任何布局组成的,并且我正尝试使用布局+物料卡视图创建活动文件。此方法是否正确进行背景布局?
另外,我想知道应该使用哪种布局。RelativeLayout可以吗?我真的不明白。
Leo*_*Leo 19
截至2018年12月16日,此组件(BackDrop)仍在针对Android Material Components库进行开发。
但是,如果您已经在使用Material Components,则实现自己的组件并不难。您将需要以下内容:
下面提供的解决方案如下图所示:
下面的示例使用一个片段,我将省略托管活动的详细信息,因为它与问题/答案无关。但是,您可以对活动执行完全相同的操作。您的片段布局文件如下所示:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/coordinatorLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--This the interface sitting behind the backdrop and shown when it is collapsed-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/colorPrimary"
android:padding="@dimen/activity_spacing">
<EditText
android:id="@+id/searchTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_search_primary_xlight_24dp"
style="@style/EditTextStyle.Inverse.Large.Light"
android:hint="@string/search_hint"/>
<EditText
android:id="@+id/datesFilterButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_calendar_primary_xlight_24dp"
style="@style/EditTextStyle.Inverse.Large.Light"
android:hint="@string/select_dates_hint"/>
</LinearLayout>
<!--This is the backdrop's content with a BottomSheetBehaviour applied to it-->
<LinearLayout
android:id="@+id/contentLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:behavior_peekHeight="56dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<!--This is the backdrop's header with a title and icon-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:clickable="true"
android:background="@drawable/ic_list_header_background"
android:padding="@dimen/activity_spacing"
android:elevation="4dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
style="@style/TextAppearance.Stems.Body2"
android:text="0 items(s)"/>
<ImageView
android:id="@+id/filterIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_filter_black_24dp"
android:layout_gravity="end"/>
</LinearLayout>
<!--And finally this is the body of the backdrop's content. You can add here whatever you need inside a view group (LinearLayout, RelativeLayout, SwipeRefreshLayout, ConstraintLayout, etc.)-->
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorBackground">
<!--The content's body goes here-->
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Run Code Online (Sandbox Code Playgroud)
There's a couple of things you need to be aware of here. First, the LinearLayout
that sits behind the backdrop its using the colorPrimary
color which exactly the same as the Toolbar
's background color...the toolbar has been ommitted for clarity, it is declared in the hosting activity (remember, this solution is for a fragment).
Then the fragment's class will look like this...
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
coordinatorLayout = (CoordinatorLayout)inflater.inflate(R.layout.fragment_hazards, container, false);
Context context = getContext();
if(context != null){
setTitle(context.getString(R.string.title_hazards));
}
filterIcon = coordinatorLayout.findViewById(R.id.filterIcon);
LinearLayout contentLayout = coordinatorLayout.findViewById(R.id.contentLayout);
sheetBehavior = BottomSheetBehavior.from(contentLayout);
sheetBehavior.setFitToContents(false);
sheetBehavior.setHideable(false);//prevents the boottom sheet from completely hiding off the screen
sheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);//initially state to fully expanded
filterIcon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
toggleFilters();
}
});
return coordinatorLayout;
}
private void toggleFilters(){
if(sheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED){
sheetBehavior.setState(BottomSheetBehavior.STATE_HALF_EXPANDED);
}
else {
sheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
}
Run Code Online (Sandbox Code Playgroud)
And that's it, the only thing you need to keep in mind is that root layout has to be a CoordinatorLayout
and that the BottomSheetBehaviour
has to be applied to an immediate child of the root layout
You will also notice that I'm not using a CardView
in the BackDrop's header to get the nice rounded corners the CardView
comes with. That's because I only need the top corners to be rounded and the default implementation of CardView
doesn't allow you to explicitly set individual corners. Instead, I used a good old LinearLayout
and provided my own drawable for its background (ic_list_header_background
). Here's the xml declaration of this drawable...
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="@color/colorBackground" />
<corners android:topLeftRadius="16dp" android:topRightRadius="16dp" />
</shape>
Run Code Online (Sandbox Code Playgroud)
Nothing really fancy, just a rectangular shape with selective rounded corners (the top ones)
You will want to remove the ToolBar's drop shadow, to do so, you can set its elevation to 0dp
or programmatically remove the outline provider on the parent AppBarLayout
as below...
appBarLayout.setOutlineProvider(null);
Run Code Online (Sandbox Code Playgroud)
obviously, this is assuming that your Toolbar
is inside an AppBarLayout
as per the guidelines
I hope this really helps someone out there while the Material Component's BackDrop is still under development. It's not perfect because you are still bound to the functionalities exposed by the BottomSheetBehaviour component that it's quite limited. But if you are picky or want to go fancy, I'd recommend implementing your own BottomSheetBehaviour by extending the default one
Based on Material Design Guidelines, it is recommended not to use swipe gestures on the front layer of the backdrop
Don’t use the swipe gesture on the front layer to reveal the back layer.
However, by default, the BottomSheetBehaviour
doesn't expose any properties or APIs to disable swipe gestures. To achieve that, you will need to implement your own by extending the BottomSheetBehaviour
overriding all gesture-related methods. Here's an example I'm using in one of my projects (written in Kotlin)
class GestureLockedBottomSheetBehavior<V: View>(context: Context, attributeSet: AttributeSet?) : BottomSheetBehavior<V>(context, attributeSet){
constructor(context: Context):this(context, null)
override fun onInterceptTouchEvent(parent: CoordinatorLayout, child: V, event: MotionEvent): Boolean = false
override fun onTouchEvent(parent: CoordinatorLayout, child: V, event: MotionEvent): Boolean = false
override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
directTargetChild: View,
target: View,
axes: Int,
type: Int
): Boolean = false
override fun onNestedPreScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
dx: Int,
dy: Int,
consumed: IntArray,
type: Int
) { }
override fun onStopNestedScroll(coordinatorLayout: CoordinatorLayout, child: V, target: View, type: Int) { }
override fun onNestedFling(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
velocityX: Float,
velocityY: Float,
consumed: Boolean
): Boolean = false
}
Run Code Online (Sandbox Code Playgroud)
Even if you're not familiar with Kotlin it shouldn't be hard to figure out that all I'm doing is overriding a bunch on methods and return false or doing nothing by not calling the super class's counterpart
Then to use this GestureLockedBottomSheetBehavior
class, you will need to replace it in your layout as below...
<LinearLayout
android:id="@+id/contentLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:behavior_peekHeight="56dp"
app:layout_behavior="ui.behaviors.GestureLockedBottomSheetBehavior">
...
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
Just make sure the fully-qualified name is set according to the package your custom class resides in.
它现在正在开发中(背景 github 页面)。
代码和如何......一旦开发出来就可用。因此,现在您必须创建自己的自定义背景或等待。
如果你想这样做,我会建议你使用FrameLayout并在其中添加一些CardView 并 在其中添加一些边距以使其看起来像背景,在过渡时添加一些动画,您的自定义背景就准备好了。
归档时间: |
|
查看次数: |
4196 次 |
最近记录: |