Android自定RadioGroup实现点击切换效果

2023-05-16



  

一:.java文件  


  

public class SegmentedGroup extends RadioGroup {

    private int mMarginDp;
    private Resources resources;
    private int mTintColor;
    private int mCheckedTextColor = Color.WHITE;
    private LayoutSelector mLayoutSelector;
    private Float mCornerRadius;

    public SegmentedGroup(Context context) {
        super(context);
        resources = getResources();
        mTintColor = resources.getColor(R.color.radio_button_selected_color);
        mMarginDp = (int) getResources().getDimension(R.dimen.radio_button_stroke_border);
        mCornerRadius = getResources().getDimension(R.dimen.radio_button_conner_radius);
        mLayoutSelector = new LayoutSelector(mCornerRadius);
    }

    /* Reads the attributes from the layout */
    private void initAttrs(AttributeSet attrs) {
        TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.SegmentedGroup,
                0, 0);

        try {
            mMarginDp = (int) typedArray.getDimension(
                    R.styleable.SegmentedGroup_sc_border_width,
                    getResources().getDimension(R.dimen.radio_button_stroke_border));

            mCornerRadius = typedArray.getDimension(
                    R.styleable.SegmentedGroup_sc_corner_radius,
                    getResources().getDimension(R.dimen.radio_button_conner_radius));

            mTintColor = typedArray.getColor(
                    R.styleable.SegmentedGroup_sc_tint_color,
                    getResources().getColor(R.color.radio_button_selected_color));

            mCheckedTextColor = typedArray.getColor(
                    R.styleable.SegmentedGroup_sc_checked_text_color,
                    getResources().getColor(android.R.color.white));

        } finally {
            typedArray.recycle();
        }
    }

    public SegmentedGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
        resources = getResources();
        mTintColor = resources.getColor(R.color.radio_button_selected_color);
        mMarginDp = (int) getResources().getDimension(R.dimen.radio_button_stroke_border);
        mCornerRadius = getResources().getDimension(R.dimen.radio_button_conner_radius);
        initAttrs(attrs);
        mLayoutSelector = new LayoutSelector(mCornerRadius);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        //Use holo light for default
        updateBackground();
    }

    public void setTintColor(int tintColor) {
        mTintColor = tintColor;
        updateBackground();
    }

    public void setTintColor(int tintColor, int checkedTextColor) {
        mTintColor = tintColor;
        mCheckedTextColor = checkedTextColor;
        updateBackground();
    }

    public void updateBackground() {
        int count = super.getChildCount();
        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            updateBackground(child);

            // If this is the last view, don't set LayoutParams
            if (i == count - 1) break;

            LayoutParams initParams = (LayoutParams) child.getLayoutParams();
            LayoutParams params = new LayoutParams(initParams.width, initParams.height, initParams.weight);
            // Check orientation for proper margins
            if (getOrientation() == LinearLayout.HORIZONTAL) {
                params.setMargins(0, 0, -mMarginDp, 0);
            } else {
                params.setMargins(0, 0, 0, -mMarginDp);
            }
            child.setLayoutParams(params);
        }
    }

    @SuppressLint("NewApi") private void updateBackground(View view) {
        int checked = mLayoutSelector.getSelected();
        int unchecked = mLayoutSelector.getUnselected();
        //Set text color
        ColorStateList colorStateList = new ColorStateList(new int[][]{
                {android.R.attr.state_pressed},
                {-android.R.attr.state_pressed, -android.R.attr.state_checked},
                {-android.R.attr.state_pressed, android.R.attr.state_checked}},
                new int[]{Color.GRAY, mTintColor, mCheckedTextColor});
        ((Button) view).setTextColor(colorStateList);

        //Redraw with tint color
        Drawable checkedDrawable = resources.getDrawable(checked).mutate();
        Drawable uncheckedDrawable = resources.getDrawable(unchecked).mutate();
        ((GradientDrawable) checkedDrawable).setColor(mTintColor);
        ((GradientDrawable) checkedDrawable).setStroke(mMarginDp, mTintColor);
        ((GradientDrawable) uncheckedDrawable).setStroke(mMarginDp, mTintColor);
        //Set proper radius
        ((GradientDrawable) checkedDrawable).setCornerRadii(mLayoutSelector.getChildRadii(view));
        ((GradientDrawable) uncheckedDrawable).setCornerRadii(mLayoutSelector.getChildRadii(view));

        //Create drawable
        StateListDrawable stateListDrawable = new StateListDrawable();
        stateListDrawable.addState(new int[]{-android.R.attr.state_checked}, uncheckedDrawable);
        stateListDrawable.addState(new int[]{android.R.attr.state_checked}, checkedDrawable);

        //Set button background
        if (Build.VERSION.SDK_INT >= 16) {
            view.setBackground(stateListDrawable);
        } else {
            view.setBackgroundDrawable(stateListDrawable);
        }
    }

    /*
     * This class is used to provide the proper layout based on the view.
     * Also provides the proper radius for corners.
     * The layout is the same for each selected left/top middle or right/bottom button.
     * float tables for setting the radius via Gradient.setCornerRadii are used instead
     * of multiple xml drawables.
     */
    private class LayoutSelector {

        private int children;
        private int child;
        private final int SELECTED_LAYOUT = R.drawable.radio_checked;
        private final int UNSELECTED_LAYOUT = R.drawable.radio_unchecked;

        private float r;    //this is the radios read by attributes or xml dimens
        private final float r1 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP
                , 0.1f, getResources().getDisplayMetrics());    //0.1 dp to px
        private final float[] rLeft;    // left radio button
        private final float[] rRight;   // right radio button
        private final float[] rMiddle;  // middle radio button
        private final float[] rDefault; // default radio button
        private final float[] rTop;     // top radio button
        private final float[] rBot;     // bot radio button
        private float[] radii;          // result radii float table

        public LayoutSelector(float cornerRadius) {
            children = -1; // Init this to force setChildRadii() to enter for the first time.
            child = -1; // Init this to force setChildRadii() to enter for the first time
            r = cornerRadius;
            rLeft = new float[]{r, r, r1, r1, r1, r1, r, r};
            rRight = new float[]{r1, r1, r, r, r, r, r1, r1};
            rMiddle = new float[]{r1, r1, r1, r1, r1, r1, r1, r1};
            rDefault = new float[]{r, r, r, r, r, r, r, r};
            rTop = new float[]{r, r, r, r, r1, r1, r1, r1};
            rBot = new float[]{r1, r1, r1, r1, r, r, r, r};
        }

        private int getChildren() {
            return SegmentedGroup.this.getChildCount();
        }

        private int getChildIndex(View view) {
            return SegmentedGroup.this.indexOfChild(view);
        }

        private void setChildRadii(int newChildren, int newChild) {

            // If same values are passed, just return. No need to update anything
            if (children == newChildren && child == newChild)
                return;

            // Set the new values
            children = newChildren;
            child = newChild;

            // if there is only one child provide the default radio button
            if (children == 1) {
                radii = rDefault;
            } else if (child == 0) { //left or top
                radii = (getOrientation() == LinearLayout.HORIZONTAL) ? rLeft : rTop;
            } else if (child == children - 1) {  //right or bottom
                radii = (getOrientation() == LinearLayout.HORIZONTAL) ? rRight : rBot;
            } else {  //middle
                radii = rMiddle;
            }
        }

        /* Returns the selected layout id based on view */
        public int getSelected() {
            return SELECTED_LAYOUT;
        }

        /* Returns the unselected layout id based on view */
        public int getUnselected() {
            return UNSELECTED_LAYOUT;
        }

        /* Returns the radii float table based on view for Gradient.setRadii()*/
        public float[] getChildRadii(View view) {
            int newChildren = getChildren();
            int newChild = getChildIndex(view);
            setChildRadii(newChildren, newChild);
            return radii;
        }
    }
}
二:Drawable配置资源

