android 自定义圆角button效果的实例代码(自定义view Demo)

概述

在平时开发过程中经常会碰到需要使用圆角button的情况,一般也会包括很多其他小功能,比如要在里面添加img,设置不同的圆角大小等。

针对这样的场景,直接使用创建多个shape,定义多个xml文件也是可以实现的。但是如果使用非常频繁,那么直接自定义一个就会来的非常方便。

甚至在一些情况下,不是可以用shape定义的规则图形,比如需要用到贝塞尔曲线等。
如果全局需要这样风格的view,那么自定义一个View是非常必要的。

本文主要是个demo记录,如有需要的读者可以借鉴学习。

Demo

主要实现功能:

  1. 自定义圆角大小
  2. 支持设置leftDrawable,和自定义文字内容(文字和img默认居中)
  3. 支持点击效果

源码

RoundRadiusButton.java

/**
 * author: xujiajia
 * description:
 * 1、drawable只有在设置textString的时候才会生效(居中效果两个一起测量)
 */
public class RoundRadiusButton extends View {
 //data
 private int width = 0;
 private int height = 0;
 private int roundRadius = 16;
 private int bgColor = Color.LTGRAY;
 private boolean isTouching = false;
 //img and text
 private Drawable leftDrawable = null;
 private int drawableWidth = 20;
 private int drawableHeight = 20;
 private int leftDrawablePaddingRight = 0;
 private String textString;
 private int textSize = 30;
 private int textColor = Color.BLACK;
 //onDraw
 Paint paint;
 Path path;
 RectF rectF;
 Rect rect;
 public RoundRadiusButton(Context context, int width, int height) {
 super(context);
 this.width = width;
 this.height = height;
 this.setLayoutParams(new ViewGroup.LayoutParams(width, height));
 this.setClickable(true);
 }
 public RoundRadiusButton(Context context, AttributeSet attrs) {
 super(context, attrs);
 getDataFromAttrs(context, attrs);
 this.setClickable(true);
 }
 public RoundRadiusButton(Context context, AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 getDataFromAttrs(context, attrs);
 this.setClickable(true);
 }
 private void getDataFromAttrs(Context context, AttributeSet attrs) {
 if (attrs == null) {
 return;
 }
 TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.RoundRadiusButton);
 roundRadius = ta.getDimensionPixelOffset(R.styleable.RoundRadiusButton_roundRadius, 16);
 bgColor = ta.getColor(R.styleable.RoundRadiusButton_bgColor, Color.LTGRAY);
 leftDrawable = ta.getDrawable(R.styleable.RoundRadiusButton_leftDrawable);
 drawableWidth = ta.getDimensionPixelOffset(R.styleable.RoundRadiusButton_drawableWidth, 0);
 drawableHeight = ta.getDimensionPixelOffset(R.styleable.RoundRadiusButton_drawableHeight, 0);
 leftDrawablePaddingRight =
 ta.getDimensionPixelOffset(R.styleable.RoundRadiusButton_leftDrawablePaddingRight, 0);
 textString = ta.getString(R.styleable.RoundRadiusButton_textString);
 textSize = ta.getDimensionPixelOffset(R.styleable.RoundRadiusButton_textSize, 0);
 textColor = ta.getColor(R.styleable.RoundRadiusButton_textColor, Color.BLACK);
 ta.recycle();
 }
 public void setRoundRadius(int roundRadius) {
 this.roundRadius = roundRadius;
 invalidate();
 }
 public void setBgColor(int bgColor) {
 this.bgColor = bgColor;
 invalidate();
 }
 public void setLeftDrawable(Drawable leftDrawable, int drawableWidth, int drawableHeight,
 int paddingRight) {
 this.leftDrawable = leftDrawable;
 this.drawableWidth = drawableWidth;
 this.drawableHeight = drawableHeight;
 this.leftDrawablePaddingRight = paddingRight;
 invalidate();
 }
 public void setTextString(String textString) {
 this.textString = textString;
 invalidate();
 }
 public void setTextColor(int textColor) {
 this.textColor = textColor;
 invalidate();
 }
 public void setTextSize(int textSize) {
 this.textSize = textSize;
 invalidate();
 }
 @Override public boolean onTouchEvent(MotionEvent event) {
 if (isClickable()) {
 switch (event.getAction()) {
 case MotionEvent.ACTION_DOWN:
  isTouching = true;
  invalidate();
  break;
 case MotionEvent.ACTION_UP:
  isTouching = false;
  invalidate();
  break;
 }
 }
 return super.onTouchEvent(event);
 }
 @Override protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 if (width == 0 || height == 0) {
 width = getWidth();
 height = getHeight();
 }
 if (paint == null) {
 paint = new Paint();
 }
 if (path == null) {
 path = new Path();
 }
 if (rectF == null) {
 rectF = new RectF();
 }
 if (rect == null) {
 rect = new Rect();
 }
 paint.setColor(bgColor);
 paint.setAntiAlias(true);//抗锯齿
 paint.setStrokeWidth(0);//线的宽度设为0,避免画圆弧的时候部分圆弧与边界相切
 paint.setStyle(Paint.Style.FILL_AND_STROKE);
 path.setFillType(Path.FillType.WINDING);
 //左上圆角
 path.moveTo(0, roundRadius);
 rectF.set(0, 0, 2 * roundRadius,
 2 * roundRadius);
 path.addArc(rectF, 180, 90);
 //上边
 path.lineTo(width - roundRadius, 0);
 //右上圆角
 rectF.set(width - roundRadius * 2, 0, width, roundRadius * 2);
 path.addArc(rectF, -90, 90);
 //右边
 path.lineTo(width, height - roundRadius);
 //右下圆角
 rectF.set(width - roundRadius * 2, height - roundRadius * 2, width,
 height);
 path.addArc(rectF, 0, 90);
 //下边
 path.lineTo(roundRadius, height);
 //左下圆角
 rectF.set(0, height - roundRadius * 2, 2 * roundRadius,
 height);
 path.addArc(rectF, 90, 90);
 //左边
 path.lineTo(0, roundRadius);
 path.close();
 canvas.drawPath(path, paint);
 if (isTouching) {
 paint.setColor(getContext().getResources().getColor(R.color.black_tran_30));
 canvas.drawPath(path, paint);
 }
 //填充背景中间空白的部分
 path.moveTo(0, roundRadius);
 path.lineTo(width - roundRadius, 0);
 path.lineTo(width, height - roundRadius);
 path.lineTo(roundRadius, height);
 path.close();
 canvas.drawPath(path, paint);
 if (isTouching) {
 paint.setColor(getContext().getResources().getColor(R.color.black_tran_30));
 canvas.drawPath(path, paint);
 }
 //text, drawable两个一起计算位置
 if (!TextUtils.isEmpty(textString)) {
 paint.setStrokeWidth(1.5f);
 paint.setColor(textColor);
 paint.setTextSize(textSize);
 rect.setEmpty();
 paint.getTextBounds(textString, 0, textString.length(), rect);
 float leftBitmap = 0;
 float topBitmap = 0;
 if (leftDrawable != null) {
 if (leftDrawable != null) {
  leftBitmap = (1.0f * width - drawableWidth - rect.width() - leftDrawablePaddingRight) / 2;
  topBitmap = (1.0f * height - drawableHeight) / 2;
  leftDrawable.setBounds((int) leftBitmap, (int) topBitmap,
  (int) (leftBitmap + drawableWidth),
  (int) (topBitmap + drawableHeight));
  leftDrawable.draw(canvas);
 }
 }
 float textX = 0;
 float textY =
  1.0f * height / 2 + paint.getTextSize() / 2 - paint.getFontMetrics().descent / 2;
 if (leftBitmap == 0 && topBitmap == 0) {
 textX = width / 2 - rect.width() / 2;
 } else {
 textX = leftBitmap + drawableWidth + leftDrawablePaddingRight;
 }
 canvas.drawText(textString, textX, textY, paint);
 }
 }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {
 private LinearLayout llContainer;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 initView();
 }
 private void initView() {
 llContainer = findViewById(R.id.ll_container);
 RoundRadiusButton roundRadiusButton = new RoundRadiusButton(this, 500, 200);
 roundRadiusButton.setBgColor(Color.LTGRAY);
 roundRadiusButton.setRoundRadius(40);
 //text
 roundRadiusButton.setTextString("testtesttest");
 roundRadiusButton.setTextColor(Color.WHITE);
 roundRadiusButton.setTextSize(40);
 //drawable
 roundRadiusButton.setLeftDrawable(getResources().getDrawable(R.mipmap.ic_launcher), 60, 60, 80);
 roundRadiusButton.setOnClickListener(new View.OnClickListener() {
 @Override public void onClick(View v) {
 Toast.makeText(MainActivity.this, "testest", Toast.LENGTH_LONG).show();
 }
 });
 roundRadiusButton.setClickable(false);
 llContainer.addView(roundRadiusButton);
 }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="@+id/ll_container"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="#868684"
 android:gravity="center"
 android:orientation="vertical"
 tools:context=".MainActivity"
 >
 <com.example.newbuttiontest.RoundRadiusButton
 android:layout_width="300dp"
 android:layout_height="200dp"
 app:bgColor="#FFEB3B"
 app:drawableHeight="18dp"
 app:drawableWidth="18dp"
 app:leftDrawable="@mipmap/ic_launcher"
 app:leftDrawablePaddingRight="5dp"
 app:roundRadius="30dp"
 app:textColor="#FF4329"
 app:textSize="16dip"
 app:textString="testtesttest"
 />
