Android Preference 卡片圆角风格定制

简介: Android Preference 卡片圆角风格定制

效果图


afbPyD.png


aLIiFO.png


实现步骤


在网上查找这块的资料,发现并未找到相关的,大多都是通过修改 Preference style 来设置背景色什么的,和我们预想的

效果不太一样,那就去看看 Preference 源码吧,说不定能有什么收获。

先看下 Preference 类继承关系结构图,在AS中通过快捷键 ctrl + h 即可调出视图

afva11.png


基本上我们常用的简单显示控件都继承自 Preference,系统设置界面也不例外,全都是用的 Preference


通过分析 Preference 源码发现了默认布局文件为 preference.xml,文件路径位于


frameworks/base/core/res/res/layout/preference.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Layout for a Preference in a PreferenceActivity. The
     Preference is able to place a specific widget for its particular
     type in the "widget_frame" layout. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical"
    android:paddingEnd="?android:attr/scrollbarSize"
    android:background="?android:attr/selectableItemBackground" >
    <ImageView
        android:id="@+android:id/icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        />
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="15dip"
        android:layout_marginEnd="6dip"
        android:layout_marginTop="6dip"
        android:layout_marginBottom="6dip"
        android:layout_weight="1">
        <TextView android:id="@+android:id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal" />
        <TextView android:id="@+android:id/summary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@android:id/title"
            android:layout_alignStart="@android:id/title"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textColor="?android:attr/textColorSecondary"
            android:maxLines="4" />
    </RelativeLayout>
    <!-- Preference should place its actual preference widget here. -->
    <LinearLayout android:id="@+android:id/widget_frame"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:orientation="vertical" />
</LinearLayout>


可以看到对应 Preference 基本属性 icon、title、summary,最外层布局为 LinearLayout,我们是不是可以通过修改


LinearLayout 的 background 属性来实现我们想要的效果呢?答案是可以的,巧的是 Preference 中提供了修改 layoutid 方法

public void setLayoutResource(int layoutResId) {
        mLayoutResId = layoutResId;
    }


google 已经贴心的给我们预留了定制接口,


在 xml 中使用 android:layout="@layout/card_preference"


在 java 中使用 mPreference.setLayoutResource(R.layout.card_preference)


这样我们就不用去修改 preference.xml 源码,copy preference.xml 保证里面的 id 对应即可,其它的随你定义。


接下来就让我们来实现上图的效果吧


1、新建圆角矩形 drawable 资源文件


card_style.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/cardBgColor" />
    <stroke
        android:width="1dp"
        android:color="@color/cardBgColor" />
    <corners android:radius="@dimen/card_corner_radius"/>
</shape>

card_style_top.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/cardBgColor" />
    <stroke
        android:width="1dp"
        android:color="@color/cardBgColor" />
    <corners
        android:topLeftRadius="@dimen/card_corner_radius"
        android:topRightRadius="@dimen/card_corner_radius"
        android:bottomRightRadius="0dp"
        android:bottomLeftRadius="0dp"/>
</shape>


card_style_middle.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/cardBgColor" />
    <stroke
        android:width="1dp"
        android:color="@color/cardBgColor" />
    <corners android:radius="0dp"/>
</shape>


card_style_bottom.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/cardBgColor" />
    <stroke
        android:width="1dp"
        android:color="@color/cardBgColor" />
    <corners
        android:topLeftRadius="0dp"
        android:topRightRadius="0dp"
        android:bottomRightRadius="@dimen/card_corner_radius"
        android:bottomLeftRadius="@dimen/card_corner_radius"/>
</shape>


对应 color 和 dimen


<color name="cardBgColor">#9C9C9C</color>
<dimen name="card_corner_radius">30dp</dimen>


2、新建圆角矩形 layout 布局文件


card_preference.xml card_preference_top.xml card_preference_middle.xml card_preference_bottom.xml

card_preference.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="20dp"
    android:layout_marginRight="20dp"
    android:background="@drawable/card_style"
    android:gravity="center_vertical"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:paddingEnd="?android:attr/scrollbarSize">
    <ImageView
        android:id="@android:id/icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="15dip"
        android:layout_marginTop="6dip"
        android:layout_marginEnd="6dip"
        android:layout_marginBottom="6dip"
        android:layout_weight="1">
        <TextView
            android:id="@android:id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal"
            android:singleLine="true" />
        <TextView
            android:id="@android:id/summary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@android:id/title"
            android:layout_alignStart="@android:id/title"
            android:maxLines="4"
            android:textColor="?android:attr/textColorSecondary" />
    </RelativeLayout>
    <!-- Preference should place its actual preference widget here. -->
    <LinearLayout
        android:id="@android:id/widget_frame"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:orientation="vertical" />
</LinearLayout>

其余布局文件copy card_preference.xml 修改 android:background="@drawable/card_style" 为对应 drawable 即可


3、主角登场 xml 目录下新建 grouppe.xml 文件


