在Android上使用背景

在Android上使用背景,android,material-design,Android,Material Design,我在材料设计上找到了这个,但找不到任何资源。 考虑到它的布局,我认为它是由任何带有材质卡片视图的布局组成的,我正在尝试使用布局+材质卡片视图制作我的活动文件。这种方法制作背景布局正确吗 另外,我想知道我应该使用哪种布局。是相对的吗?你可以这样做吗?实际上我不明白。它现在正在开发中() 代码和如何。。一旦开发出来就可以使用。所以,现在你必须创建自己的定制背景或等待它 我建议如果您想这样做,那么使用FrameLayout并添加一些CardView 在其中添加一些边距以使其看起来像背景,在过渡时添加一

我在材料设计上找到了这个,但找不到任何资源。 考虑到它的布局,我认为它是由任何带有材质卡片视图的布局组成的,我正在尝试使用布局+材质卡片视图制作我的活动文件。这种方法制作背景布局正确吗


另外,我想知道我应该使用哪种布局。是相对的吗?你可以这样做吗?实际上我不明白。

它现在正在开发中()

代码和如何。。一旦开发出来就可以使用。所以,现在你必须创建自己的定制背景或等待它

我建议如果您想这样做,那么使用FrameLayout并添加一些CardView 在其中添加一些边距以使其看起来像背景,在过渡时添加一些动画&您的自定义背景将准备就绪。

自2018年12月16日起,该组件(背景)仍在为库开发中

但是,如果您已经在使用材质组件,那么实现自己的组件并不难。您将需要以下内容:

  • 作为根布局
  • 应用于根布局的直接子级的
下面提供的解决方案如下图所示

下面的示例使用了一个片段,我将介绍托管活动的详细信息,因为它与问题/答案无关。但是,您可以对活动执行完全相同的操作。您的片段布局文件如下所示

<?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>
就是这样,您需要记住的唯一一件事是根布局必须是
协调布局
,并且
底部布局行为
必须应用于根布局的直接子级

圆角 您还会注意到,我没有在背景标题中使用
CardView
来获得
CardView
附带的漂亮圆角。这是因为我只需要将顶角圆角,而
cardwiew
的默认实现不允许显式设置各个角。相反,我使用了一个很好的老式
线性布局
,并为其背景提供了我自己的绘图工具(
ic\u list\u header\u 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/colorBackground" />
    <corners android:topLeftRadius="16dp" android:topRightRadius="16dp" />

</shape>
显然,这是假设您的
工具栏
按照指南位于
AppBarLayout

我希望这真的能帮助一些人,而材料组件的背景仍在开发中。它并不完美,因为您仍然受限于BottomSheetBehavior组件公开的功能,因此它非常有限。但是,如果你很挑剔或者想变得花哨,我建议通过扩展默认行为来实现你自己的行为

禁用用户的刷卡手势 基于,建议不要在背景的前一层使用滑动手势

不要在前一层使用滑动手势来显示后一层

但是,默认情况下,
bottomsheetbehavior
不会公开任何属性或API来禁用滑动手势。要实现这一点,您需要通过扩展
bottomsheetbehavior
覆盖所有与手势相关的方法来实现自己的方法。下面是我在一个项目中使用的一个示例(用Kotlin编写)


只需确保完全限定名是根据自定义类所在的包设置的。

我想对Leo的答案做一点修改:

我在
LinearLayout
中使用
RecyclerView
。这张
LinearLayout
是我的底稿。按照Leo的建议使用
GestureLockedBottomSheetBehavior
,不允许
RecyclerView
滚动,下面是我为解决这个问题所做的

这是我最后用来进行
RecyclerView
滚动的自定义底部表单行为类

class GestureLockedBottomSheetBehavior<V: View>(context: Context, attributeSet: AttributeSet) : BottomSheetBehavior<V>(context, attributeSet){

    override fun onInterceptTouchEvent(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
}
class GestureLockedBottomSheetBehavior(上下文:上下文,属性集:属性集):BottomSheetBehavior(上下文,属性集){
重写InterceptTouchEvent(父级:CoordinatorLayout,子级:V,事件:MotionEvent):布尔值=false
覆盖启动时的乐趣嵌套滚动(
协调布局:协调布局,
孩子:V,
directTargetChild:视图,
目标:视图,
轴:Int,
类型:Int
):Boolean=false
}
我的
RecyclerView
正在滚动。但它仅在底部工作表的状态为“已展开”时滚动,而在底部工作表的状态为“已展开”时,
RecyclerView
不会滚动


如果有人知道如何解决这个问题,这将非常有帮助。

我添加了一个cardview,但我不确定如何使其全屏显示。我想让cardview在滚动时填充屏幕。这可以通过ScrollView获得吗?您应该以编程方式更改布局参数以扩展您的cardview。分享一些代码,我会研究一下,并提供一些建议这确实很有效,但有一点,当用户尝试向上滚动时,底部会向下滚动,有什么解决方案吗?@tamimatafi这个答案中的代码还没有准备好生产。事实上,根据材料设计准则,你不应该允许在背景的前一层上使用滑动手势。我刚刚更新了答案,解释了如何禁用刷卡gestures@Leo:你是如何制作gif动画的?谢谢@斯蒂芬,我不记得了。就拿Android Studio和Google生成的mp4“mp4到gif”来说吧。你会在这个搜索词上获得很多点击率有人有EditText风格吗?(EditTextStyle.Inverse.Large.Light)我已经做了好几次了,我想你所要做的就是在recycleview上启用嵌套滚动。在kotlin中…
recyclerview.isNestedScrollingEnabled=true
appBarLayout.setOutlineProvider(null);
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
}
<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>
class GestureLockedBottomSheetBehavior<V: View>(context: Context, attributeSet: AttributeSet) : BottomSheetBehavior<V>(context, attributeSet){

    override fun onInterceptTouchEvent(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
}