仿iOS Segmented Control样式"
同步发表于http://avenwu.net/2015/02/05/styled_radiogroup_segmented_control
Fork on github https://github.com/avenwu/support
iOS中有一个Segmented Control组件,android中的RadioGroup与之类似,但是RadioGroup的默认样式不是很美观,但是只需要稍微调一下就可以长得和Segmented Control控件一样简洁优雅。
实现
直接写style文件当然是最快的,只需设置每个RadioButton的对其为居中,修改默认的android:button资源,然后加上背景、文字的selector。
<RadioGroup
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A"
android:id="@+id/radioButton"
style="@style/FlatRadioButtonStyle"
android:background="@drawable/flat_round_shape_left" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="B"
android:id="@+id/radioButton2"
android:checked="true"
style="@style/FlatRadioButtonStyle"
android:background="@drawable/flat_round_shape_middle" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="C"
android:id="@+id/radioButton3"
style="@style/FlatRadioButtonStyle"
android:background="@drawable/flat_round_shape_right" />
</RadioGroup>
style样式
<style name="FlatRadioButtonStyle">
<item name="android:layout_weight">1</item>
<item name="android:button">@null</item>
<item name="android:gravity">center</item>
<item name="android:textAppearance">?android:textAppearanceMedium</item>
<item name="android:textColor">@color/radio_button_color</item>
<item name="android:padding">5dp</item>
</style>
背景selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true">
<shape android:shape="rectangle">
<corners android:topLeftRadius="5dp" android:bottomLeftRadius="5dp" />
<solid android:color="@android:color/white" />
<stroke android:color="@android:color/white" android:width="1dp" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<corners android:topLeftRadius="5dp" android:bottomLeftRadius="5dp" />
<solid android:color="@android:color/transparent" />
<stroke android:color="@android:color/white" android:width="1dp" />
</shape>
</item>
</selector>
这些都没什么问题,但是比较零散,每次都需要写很多的xml及其样式,selector等,所以可以做一些简单的封装,暴露一些必要的属性用于自定义,比如边框线的宽度,背景色等。
简单封装
自定义RadioGroup,将必要的初始化配置在内部完成。
package net.avenwu.support.widget;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.StateListDrawable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import net.avenwu.support.R;
/**
* Created by chaobin on 2/4/15.
*/
public class FlatTabGroup extends RadioGroup {
public FlatTabGroup(Context context) {
this(context, null);
}
private int mRadius;
private int mStroke;
private int mHighlightColor;
private String[] mItemString;
private float mTextSize;
private ColorStateList mTextColor;
public FlatTabGroup(Context context, AttributeSet attrs) {
super(context, attrs);
setOrientation(HORIZONTAL);
setGravity(Gravity.CENTER_VERTICAL);
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.FlatTabGroup);
mHighlightColor = array.getColor(R.styleable.FlatTabGroup_tab_border_color, Color.WHITE);
mStroke = array.getDimensionPixelSize(R.styleable.FlatTabGroup_tab_border_width, 2);
mRadius = array.getDimensionPixelOffset(R.styleable.FlatTabGroup_tab_radius, 5);
mTextColor = array.getColorStateList(R.styleable.FlatTabGroup_tab_textColor);
mTextSize = array.getDimensionPixelSize(R.styleable.FlatTabGroup_tab_textSize, 14);
array.recycle();
int id = array.getResourceId(R.styleable.FlatTabGroup_tab_items, 0);
mItemString = isInEditMode() ? new String[]{"TAB A", "TAB B", "TAB C"} : context.getResources().getStringArray(id);
generateTabView(context, attrs);
updateChildBackground();
}
private void generateTabView(Context context, AttributeSet attrs) {
if (mItemString == null) {
return;
}
for (String text : mItemString) {
RadioButton button = new RadioButton(context, attrs);
button.setGravity(Gravity.CENTER);
button.setButtonDrawable(android.R.color.transparent);
button.setText(text);
button.setTextColor(mTextColor);
button.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
addView(button, new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 1));
}
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
updateChildBackground();
}
private void updateChildBackground() {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child instanceof RadioButton) {
child.setBackgroundDrawable(generateTabBackground(i, mHighlightColor));
}
}
}
private Drawable generateTabBackground(int position, int color) {
StateListDrawable stateListDrawable = new StateListDrawable();
stateListDrawable.addState(new int[]{android.R.attr.state_checked}, generateDrawable(position, color));
stateListDrawable.addState(new int[]{}, generateDrawable(position, Color.TRANSPARENT));
return stateListDrawable;
}
private Drawable generateDrawable(int position, int color) {
float[] radius;
if (position == 0) {
radius = new float[]{
mRadius, mRadius,
0, 0,
0, 0,
mRadius, mRadius
};
} else if (position == getChildCount() - 1) {
radius = new float[]{
0, 0,
mRadius, mRadius,
mRadius, mRadius,
0, 0
};
} else {
radius = new float[]{
0, 0,
0, 0,
0, 0,
0, 0
};
}
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadii(radius);
shape.setColor(color);
shape.setStroke(mStroke, mHighlightColor);
return shape;
}
}
属性
定义需要暴露给外面的属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="FlatTabGroup">
<attr name="tab_items" format="reference" />
<attr name="tab_border_width" format="dimension|reference" />
<attr name="tab_border_color" format="color|reference" />
<attr name="tab_radius" format="dimension|reference" />
<attr name="tab_textColor" format="dimension|reference" />
<attr name="tab_textSize" format="dimension|reference" />
</declare-styleable>
</resources>
现在需要写一个RadioGroup时只需要少量的的配置:
- app:tab_border_width="1dp" 边线宽度
- app:tab_border_color="@android:color/white" 边线颜色
- app:tab_items="@array/demo_array" tabs字符串数组
- app:tab_radius="5dp" 边框弧度
- app:tab_textSize="16sp" 文本字号
- app:tab_textColor="@color/radio_button_color_light_blue" 文本颜色selector
示例:
<net.avenwu.support.widget.FlatTabGroup
android:layout_width="match_parent"
android:layout_height="40dp"
app:tab_border_width="1dp"
app:tab_border_color="@android:color/white"
app:tab_items="@array/demo_array"
app:tab_radius="5dp"
app:tab_textSize="16sp"
app:tab_textColor="@color/radio_button_color_light_blue"
android:paddingTop="5dp"
android:paddingBottom="5dp" />
所以现在写RadioGroup就非常方便,只需要根据需求配置相应属性即可。比如实现文章开头的效果,可以这样:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/ll_container">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:orientation="vertical"
android:background="@android:color/holo_red_dark">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RadioGroup with custom style"
android:textColor="@android:color/white"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp" />
<RadioGroup
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A"
android:id="@+id/radioButton"
style="@style/FlatRadioButtonStyle"
android:background="@drawable/flat_round_shape_left" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="B"
android:id="@+id/radioButton2"
android:checked="true"
style="@style/FlatRadioButtonStyle"
android:background="@drawable/flat_round_shape_middle" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="C"
android:id="@+id/radioButton3"
style="@style/FlatRadioButtonStyle"
android:background="@drawable/flat_round_shape_right" />
</RadioGroup>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Custom FlatTabGroup extend RadioGroup"
android:textColor="@android:color/white"
android:layout_marginTop="10dp" />
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:background="@android:color/holo_red_dark">
<net.avenwu.support.widget.FlatTabGroup
android:layout_width="match_parent"
android:layout_height="40dp"
app:tab_border_width="1dp"
app:tab_border_color="@android:color/white"
app:tab_items="@array/demo_array"
app:tab_radius="5dp"
app:tab_textSize="16sp"
app:tab_textColor="@color/radio_button_color"
android:paddingTop="5dp"
android:paddingBottom="5dp" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:background="@color/tab_orange">
<net.avenwu.support.widget.FlatTabGroup
android:layout_width="match_parent"
android:layout_height="40dp"
app:tab_border_width="1dp"
app:tab_border_color="@android:color/white"
app:tab_items="@array/demo_array"
app:tab_radius="5dp"
app:tab_textSize="16sp"
app:tab_textColor="@color/radio_button_color_orange"
android:paddingTop="5dp"
android:paddingBottom="5dp" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:background="@color/tab_purple">
<net.avenwu.support.widget.FlatTabGroup
android:layout_width="match_parent"
android:layout_height="40dp"
app:tab_border_width="1dp"
app:tab_border_color="@android:color/white"
app:tab_items="@array/demo_array"
app:tab_radius="5dp"
app:tab_textSize="16sp"
app:tab_textColor="@color/radio_button_color_purple"
android:paddingTop="5dp"
android:paddingBottom="5dp" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:background="@color/tab_blue">
<net.avenwu.support.widget.FlatTabGroup
android:layout_width="match_parent"
android:layout_height="40dp"
app:tab_border_width="1dp"
app:tab_border_color="@android:color/white"
app:tab_items="@array/demo_array"
app:tab_radius="5dp"
app:tab_textSize="16sp"
app:tab_textColor="@color/radio_button_color_blue"
android:paddingTop="5dp"
android:paddingBottom="5dp" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:background="@color/tab_light_blue">
<net.avenwu.support.widget.FlatTabGroup
android:layout_width="match_parent"
android:layout_height="40dp"
app:tab_border_width="1dp"
app:tab_border_color="@android:color/white"
app:tab_items="@array/demo_array"
app:tab_radius="5dp"
app:tab_textSize="16sp"
app:tab_textColor="@color/radio_button_color_light_blue"
android:paddingTop="5dp"
android:paddingBottom="5dp" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:background="@color/tab_green">
<net.avenwu.support.widget.FlatTabGroup
android:layout_width="match_parent"
android:layout_height="40dp"
app:tab_border_width="1dp"
app:tab_border_color="@android:color/white"
app:tab_items="@array/demo_array"
app:tab_radius="5dp"
app:tab_textSize="16sp"
app:tab_textColor="@color/radio_button_color_green"
android:paddingTop="5dp"
android:paddingBottom="5dp" />
</FrameLayout>
</LinearLayout>
</ScrollView>
颜色selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/tab_light_blue" android:state_checked="true" />
<item android:color="@android:color/white" />
</selector>
tab数组
<string-array name="demo_array">
<item>A</item>
<item>B</item>
<item>C</item>
</string-array>
小结
完整代码可以再这里获取:
仿iOS Segmented Control样式"的更多相关文章
- CSS 仿 iOS 系统通知数字样式
/** 仿 iOS 系统通知数字样式 **/ .num_span{ background-color: #f00; background-image: -webkit-linear-gradient( ...
- iOS动画效果集合、 通过摄像头获取心率、仿淘宝滑动样式、瀑布流、分类切换布局等源码
iOS精选源码 动画知识运用及常见动画效果收集 较为美观的多级展开列表 MUImageCache -简单轻量的图片缓存方案 iOS 瀑布流之栅格布局 一用就上瘾的JXCategoryView iOS ...
- 从零开始学ios开发(六):IOS控件(3),Segmented Control、Switch
这次的学习还是基于上一个项目继续进行(你也可以新建一个项目)学习Segmented Control和Switch. Segmented Control Switch Segmented Control ...
- IOS学习之segmented control
转载请注明出处 http://blog.csdn.net/pony_maggie/article/details/27086877 作者:小马 什么是segmented control? 先上几张图: ...
- WPF C#仿ios 安卓 红点消息提示
原文:WPF C#仿ios 安卓 红点消息提示 先把效果贴出来,大家看看. 代码下载地址: http://download.csdn.net/detail/candyvoice/9730751 点击+ ...
- WPF 仿IPhone滑块开关 样式 - CheckBox
原文:WPF 仿IPhone滑块开关 样式 - CheckBox <Style x:Key="CheckRadioFocusVisual"> <Setter Pr ...
- android 仿ios 对话框已封装成工具类
对话框 在android中是一种非经常见的交互提示用户的方式,可是非常多产品狗都叫我们这些做android的仿ios,搞的我们android程序猿非常苦逼,凭什么效果老是仿ios,有没有一点情怀,只是 ...
- react-native自定义Modal模态框|仿ios、微信弹窗RN版
前序 纵观每个优质项目,无论web端还是native原生应用开发,弹窗都是不可忽视的一环,能很大程度上直接决定用户体验.如:微信.支付宝.ios都有很成熟的一套弹窗UI展示场景. 最近一直沉迷在rea ...
- div css仿京东订单流程图样式代码
效果展示 http://hovertree.com/texiao/css/25/ 本效果适合PC,也适合移动端 手机扫描二维码查看效果: 效果图: 代码如下: <!DOCTYPE html> ...
随机推荐
- nodejs:csv模块解析
Nodejs最大的特点就是基于事件驱动和异步并发操作.大多数人知道nodejs是用于网络后台服务的新平台,可以很方便的提供后台服务:除了用于网络开发外,其实nodejs对于线下文件并发处理也是很方便的 ...
- ubuntu 14.04下 horizon openstack_dashboard 的开发环境搭建
序:公司要在openstack的基础上,做开发做产品,网上资料也不是很多,很多都是在来回copy,在此做个blog,慢慢更新,推动自己进步. 首先老话题:开发环境的搭建. 一个纯净的ubunt ...
- (转) 在C#用HttpWebRequest中发送GET/HTTP/HTTPS请求
转自:http://blog.csdn.net/zhoufoxcn/article/details/6404236 通用辅助类 下面是我编写的一个辅助类,在这个类中采用了HttpWebRequest中 ...
- javaweb 乱码---汉字存入mysql数据库中变成乱码
今天郁闷了一天,java程序在向mysql插入数据前不是乱码,数据库安装时也选了编码为utf8(和我程序的编码格式一致).可是插入数据就变成乱码,相当郁闷. 原因:mysql的配置文件中的编码并没有改 ...
- Linux Kernel 3.11 正式版发布
Linus 发布 了 3.11 版本的 Linux 内核.该版本值得关注的新特性有: Lustre 分布式文件系统.透明的 ARM 架构的大数据页支持:ARM64 上的 Xen 和 KVM 虚拟化:O ...
- elixir 高可用系列(五) Supervisor
概述 OTP 平台的容错性高,是因为它提供了机制来监控所有 processes 的状态,如果有进程出现异常, 不仅可以及时检测到错误,还可以对 processes 进行重启等操作. 有了 superv ...
- solr与.net系列课程(五)solrnet的使用
solr与.net系列课程(五)solrnet的使用 最近因项目比较忙,所以这篇文章出的比较晚,离上一篇文章已经有半个月的时间了,这节课我们来学下一下solr的.net客户端solrnet 出处 ...
- ASP.NET Web API从注释生成帮助文档
默认情况下,ASP.NET Web API不从Controller的注释中生成帮助文档.如果要将注释作为Web API帮助文档的一部分,比如在帮助文档的Description栏目中显示方法注释中的su ...
- [51单片机] SPI nRF24L01无线 [可以放在2个单片机里实现通信]
main.c #include<reg51.h> #include"2401.h" #define uint unsigned int #define uchar un ...
- Django站点管理--ModelAdmin
class AuthorAdmin(admin.ModelAdmin): list_display=('name', 'age', 'sex') #指定要显示的字段 search_fields=('n ...