android 自定义圆角button效果的实例代码(自定义view Demo)
作者:许佳佳233 发布时间:2022-07-13 11:35:09
标签:android,圆角,button
概述
在平时开发过程中经常会碰到需要使用圆角button的情况,一般也会包括很多其他小功能,比如要在里面添加img,设置不同的圆角大小等。
针对这样的场景,直接使用创建多个shape,定义多个xml文件也是可以实现的。但是如果使用非常频繁,那么直接自定义一个就会来的非常方便。
甚至在一些情况下,不是可以用shape定义的规则图形,比如需要用到贝塞尔曲线等。
如果全局需要这样风格的view,那么自定义一个View是非常必要的。
本文主要是个demo记录,如有需要的读者可以借鉴学习。
Demo
主要实现功能:
自定义圆角大小
支持设置leftDrawable,和自定义文字内容(文字和img默认居中)
支持点击效果
源码
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效果的实例代码网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
来源:https://blog.csdn.net/Double2hao/article/details/103705311


猜你喜欢
- SpringBoot集成Freemarker主要特征:静态页面,无接 * 互数据实时性不高且体量小的网站可采用生成静态html的形式数据提前渲
- 前言默认删除文件的时候 File.Delete 是将文件永久删除,如果是一些文档,建议删除到回收站,这样用户可以自己还原 通过 SHFile
- 本文实例汇总了C#常用GDI+文字操作,包含了文字的投影、倒影、旋转等常见的效果,在进行C#应用程序开发中有不错的实用价值。分享给大家供大家
- 概念Java中的集合就是一种容器,可以容纳不同种类的数据,这些容纳是建立在未知的基础上。优点1.可以动态保存任意多个对象,使用比较方便。2.
- 在实际项目开发过程中,我们经常需要对某个对象或者某个集合中的元素进行排序,常用的两种方式是实现某个接口。常见的可以实现比较功能的接口有Com
- 首先介绍一下Java解释器的概念,Java解释器:解释器是Java虚拟机非常重要的一部分,它的工作就是把字节码转化为机器码并在特定的平台进行
- 自定义控件在android中无处不见,自定义控件给了我们很大的方便。比如说,一个视图为imageview ,imagebutton ,tex
- 下面是 Java 线程相关的热门面试题,你可以用它来好好准备面试。1) 什么是线程?线程是操作系统能够进行运算调度的最小单位,它被包含在进程
- 一、问题说明偶然换了下spring boot的版本号,结果idea一直标红,报该父依赖一直找不到。但是当我查看引入的依赖时,版本号已经变成2
- Android 文件读写操作方法总结在Android中的文件放在不同位置,它们的读取方式也有一些不同。本文对android中对资源文件的读取
- 本文实例为大家分享了Java操作MongoDB模糊查询和分页查询,供大家参考,具体内容如下模糊查询条件:1、完全匹配Pattern patt
- 在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户
- 介绍在本文中,我们将了解如何将现有应用程序迁移到Spring 6以及如何充分利用此升级。本文中的提示基于我在Hypersistence Op
- 使用百度地图出现闪退一般情况下出现闪退是在AndroidManifest.xml文件中未在application标签中配置<meta-
- 我们通过项目的reimport等众多办法无法解决之后:假设这个是爆红的,因为被我已经解决了。我们进入到我们的本地仓库, 新建包。在repos
- 文章描述以下主要还是使用到了ffmpeg命令,分别实现了给视频添加图片水印以及文字水印。开发环境.NET Framework版本:4.5开发
- 前言每次update Maven Project 的时候,看着进度条寸步难行,心里憋得十分难受,明显阻碍我学习的热情。 maven仓库默认在
- 本文实例为大家分享了C#无损高质量压缩图片的具体代码,供大家参考,具体内容如下/// 无损压缩图片 /// <param
- 前言在使用easyExcel读取文件时,对于Excel的表头,在解析读取时分成不同的状态,需要加以区分.1 环境准备准备一个可以正常访问的S
- 这篇文章主要介绍了SpringMVC Mybatis配置多个数据源并切换代码详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一