</LinearLayout>

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <declare-styleable name="RoundRadiusButton">
 <attr name="roundRadius" format="dimension" />
 <attr name="bgColor" format="color" />
 <attr name="leftDrawable" format="reference" />
 <attr name="leftDrawablePaddingRight" format="dimension" />
 <attr name="drawableWidth" format="dimension" />
 <attr name="drawableHeight" format="dimension" />
 <attr name="textString" format="string" />
 <attr name="textSize" format="dimension" />
 <attr name="textColor" format="color" />
 </declare-styleable>
</resources>

colors.xml

<resources>
 <color name="black_tran_30">#30000000</color>
</resources>

总结

以上所述是小编给大家介绍的android 自定义圆角button效果的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • Android实现圆角Button按钮

    本文实例讲述了Android开发圆角Button按钮实现过程,分享给大家供大家参考,具体内容如下 需求及效果图: 实现思路: 1.shape实现圆角 在drawable新建两个xml 文件, 这两个 xml文件用shape 实现了圆角效果. Note: 因为要让用户有按下去的效果体验, 所有要有两套圆角图, 在按下去时候切换 <!-- res/drawable/button_shape_normal.xml --> <shape xmlns:android="http://sc

  • android 自定义圆角button效果的实例代码(自定义view Demo)

    概述 在平时开发过程中经常会碰到需要使用圆角button的情况,一般也会包括很多其他小功能,比如要在里面添加img,设置不同的圆角大小等. 针对这样的场景,直接使用创建多个shape,定义多个xml文件也是可以实现的.但是如果使用非常频繁,那么直接自定义一个就会来的非常方便. 甚至在一些情况下,不是可以用shape定义的规则图形,比如需要用到贝塞尔曲线等. 如果全局需要这样风格的view,那么自定义一个View是非常必要的. 本文主要是个demo记录,如有需要的读者可以借鉴学习. Demo 主要

  • Vue自定义加水波纹效果指令实例代码

    目录 前言 自定义指令 指令的作用 水波纹 水波纹效果 实现 原理 核心 代码实现 总结 前言 大家好,我是不吃鱼d猫,过年以来.断更许久,又回来了,学无止境,作为程序员知识是要不断更新迭代的.在此期间,接触了几天的Vue,确实好用,今天给大家说个好玩的,在做项目过程中,点击按钮,大家肯定会接触过很花的效果.接下来给大家说说水波纹效果. 自定义指令 指令的作用 言简意赅,就是操作底层dom 当然vue自身有非常强大的指令功能,代替你进行dom操作,比如v-on绑定事件对不对,这应该大家熟悉的指令

  • android GridView多选效果的实例代码

    具体代码如下: main.xml 复制代码 代码如下: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:background="#000000" android:layout_width="fill_parent"

  • Android仿IOS上拉下拉弹性效果的实例代码

    用过iphone的朋友相信都体验过页面上拉下拉有一个弹性的效果,使用起来用户体验很好:Android并没有给我们封装这样一个效果,我们来看下在Android里如何实现这个效果.先看效果,感觉有些时候还是蛮实用的. 思路:其实原理很简单,实现一个自定义的Scrollview方法(来自网上大神),然后在布局文件中使用自定义方法Scrollview就可以了. 代码: 自定义View,继承自Scrollview.MyReboundScrollView类 package com.wj.myrebounds

  • Android实现空心圆角矩形按钮的实例代码

    页面上有时会用到背景为空心圆角矩形的Button,可以通过xml绘制出来. drawrable文件夹下bg_red_hollow_rectangle.xml <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle&qu

  • Android自定义水波纹动画Layout实例代码

    话不多说,我们先来看看效果: Hi前辈搜索预览 这一张是<Hi前辈>的搜索预览图,你可以在这里下载这个APP查看更多效果: http://www.wandoujia.com/apps/com.superlity.hiqianbei LSearchView 这是一个MD风格的搜索框,集成了ripple动画以及search时的loading,使用很简单,如果你也需要这样的搜索控件不妨来试试:https://github.com/onlynight/LSearchView RippleEverywh

  • Android 中TabLayout自定义选择背景滑块的实例代码

    TabLayout是Android 的Material Design包中的一个控件,可以和V4包中的ViewPager搭配产生一个联动的效果.这里我自定义了一个滑块能够跟随TabLayout进行滑动选择的SliderLayout.效果见下图(白色方框): 下面是SliderLayout的源码: import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawabl

  • Android TV开发:实现3D仿Gallery效果的实例代码

    本文讲述了Android TV开发:实现3D仿Gallery效果的实例代码.分享给大家供大家参考,具体如下: 1.实现效果: 滚动翻页+ 页面点击+页码指示器+焦点控制 2.实现这个效果之前必须要了解 Android高级图片滚动控件实现3D版图片轮播器这篇文章,我是基于他的代码进行修改的,主要为了移植到电视上做了按键事件和焦点控制. 3.具体代码: public class Image3DSwitchView extends LinearLayout { private int currentP

  • Android实现随意拖动View效果的实例代码

    项目过程中要实现能在页面中随意的拖动,刚开始实现是用悬浮球的形式进行实现,因为之前项目中用过,实现后发现用户每次安装后,都有权限的限制,甚至有些用户关闭悬浮球权限之后,不知道怎么在手机上打开悬浮球的权限,这样的话用户体验很不好,所以自己重新自定义实现在页面中拖动,不需要请求权限. 自定义随意拖动View: package com.dragdemo; import android.annotation.SuppressLint; import android.content.Context; im

  • Android中View跟随手指滑动效果的实例代码

    本文讲述了Android中View跟随手指滑动效果的实例代码.分享给大家供大家参考,具体如下: 1.android View 主要6种滑动方法,分别是 layout() offsetLeftAndRight()和offsetTopAndBottom() LayoutParams scrollBy()和 scrollTo() Scroller 动画 2.实现效果图 3.自定义中使用layout()方法实习view的滑动 public class MoveView extends View { pr

随机推荐