Android如何微信自定义分享按钮按钮效果

Android自定义开关按钮ToggleButton - 简书
Android自定义开关按钮ToggleButton
由于项目开发需要,所以做了一个自定义的开关按钮,样式类似于Android5.0中开关按钮,也有开启关闭的切换效果,在这里和大家分享一下,先看一下效果图如下:
togglebutton.gif
看过效果图以后我们废话不多说,直接来看一下实现代码。
这里主要是写了一个类去继承View,然后不断的对它进行重绘以显示出这种效果,该类ToggleButton.java的实现代码如下:
public class ToggleButton extends View implements View.OnClickListener{
private OnToggleC
private int onColor = Color.parseColor("#4ebb7f");
private int offColor = Color.parseColor("#dadbda");
private boolean toggleOn =
private int BTN_WIDTH = 40;// 宽度
private int BTN_HEIGHT = 30;// 高度
private int CIRCLE_RADIUS = 8;// 圆的半径
private int LINE_WIDTH = 2;// 直线高度
private int circleX;// 圆心X轴坐标
private boolean changeCompelete =
private TimerT
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == 1111) {
invalidate();
public ToggleButton(Context context) {
this(context, null, 0);
public ToggleButton(Context context, AttributeSet attrs) {
this(context, attrs, 0);
public ToggleButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
public int getOnColor() {
return onC
public void setOnColor(int onColor) {
this.onColor = onC
invalidate();
public int getOffColor() {
return offC
public void setOffColor(int offColor) {
this.offColor = offC
invalidate();
public boolean isToggleOn() {
return toggleOn;
public void setToggleOn(boolean toggleOn) {
this.toggleOn = toggleOn;
if (toggleOn) {
circleX = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, BTN_WIDTH - CIRCLE_RADIUS, r.getDisplayMetrics());
circleX = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CIRCLE_RADIUS, r.getDisplayMetrics());
invalidate();
private void doInit() {
r = Resources.getSystem();
setOnClickListener(this);
circleX = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, BTN_WIDTH - CIRCLE_RADIUS, r.getDisplayMetrics());
protected void onDraw(Canvas canvas) {
if (toggleOn) {
Paint linePaint = new Paint();
linePaint.setColor(onColor);
linePaint.setAntiAlias(true);
linePaint.setStyle(Style.FILL);
linePaint.setStrokeWidth(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, LINE_WIDTH, r.getDisplayMetrics()));
canvas.drawRect(0, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (BTN_HEIGHT - LINE_WIDTH) / 2, r.getDisplayMetrics()), TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, BTN_WIDTH, r.getDisplayMetrics()), TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (BTN_HEIGHT + LINE_WIDTH) / 2, r.getDisplayMetrics()), linePaint);
Paint circlePaint = new Paint();
circlePaint.setColor(onColor);
circlePaint.setAntiAlias(true);
canvas.drawCircle(circleX, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, BTN_HEIGHT / 2, r.getDisplayMetrics()),TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CIRCLE_RADIUS, r.getDisplayMetrics()), circlePaint);
Paint circlePaint = new Paint();
circlePaint.setColor(offColor);
circlePaint.setAntiAlias(true);
canvas.drawCircle(circleX,TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, BTN_HEIGHT / 2, r.getDisplayMetrics()),TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CIRCLE_RADIUS, r.getDisplayMetrics()), circlePaint);
Paint linePaint = new Paint();
linePaint.setColor(offColor);
linePaint.setAntiAlias(true);
linePaint.setStyle(Style.FILL);
linePaint.setStrokeWidth(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, LINE_WIDTH, r.getDisplayMetrics()));
canvas.drawRect(0, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (BTN_HEIGHT - LINE_WIDTH) / 2, r.getDisplayMetrics()),TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, BTN_WIDTH, r.getDisplayMetrics()), TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (BTN_HEIGHT + LINE_WIDTH) / 2, r.getDisplayMetrics()), linePaint);
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode == MeasureSpec.UNSPECIFIED || widthMode == MeasureSpec.AT_MOST{
widthSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, BTN_WIDTH, r.getDisplayMetrics());
widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
if (heightMode == MeasureSpec.UNSPECIFIED || heightMode == MeasureSpec.AT_MOST) {heightSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, BTN_HEIGHT,r.getDisplayMetrics());
heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
public void onClick(View v) {
if (changeCompelete) {
if (toggleOn) {
toggleOn =
toggleOn =
changeCompelete =
task = new TimerTask() {
public void run() {
if (toggleOn) {
circleX++;
circleX--;
handler.sendEmptyMessage(1111);
if (circleX == TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, BTN_WIDTH - CIRCLE_RADIUS, r.getDisplayMetrics()) || circleX ==TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CIRCLE_RADIUS, r.getDisplayMetrics())) {
changeCompelete =
timer.cancel();
timer = new Timer();
timer.schedule(task, 0, 2);
if (listener != null)
listener.onToggle(toggleOn);
public interface OnToggleChanged {
public void onToggle(boolean on);
public void setOnToggleChanged(OnToggleChanged onToggleChanged) {
listener = onToggleC
这是整个自定义开关按钮的全部代码,其实非常简单,我来给大家解释一下具体思路,首先我们规定好按钮的宽度和高度,也就是代码中BTN_WIDTH、BTN_HEIGHT这两个值,当然这两个值你可以设置成任意值,并不一定是和我一样,然后是圆的半径CIRCLE_RADIUS。整个按钮其实是通过画一个直线和圆组合而成,而圆心的X轴坐标在最左边就是CIRCLE_RADIUS,在最右边是BTN_WIDTH-CIRCLE_RADIUS。然后我们想实现一个开关变换的动态效果时就不断改变圆心的X轴坐标的位置并不断对圆进行重绘,从而造成这么一种假象,好像圆在不断的移动。在开关切换时我们变换画笔的颜色,这些颜色当然也可以任意设置,整个思路大致就是这样。下面我们来继续来对它进行使用,就和使用Android自带的控件一样进行使用。
布局文件activity_main.xml:
&?xml version="1.0" encoding="utf-8"?&
&RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"&
&me.my.togglebutton.ToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:id="@+id/toggle_button"/&
&/RelativeLayout&
主界面MainActivity.java:
public class MainActivity extends Activity{
private ToggleButton toggleB
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toggleButton = (ToggleButton) findViewById(R.id.toggle_button);
toggleButton.setOnToggleChanged(new ToggleButton.OnToggleChanged() {
public void onToggle(boolean on) {
Toast.makeText(getApplicationContext(), "是否开启" + on, Toast.LENGTH_SHORT).show();
运行之后效果如上图所示,到这里自定义开关按钮就介绍完了。下面为了使这个控件有更多效果设置的空间,我再来和大家谈谈如何为自定义控件设置自定义属性,就以本文中的这个控件为例,我们为其加上一些自定义属性。
自定义控件的自定义属性
添加自定义属性文件attrs.xml(该文件放在项目的values目录下):
&?xml version="1.0" encoding="utf-8"?&
&resources&
&declare-styleable name="ToggleButton"&
&attr name="onColor" format="color" /&
&attr name="offColor" format="color" /&
&attr name="btnWidth" format="integer" /&
&attr name="btnHeight" format="integer" /&
&attr name="circleRadius" format="integer" /&
&attr name="lineHeight" format="integer" /&
&/declare-styleable&
&/resources&
上述文件定义的自定义属性对应MainActivity.java中的如下几个变量:
private int onColor = Color.parseColor("#4ebb7f");// 开启颜色
private int offColor = Color.parseColor("#dadbda");// 关闭颜色
private int BTN_WIDTH = 40;// 宽度
private int BTN_HEIGHT = 30;// 高度
private int CIRCLE_RADIUS = 8;// 圆的半径
private int LINE_WIDTH = 2;// 直线高度
现在我们可以在布局文件中直接为自定义的开关控件设置这些属性,我就随便设置了一些值,更改后的布局文件activity_main.xml如下:
&?xml version="1.0" encoding="utf-8"?&
&RelativeLayout 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"&
&me.my.togglebutton.ToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
app:offColor="#ff0000"
app:onColor="#00ff00"
app:btnWidth="80"
app:btnHeight="60"
app:circleRadius="15"
app:lineHeight="4"
android:id="@+id/toggle_button"/&
&/RelativeLayout&
这里要注意在布局文件中加上:
xmlns:app="http://schemas.android.com/apk/res-auto"
加上了这一句代码才能使用自定义属性,并且为其命名为app,当然你也可以命名为其他的,然后就可以为自定义控件添加自定义属性了,你也可以为属性设置其他值。注意,虽然在布局文件中为控件设置了自定义属性,但这还不够,我门还需要在自定义控件的初始化中去获取这些值,所以我们更改上面的ToggleButton.java文件中的部分代码如下:
private void doInit(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ToggleButton, defStyleAttr, 0);
onColor = a.getColor(R.styleable.ToggleButton_onColor, Color.parseColor("#4ebb7f"));
offColor = a.getColor(R.styleable.ToggleButton_offColor, Color.parseColor("#dadbda"));
BTN_WIDTH = a.getInteger(R.styleable.ToggleButton_btnWidth, 40);
BTN_HEIGHT = a.getInteger(R.styleable.ToggleButton_btnHeight, 30);
CIRCLE_RADIUS = a.getInteger(R.styleable.ToggleButton_circleRadius, 8);
LINE_WIDTH = a.getInteger(R.styleable.ToggleButton_lineHeight, 2);
r = Resources.getSystem();
setOnClickListener(this);
circleX = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, BTN_WIDTH - CIRCLE_RADIUS, r.getDisplayMetrics());
这里只是在doInit()方法中加入了几句代码,然后为该方法加入相应参数就可以了,至此自定义属性的工作就完成了,然后运行一下,来看一下运行效果吧:
togglebutton2.gif
ok,到这里所以介绍就结束了,代码中可能有不足之处,欢迎大家批评指正,共同学习!
比没有技术深度更可怕的是不知道自己没有技术深度!
用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金Cover 有什么料? 从这篇文章中你能获得这些料: 知道setContentView()之后发生了什么? ... Android 获取 View 宽高的常用正确方式,避免为零 - 掘金相信有很多朋友...
内容抽屉菜单ListViewWebViewSwitchButton按钮点赞按钮进度条TabLayout图标下拉刷新ViewPager图表(Chart)菜单(Menu)浮动菜单对话框空白页滑动删除手势操作RecyclerViewCardColorDrawableSpinner...
用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你能获得这些料: 知道setContentView()之后发生了什么? ... Android 获取 View 宽高的常用正确方式,避免为零 - 掘金 相信有很多...
发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注
09:45字数 61697阅读 3316评论 2喜欢 85 用到的组件 1、通过CocoaPods安装 项目名称 项目信息 AFNetworking 网络请求组件 FM...
Android 从 0 开始自定义控件之 View 的 draw 过程 (九) - Android - 掘金转载请标明出处: http://blog.csdn.net/airsaid/article/details/ 本文出自:周游的博客 ... Andri...
如果这个世界真有奇迹,那也只是努力的另外一个名字。遇不到真爱,是因为你活得还不够漂亮,只有当你的脸能够闪烁出迷人的气场,你心灵的丰盈才能让身边的人感受到你的力量。
时光如梭,一转眼你长大成了一个男子汉,伴随着你的成长,我们有过辛苦,烦恼,但更多是感受了一家人在一起快乐和幸福。
儿子,你是爸爸的孩子,这种血缘关系是前世修来的,是上帝赐予的,爸爸非常珍爱,爸爸想做你坚实的后盾,更想做你的朋友,最知心最要好的朋友。
在朋友圈里发了一条公司的开工利是的图片,突然发现原来自己一直被“关心”着,楼下一堆人问多少钱,什么公司,在做什么的。我认为没有什么也就如实相告了。 没成想引发一场吐槽。 “哎哟,就这么点,你看看人家腾讯,几千几千的给” “哎哟,这什么公司啊,听都没听过” “哎哟,做这个不赚...
Description Given a sorted linked list, delete all duplicates such that each element appear only once. For example,Given 1-&1-&2, return ...没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!}

我要回帖

更多关于 android 自定义按钮 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信