(1)button_text_color.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true" android:color="#DDd4d4d4"/>
    <item android:state_checked="false" android:state_pressed="false" android:color="@color/radio_button_selected_color"/>
    <item android:state_checked="true" android:state_pressed="false" android:color="#fff2f2f2"/>

</selector>



(2)radio_checked.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:padding="10dp"
    android:shape="rectangle">
    <!-- you can use any color you want I used here gray color-->
    <solid android:color="@color/radio_button_selected_color" />
    <stroke
        android:width="@dimen/radio_button_stroke_border"
        android:color="@color/radio_button_selected_color" />
</shape>


(3)radio_unchecked.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle"
    android:padding="10dp">
    <!-- you can use any color you want I used here gray color-->
    <solid android:color="@color/radio_button_unselected_color" />
    <stroke
        android:width="@dimen/radio_button_stroke_border"
        android:color="@color/radio_button_selected_color" />
</shape>


三:attrs配置资源

<?xml version="1.0" encoding="utf-8"?>
<resources>
     
    <declare-styleable name="SegmentedGroup">
        <attr name="sc_corner_radius" format="dimension" />
        <attr name="sc_border_width" format="dimension" />
        <attr name="sc_tint_color" format="color" />
        <attr name="sc_checked_text_color" format="color" />
    </declare-styleable>