<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:targetpre="http://schemas.android.com/apk/res-auto"
    android:key="root">
    <PreferenceCategory
        android:key="fpc"
        android:title="first bold">
        <SwitchPreference
            android:defaultValue="true"
            android:key="pref_is_full_app"
            android:layout="@layout/card_preference"
            android:persistent="true"
            android:summary="is_full_app_desc"
            android:title="@string/app_name" />
        <Preference
            android:key="go_launcher"
            android:persistent="false"
            android:title="go_launcher_title">
            <intent
                android:targetClass="com.android.launcher3.Launcher"
                android:targetPackage="com.android.launcher3" />
        </Preference>
    </PreferenceCategory>
    <PreferenceCategory
        android:title=""
        targetpre:card_style="top">
        <Preference
            android:icon="@drawable/ic_sim"
            android:key="red"
            android:persistent="false"
            android:summary="CardPreferenceCategory"
            android:title="@string/app_name" />
    </PreferenceCategory>
    <PreferenceCategory>
        <Preference
            android:icon="@drawable/ic_sim"
            android:key="blue"
            android:layout="@layout/card_preference_top"
            android:persistent="false"
            android:summary="红"
            android:title="@string/app_name">
            <intent android:action="android.settings.DEVICE_INFO_SETTINGS" />
        </Preference>
        <Preference
            android:icon="@drawable/ic_sim"
                android:layout="@layout/card_preference_middle"
            android:persistent="false"
            android:summary="黄"
            android:title="@string/app_name">
            <intent android:action="android.settings.DEVICE_INFO_SETTINGS" />
        </Preference>
        <Preference
            android:icon="@drawable/ic_sim"
            android:layout="@layout/card_preference_bottom"
            android:persistent="false"
            android:summary="蓝"
            android:title="@string/app_name">
            <intent android:action="android.settings.DEVICE_INFO_SETTINGS" />
        </Preference>
    </PreferenceCategory>
    <!--for divide-->
    <Preference
        android:selectable="false"/>
    <SwitchPreference
        android:defaultValue="true"
        android:layout="@layout/card_preference"
        android:persistent="true"
        android:summary="just see color"
        android:title="@string/app_name" />
</PreferenceScreen>


4、新建 CardActivity.java 继承 PreferenceActivity, 加载 grouppe 布局


public class CardActivity extends PreferenceActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.grouppe);
    }
}


小技巧


为了让多个 Preference 子项紧邻形成一组,需要用 PreferenceCategory 包裹

为了让卡片和单个 Preference 之前增加空行间隔,可以使用空白的 Preference 并设置不可点击 android:selectable=“false”

目录
相关文章
|
6月前
|
XML 前端开发 Java
Android App开发图像加工中卡片视图CardView和给图像添加装饰的讲解以及实战(附源码 简单易懂)
Android App开发图像加工中卡片视图CardView和给图像添加装饰的讲解以及实战(附源码 简单易懂)
277 0
|
XML Android开发 数据格式
Android深度定制化TabLayout:圆角,渐变色,背景边框,圆角渐变下划线,基于Android原生TabLayout
Android深度定制化TabLayout:圆角,渐变色,背景边框,圆角渐变下划线,基于Android原生TabLayout 在附录1的基础上丰富自定义的TabLayout,这次增加两个内容:1, 当选中某一个切换卡时候,文本字体变粗。
6293 0
|
3月前
|
XML 前端开发 Android开发
Android经典实战之Kotlin中实现圆角图片和圆形图片
本文介绍两种实现圆角图像视图的方法。第一种是通过自定义Kotlin `AppCompatImageView`,重写`onDraw`方法使用`Canvas`和`Path`进行圆角剪裁。第二种利用Android Material库中的`ShapeableImageView`,简单配置即可实现圆角效果。两种方法均易于实现且提供动态调整圆角半径的功能。
73 0
|
5月前
|
开发工具 Android开发
Android 代码自定义drawble文件实现View圆角背景
Android 代码自定义drawble文件实现View圆角背景
189 0
|
Android开发
Android 设置图片的四个角 为圆角
Android 设置图片的四个角 为圆角
|
Android开发
Android Glide加载四周圆角图
Android Glide加载四周圆角图 需要引入:implementation 'jp.wasabeef:glide-transformations:3.
2720 0
|
Android开发
Android 实现圆角布局,变相实现圆角图片效果(不同位置不同弧度)
    小菜最近在处理图片的圆角,不止是四个角全是圆角,还包括单左侧/单右侧/对角线方向的圆角。因为自己太菜只能寻求网上的大神,发现一个自定义圆角布局,这样可以变相的解决我的需求,还可以实现更多的圆角效果,不仅是图片,还包括其他布局。
2278 0
|
XML Android开发 数据格式
Android深度定制化TabLayout:圆角,渐变色,背景边框,基于Android原生TabLayout
Android深度定制化TabLayout:圆角,渐变色,背景边框,基于Android原生TabLayout 如今UI设计已经不再满足于下方只有一个下划线,切换后能改变和表示选中颜色的TabLayout了。
3977 0
|
XML Android开发 数据格式
Android自定义ProgressBar样式:渐变圆角水平进度条
Android自定义ProgressBar样式:渐变圆角水平进度条 关键是android:progressDrawable的设置,设置一个android:progressDrawable资源,但是android:progressDrawable需要是一个layer-list。
4553 0
|
Android开发 数据格式 XML
Android水平渐变色圆角矩形
Android水平渐变色圆角矩形 一个Android水平渐变色圆角矩形,如图:其实实现很简单,主要感觉颜色渐变,圆角弧度比较漂亮,故记录下来。
1560 0