android如何自定义圆角button效果
创始人
2024-12-23 22:02:06
0次

主要实现功能:

  1. 自定义圆角大小  支持设置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

 

attrs.xml

           

colors.xml

 #30000000

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...