</resources>


四:colors配置资源
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>

     
    <color name="radio_button_selected_color">#ff33b5e5</color>
    <color name="radio_button_unselected_color">@android:color/transparent</color>

</resources>




五:dimens配置资源
<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>

    <!--自定义控件SegmentetGroup-->
    <dimen name="radio_button_conner_radius">5dp</dimen>
    <dimen name="radio_button_stroke_border">1dp</dimen>

</resources>


六:styles配置资源
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <!-- 自定义RadioButton -->
    <style name="RadioButton">
        <item name="android:textColor">@drawable/button_text_color</item>
        <item name="android:minHeight">33dp</item>
        <item name="android:minWidth">70dp</item>
        <item name="android:gravity">center</item>
        <item name="android:button">@null</item>
        <item name="android:paddingLeft">5dp</item>
        <item name="android:paddingRight">5dp</item>
    </style>

</resources> 


七:使用布局文件
<com.toocms.switchbutton1.SegmentedGroup
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:layout_centerInParent="true"
    android:paddingTop="10dp"
    android:paddingBottom="10dp"
    android:fadingEdge="none">

    <RadioButton
        android:id="@+id/circle_search"
        style="@style/RadioButton"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:checked="true"
        android:gravity="center"
        android:text="发现" />

    <RadioButton
        android:id="@+id/circle_attention"
        style="@style/RadioButton"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:text="关注" />
</com.toocms.switchbutton1.SegmentedGroup>

八:截图

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android自定RadioGroup实现点击切换效果 的相关文章

  • WIN10自带远程桌面实现多用户登录

    一台主机当两台用 xff0c 利用WIN10自带远程桌面实现多用户登录 2020 04 27 10 51 24 54点赞 311收藏 35评论 先来说说家里电脑和网络的基本情况 新房装修时就考虑到家庭多媒体和自己变态的各种网络需求 xff0
  • 搭建FTP服务器,设置用户权限775 ,并只许上传、禁止下载和删除

    1 安装vsftpd软件包 xff0c 命令如下 xff1a sudo yum y install vsftpd 2 查看vsftpd的运行状态 xff0c 命令如下 xff1a sudo netstat nltp grep 21 一般情况
  • Android webrtc使用USB摄像头

    在疫情爆发的2020年 公司的Android项目要求支持外置摄像头 即要求支持USB摄像头 一脸懵逼的我从来没听过Android设备能支持USB摄像头的 只知道Android大机器能接外置的摄像头 但插口是接在Android机器上的前置和后
  • python中pip更新失败:Requirement already up-to-date: ... (19.0.3)

    坑述 装一个包说我的pip版本太低 pip 9 0 1 需要升级到19 0 3 运行 xff1a pip install upgrade pip You are using pip version 9 0 1 however version
  • LDAP入门使用

    LDAP介绍 一个为查询 浏览和搜索而优化的专业分布式数据库 xff0c 它呈树状结构组织数据 xff0c 和关系数据库不同 xff0c 它有优异的读性能 xff0c 但写性能差 xff0c 并且没有事务处理 回滚等复杂功能 xff0c 不
  • windows server 2012r2 开启远程桌面各种问题汇总

    Windows server 2012r2开启远程桌面比较麻烦 xff0c 因为毕竟是服务器 xff0c 更注重安全性 问题一 xff1a 如下图所示 xff0c 未开启相关权限 解决问题一 xff1a 先进行系统高级设置 xff0c 允许
  • java多线程入门例子-第一例

    认识多线程 1 span class hljs keyword public span span class hljs class span class hljs keyword class span span class hljs tit
  • npm无法使用npm版本过低无法升级npm版本与node版本不匹配npm WARN npm npm does not support Node.js vx.x.x

    npm WARN npm npm does not support Node js vx x x npm WARN npm You should probably upgrade to a newer version of node as
  • python 微信自动回复机器人

    python 微信自动回复机器人 导入wxauto https github com cluic wxauto span class token comment python3 span span class token comment c
  • 一篇文章讲清楚Gradle与Gradle Wrapper的区别

    Gradle xff1a android用来构建项目的编程框架 这个玩意对于使用AS开发的 xff0c 大家都清楚 xff0c 用这个来构建项目变得无比轻松和高可定制性 xff0c 比如引入第三方依赖 xff0c 发布到maven库 xff
  • 【Linux】运行yum时报错ModuleNotFoundError: No module named ‘dnf‘

    根因 xff1a 当前使用的python环境下没有yum依赖的dnf等包 解决方案 xff1a 确认当前使用的python环境下是否没有dnf包 xff1a 查看当前使用的python版本 xff0c 以及位置 xff1a 在site pa
  • POI导入Excel,获取公式的值

    直接POI导入Excel中的数据的时候 xff0c 直接获取表中的值 xff0c 如果表中单元格的值时由公式计算得出的话 xff0c 获取到的会是公式 所以需要对获取的单元格的值进行处理 xff1a 导入数字时 导入公式的计算结果而非公式
  • navicate连接远程数据库

    远程主机的3306端口一般是不允许外网直接访问的 xff0c 但是开发过程中 xff0c 使用navicate工具进行数据库操作会方便超级多 xff0c 那么要怎么配置navicate连接远程数据库呢 超简单两步走 xff1a 1 使用se
  • idea中Gradle项目控制台中文乱码

    我使用的是IEDA2021 xff0c 之前跑maven项目一切正常 今天导入了一个Gradle项目 xff0c debug的时候控制台中文乱码了 之前直接用idea控制台中文乱码做关键词搜索 xff0c 改了file settings e
  • @RequestMapping value值置为““

    我们通常用 64 RequestMapping来映射请求 xff0c 比如 xff0c 写一个方法 xff1a span class token annotation punctuation 64 RequestMapping span s
  • 三十分钟做一个网页游戏

    本文目的是短时间之内 xff0c 通过做出一个简单的缘分对对碰游戏 xff0c 了解网页的基本要素 之前没有接触过网页开发 xff0c 这次算是个入门了 对于大部分网页 xff0c 都要包括HTML CSS JavaScript三种技术 而
  • 软件安装时窗口出现在屏幕左上角而且拖不出来

    今天在安装MYSQL是出现如下问题 xff1a 安装助手出现在屏幕左上角而且拖不出来 xff0c 导致安装没办法完成 用一个很简单的方法解决了问题 xff1a 桌面空白处右键 xff0c 点屏幕分辨率 把方向改成纵向 xff0c 左上角的窗
  • DELL笔记本插入耳机没反应

    新入的戴尔燃7000 xff0c 上午因为CPU占用飙升 xff0c 关掉了笔记本上的几个自启动项 xff0c 下午插入耳机就无响应了 xff0c 耳机插进去 xff0c 还是外放 百度原因 xff0c 很多都提及了Realtek这一声卡驱
  • the server responded with a status of 404 (Not Found)

    使用ajax跳转方法时 xff0c 页面ctrl 43 shift 43 i调试报告了一个404错误 xff0c 说找不到方法 页面地址栏直接指向方法的地址跳转也是404 目标方法是新增的 xff0c 于是使用复制黏贴 xff0c 确定各处
  • select设置只读

    根据需求 xff0c 需要根据后台传来的参数 xff0c 动态设置select标签是否可以选择 xff0c 因此 xff0c 当判断某个select应当设为只读时 xff0c 使用 span class hljs variable span

随机推荐

  • java:程序包XXXX不存在

    使用idea导入maven项目 xff0c 编译时报错 xff1a java 程序包XXXX不存在 如图 xff1a 百度到的诸如右键libraries所在文件夹 xff0c 选择add to libraries 等方法没有作用 后来去查看
  • tomcat启动报错:java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.Lifec

    tomcat启动报错 xff1a java lang IllegalStateException ContainerBase addChild start org apache catalina Lifec 百度的结果一般都是让修改web
  • UE4 音乐的播放与停止--基于蓝图

    要实现的功能非常简单 xff1a 点击按钮 xff0c 播放音乐 这个功能非常基础 xff0c 就两步 xff1a 1 将音乐源文件拖到context文件夹中 注意 xff0c 这里的音乐文件必须是 wav格式的 2 在按钮的onclick
  • UnityEditor.BuildPlayerWindow+BuildMethodException

    unity3D安卓打包报错 xff1a UnityEditor BuildPlayerWindow 43 BuildMethodException 61 errors at UnityEditor BuildPlayerWindow 43
  • Spark常用API<Scala>

    概览 1 转换 2 动作1 Transformation 1 1一个RDD进行转换操作1 2 两个RDD的转换操作1 3对一个Pair RDD进行转化操作1 4对两个PairRDD进行转换操作2 Action 2 1对一个RDD进行行动操作
  • 关于特定网页打不开问题的解决

    如果有一些特定的网站打不开 排除被屏蔽的可能性的话 xff0c 试着把DNS设置成了自动获取ip试试看 我就这样子解决了打不开学校官网的问题
  • 渲染业务领域全景图

    最近图形学应用领域愈发广泛 xff0c 根据我的理解 xff0c 制作了一张渲染相关业务全景图 xff0c 希望对大家的职业规划有一定帮助
  • AI 入门怎么学?这份学习指南请收好!

    万事开头难 xff01 AI 入门对很多初学 AI 的同学来说是一大难题 搜集了一大堆入门资料 xff0c Python 数学 深度学习应有尽有 xff0c 但就是无从下手 xff0c 总是在第一章与放弃之间徘徊 那么 xff0c AI 应
  • FTP如何设置用户名密码

    1 新建FTP站点 xff0c 指定名称和物理路径 2 身份验证 选择 基本 xff0c 允许访问 选择 指定用户 xff0c 下面文本框中输入 本地用户和组 中现有的一个用户名即可 注意 xff1a 只能是 本地用户和组 中的用户 xff
  • Android布局 -- Navigation实现底部导航栏

    底部导航栏加页卡的切换 xff0c 很多App采用这种布局设计 xff0c 在以前的开发中 xff0c 需要自定义底部导航栏以及使用FragmentTransaction来管理Fragment的切换 xff0c 代码量较大 xff0c 而使
  • ViewModelProviders is deprecated

    原有的创建ViewModel的方法 xff1a viewModel 61 ViewModelProviders of this get ViewModel class 提示ViewModelProviders过时 改为 xff1a view
  • Android Fragment退出 返回上一个Fragment与直接退出

    例如应用底部有两个导航按钮A与B xff0c 刚进入的时候显示为第一个AFragment xff0c 点击B切换到BFragment 如果需求是在BFragment点击返回键回到AFragment xff0c 需要配置 app defaul
  • Android基础 -- 子线程可以修改UI吗?

    子线程可以修改UI吗 xff1f 为什么会产生这样的问题 xff0c 可能是因为在开发过程中遇到了 34 Only the original thread that created a view hierarchy can touch it
  • leetcode 417. 太平洋大西洋水流问题

    https leetcode cn com problems pacific atlantic water flow 思路是从海洋开始逆流 如果可以逆流到 就标记为1 然后检查两个海洋都可以逆流到的区域 DFS public List lt
  • Android模拟器检测常用方法

    在Android开发过程中 xff0c 防作弊一直是老生常谈的问题 xff0c 而模拟器的检测往往是防作弊中的重要一环 xff0c 接下来有关于模拟器的检测方法 xff0c 和大家进行一个简单的分享 1 传统的检测方法 传统的检测方法主要是
  • RecyclerView 隐藏部分分割线

    在项目中遇到复杂点的RecyclerView xff0c 可能会有隐藏部分分割线的需求 xff0c 例如item1和item3之间的分割线隐藏 xff0c item4和item5之间的分割线隐藏等 在看了文档里的ItemDecoration
  • 浅谈去中心化应用

    1 中心化应用 现在我们所使用的应用基本上都是中心化的应用 xff0c 什么是中心化应用呢 xff0c 举个栗子 xff0c 我们在天猫买东西的时候 xff0c 需要先付款给支付宝 xff0c 然后卖家发货 xff0c 我们确认收货之后 x
  • EGL综述

    参考 xff1a https www khronos org registry EGL specs eglspec 1 5 pdf 什么是EGL EGL是支持多平台 多操作系统的 xff0c 比如安卓 Unix Windows等 为了扩展性
  • Java二分搜索树及其添加删除遍历

    对于树这种结构 xff0c 相信大家一定耳熟能详 xff0c 二叉树 二分搜索树 AVL树 红黑树 线段树 Trie等等 xff0c 但是对于树的应用以及编写一棵解决特定问题的树 xff0c 不少同学都会觉得不是一件简单的事情 xff0c
  • Android自定RadioGroup实现点击切换效果

    一 xff1a java文件 public class SegmentedGroup extends RadioGroup private int mMarginDp private Resources resources private