Android自定义View实现带4圆角或者2圆角的效果

1 问题

实现任意view经过自定义带4圆角或者2圆角的效果

2 原理

1) 实现view 4圆角

我们只需要把左边的图嵌入到右边里面去,最终显示左边的图就行。

2) 实现view上2圆角

我们只需要把左边的图嵌入到右边里面去,最终显示左边的图就行。

安卓源码里面有这样的类

package android.graphics;

/**
 * <p>Specialized implementation of {@link Paint}'s
 * {@link Paint#setXfermode(Xfermode) transfer mode}. Refer to the
 * documentation of the {@link PorterDuff.Mode} enum for more
 * information on the available alpha compositing and blending modes.</p>
 *
 */
public class PorterDuffXfermode extends Xfermode {
 /**
  * Create an xfermode that uses the specified porter-duff mode.
  *
  * @param mode   The porter-duff mode that is applied
  */
 public PorterDuffXfermode(PorterDuff.Mode mode) {
  porterDuffMode = mode.nativeInt;
 }
}

然后我们看下点击mode进去看下

 /**
  * @hide
  */
 public static Mode intToMode(int val) {
  switch (val) {
   default:
   case 0: return Mode.CLEAR;
   case 1: return Mode.SRC;
   case 2: return Mode.DST;
   case 3: return Mode.SRC_OVER;
   case 4: return Mode.DST_OVER;
   case 5: return Mode.SRC_IN;
   case 6: return Mode.DST_IN;
   case 7: return Mode.SRC_OUT;
   case 8: return Mode.DST_OUT;
   case 9: return Mode.SRC_ATOP;
   case 10: return Mode.DST_ATOP;
   case 11: return Mode.XOR;
   case 16: return Mode.DARKEN;
   case 17: return Mode.LIGHTEN;
   case 13: return Mode.MULTIPLY;
   case 14: return Mode.SCREEN;
   case 12: return Mode.ADD;
   case 15: return Mode.OVERLAY;
  }
 }

什么意思呢?

应该可以看得懂,这里每个图片显示的效果是最终的效果,然后很明显,我们这里需要的是SrcIn效果,我们要把左图的效果嵌套到右图里面去。

3 代码实现

1)MyTextView.java文件如下

package com.onemt.sdk.circle;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.util.AttributeSet;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatTextView;

public class MyTextView extends AppCompatTextView {

 private final RectF roundRect = new RectF();
 private final Paint desPaint = new Paint();
 private final Paint srcPaint = new Paint();
 private float mRadius = 10;
 private boolean isChange = false;

 public MyTextView(@NonNull Context context) {
  super(context);
  init();
 }

 public MyTextView(@NonNull Context context, @Nullable AttributeSet attrs) {
  super(context, attrs);
  init();
 }

 public MyTextView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  init();
 }

 public void change(boolean isChange) {
  this.isChange = isChange;
  invalidate();
 }
 public void init() {
  desPaint.setAntiAlias(true);//设置抗锯齿
  desPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
  srcPaint.setAntiAlias(true);
  float density = getResources().getDisplayMetrics().density;
  mRadius *= density;
 }
 @Override
 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
  super.onLayout(changed, left, top, right, bottom);
  int width = getWidth();
  int height = getHeight();
  roundRect.set(0, 0, width, height);
 }

 @Override
 public void draw(Canvas canvas) {
  //保存最原始的roundRect
  canvas.saveLayer(roundRect, srcPaint, Canvas.ALL_SAVE_FLAG);
  if (isChange) {
   //保存去掉头部2圆角的roundRect(实际就是保留底部的2个圆角)
   canvas.drawRect(roundRect.left, (roundRect.top + roundRect.bottom) / 2, roundRect.right, roundRect.bottom, srcPaint);
   //保存去掉底部2圆角的roundRect(实际就是保留顶部的2个圆角)
//   canvas.drawRect(roundRect.left, roundRect.top, roundRect.right, roundRect.bottom / 2, srcPaint);
  }
  //保存掉头部2圆角的roundRect
  canvas.drawRoundRect(roundRect, mRadius, mRadius, srcPaint);
  //保存叠加后的内容
  canvas.saveLayer(roundRect, desPaint, Canvas.ALL_SAVE_FLAG);
  super.draw(canvas);
  //清空所有的图像矩阵修改状态
  canvas.restore();
 }

}

如果你看不懂这个函数drawRoundRect,请看下我的这篇博客介绍 Android之Canvas的drawRoundRect()

2)MainActivity.java文件如下

package com.onemt.sdk.circle;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

 public MyTextView myTextView;
 public boolean isChange = true;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  myTextView = findViewById(R.id.my_textview);
  myTextView.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    if (isChange) {
     myTextView.change(true);
     isChange = false;
    } else {
     myTextView.change(false);
     isChange = true;
    }
   }
  });
 }
}

3)activity_main.xml文件如下

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
 android:layout_height="match_parent"
 tools:context=".MainActivity">

 <com.onemt.sdk.circle.MyTextView
  android:id="@+id/my_textview"
  android:layout_width="100dp"
  android:layout_height="100dp"
  android:background="@color/colorAccent"
  app:layout_constraintBottom_toBottomOf="parent"
  app:layout_constraintLeft_toLeftOf="parent"
  app:layout_constraintRight_toRightOf="parent"
  app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

4 效果

初始进来如下效果,4圆角效果

然后我们点击图片切换效果如下,上2圆角效果

总结

到此这篇关于Android自定义View实现带4圆角或者2圆角的效果的文章就介绍到这了,更多相关android 自定义view 圆角内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android中Glide加载圆形图片和圆角图片实例代码

    一.简介: 介绍两种使用 BitmapTransformation 来实现 Glide 加载圆形图片和圆角图片的方法.Glide 并不能直接支持 Round Pictures ,需要使用 BitmapTransformation 来进行处理. 二.网上的实现方式 这里介绍下网上常见的方式和使用 RoundedBitmapDrawable 两种方法,本质上是差不多的: 使用 Canvas 和 Paint 来绘制 使用 Android.support.v4.graphics.drawable.Rou

  • Android开发使用自定义View将圆角矩形绘制在Canvas上的方法

    本文实例讲述了Android开发使用自定义View将圆角矩形绘制在Canvas上的方法.分享给大家供大家参考,具体如下: 前几天,公司一个项目中,头像图片需要添加圆角,这样UI效果会更好看,于是写了一个小的demo进行圆角的定义,该处主要是使用BitmapShader进行了渲染(如果要将一张图片裁剪成椭圆或圆形显示在屏幕上,也可以使用BitmapShader来完成). BitmapShader类完成渲染图片的基本步骤如下: 1.创建BitmapShader类的对象 /** * Call this

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

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

  • Android中快速便捷的实现圆角按钮方法详解

    前言 大家应该都知道,圆角按钮是我们在做界面时常常遇到的UI样式.通常的办法,是做一个drawable,比如这样: <?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <!-- 填充的颜色

  • Android自定义ViewGroup实现带箭头的圆角矩形菜单

    本文和大家一起做一个带箭头的圆角矩形菜单,大概长下面这个样子: 要求顶上的箭头要对准菜单锚点,菜单项按压反色,菜单背景色和按压色可配置. 最简单的做法就是让UX给个三角形的图片往上一贴,但是转念一想这样是不是太low了点,而且不同分辨率也不太好适配,干脆自定义一个ViewGroup吧! 自定义ViewGroup其实很简单,基本都是按一定的套路来的. 一.定义一个attrs.xml 就是声明一下你的这个自定义View有哪些可配置的属性,将来使用的时候可以自由配置.这里声明了7个属性,分别是:箭头宽

  • Android自定义view实现圆形、圆角和椭圆图片(BitmapShader图形渲染)

    一.前言 Android实现圆角矩形,圆形或者椭圆等图形,一般主要是个自定义View加上使用Xfermode实现的.实现圆角图片的方法其实不少,常见的就是利用Xfermode,Shader.本文直接继承ImageView,使用BitmapShader方法来实现圆形.圆角和椭圆的绘制,等大家看我本文的方法后,其他的类似形状也就都能举一反三来来画出来了. 二.效果图: 三.BitmapShader简介 BitmapShader是Shader的子类,可以通过Paint.setShader(Shader

  • Android自定义控件之圆形、圆角ImageView

    一.问题在哪里? 问题来源于app开发中一个很常见的场景--用户头像要展示成圆的:  二.怎么搞? 机智的我,第一想法就是,切一张中间圆形透明.四周与底色相同.尺寸与头像相同的蒙板图片,盖在头像上不就完事了嘛,哈哈哈! 在背景纯色的前提下,这的确能简单解决问题,但是如果背景没有这么简单呢? 在这种不规则背景下,有两个问题: 1).背景图常常是适应手机宽度缩放,而头像的尺寸又是固定宽高DP的,所以固定的蒙板图片是没法保证在不同机型上都和背景图案吻合的. 2).在这种非纯色背景下,哪天想调整一下头像

  • Android自定义View实现带4圆角或者2圆角的效果

    1 问题 实现任意view经过自定义带4圆角或者2圆角的效果 2 原理 1) 实现view 4圆角 我们只需要把左边的图嵌入到右边里面去,最终显示左边的图就行. 2) 实现view上2圆角 我们只需要把左边的图嵌入到右边里面去,最终显示左边的图就行. 安卓源码里面有这样的类 package android.graphics; /** * <p>Specialized implementation of {@link Paint}'s * {@link Paint#setXfermode(Xfe

  • Android自定义View实现带数字的进度条实例代码

    第一步.效果展示 图1.蓝色的进度条 图2.红色的进度条 图3.多条颜色不同的进度条 图4.多条颜色不同的进度条 第二步.自定义ProgressBar实现带数字的进度条 0.项目结构 如上图所示:library项目为自定义的带数字的进度条NumberProgressBar的具体实现,demo项目为示例项目以工程依赖的方式引用library项目,然后使用自定义的带数字的进度条NumberProgressBar来做展示 如上图所示:自定义的带数字的进度条的library项目的结构图 如上图所示:de

  • Android自定义View圆形和拖动圆、跟随手指拖动效果

    单纯的自定义一个圆非常简单 只需要几步就完成 拖动圆添加实现触摸事件即可 我在第一次自定义View圆遇到的几个Bug: 1.拖动圆的话在xml里面设置的自定义圆的宽和高是它能活动的空间的大小 不是圆控件的大小 如果你定义了100dp 拖动它的时候超过100dp这个距离这个圆就会看不见 就像下面这样 如果想活动于整个屏幕直接给宽和高match_parent属性就好了 2.我在定义充满属性match_parent的时候运行会报错,什么方法都用了就是不行,耐心等待过一会就好了-有可能是studio没来

  • Android自定义View控件实现多种水波纹涟漪扩散效果

    效果图 实现思路 这个效果实现起来并不难,重要的是思路 此View满足了多种水波纹涟漪扩散效果,这要求它能满足很多的变化 根据上面的样式,可以看出此View需要满足以下变化 圆圈从中心可循环向外扩散 圆圈之间的扩散间距可以改变 可控制扩散圆的渐变度 圆圈可以是线条样式或者实心样式 圆圈扩散的速度可以控制 适配圆圈不同大小下的扩散效果 具体实现 创建自定义属性 首先为View创建自定义的xml属性 在工程的values目录下新建attrs.xml文件 <declare-styleable name

  • Android自定义view系列之99.99%实现QQ侧滑删除效果实例代码详解

    首先声明本文是基于GitHub上"baoyongzhang"的SwipeMenuListView修改而来,该项目地址: https://github.com/baoyongzhang/SwipeMenuListView 可以说这个侧滑删除效果是我见过效果最好且比较灵活的项目,没有之一!!! 但是在使用它之前需要给大家提两点注意事项: 1,该项目支持Gradle dependence,但是目前作者提供的依赖地址对应的项目不是最新的项目,依赖过后的代码与demo中使用的不一致,会提示没有B

  • Android自定义View圆形和拖动圆跟随手指拖动

    单纯的自定义一个圆非常简单 只需要几步就完成 拖动圆添加实现触摸事件即可 我在第一次自定义View圆遇到的小问题: 1.拖动圆的话在xml里面设置的自定义圆的宽和高是它能活动的空间的大小 不是圆控件的大小 如果你定义了100dp 拖动它的时候超过100dp这个距离这个圆就会看不见 就像下面这样 如果想活动于整个屏幕直接给宽和高match_parent属性就好了 2.在布局里自定的view会提示编译 点击Build编译一下就好了 下面开始写代码: 先是单纯的创建一个圆形 创建一个类继承View 实

  • Android自定义View实现圆环带数字百分比进度条

    分享一个自己制作的Android自定义View.是一个圆环形状的反映真实进度的进度条,百分比的进度文字跟随已完成进度的圆弧转动.以下是效果图: 这个自定义View可以根据需要设定圆环的宽度和百分比文字的大小. 先说一下思路:这个View一共分为三部分:第一部分也就是灰色的圆环部分,代表未完成的进度:第二部分是蓝色的圆弧部分,代表已经完成的进度:第三部分是红色的百分比的数字百分比文本,显示当前确切的完成进度. 下面是View的编写思路: ①:定义三个画笔,分别画灰色圆环,蓝色圆弧,红色文字: ②:

  • Android自定义View实现分段选择按钮的实现代码

    首先演示下效果,分段选择按钮,支持点击和滑动切换. 视图绘制过程中,要执行onMeasure.onLayout.onDraw等方法,这也是自定义控件最常用到的几个方法. onMeasure:测量视图的大小,可以根据MeasureSpec的Mode确定父视图和子视图的大小. onLayout:确定视图的位置 onDraw:绘制视图 这里就不做过多的介绍,主要介绍本控件涉及的到的部分. 1.1 获取item大小.起始位置 @Override protected void onMeasure(int

  • Android自定义view实现阻尼效果的加载动画

    效果: 需要知识: 1. 二次贝塞尔曲线 2. 动画知识 3. 基础自定义view知识 先来解释下什么叫阻尼运动 阻尼振动是指,由于振动系统受到摩擦和介质阻力或其他能耗而使振幅随时间逐渐衰减的振动,又称减幅振动.衰减振动.[1] 不论是弹簧振子还是单摆由于外界的摩擦和介质阻力总是存在,在振动过程中要不断克服外界阻力做功,消耗能量,振幅就会逐渐减小,经过一段时间,振动就会完全停下来.这种振幅随时间减小的振动称为阻尼振动.因为振幅与振动的能量有关,阻尼振动也就是能量不断减少的振动.阻尼振动是非简谐运

  • Android 自定义View 密码框实例代码

    暴露您view中所有影响可见外观的属性或者行为. •通过XML添加和设置样式 •通过元素的属性来控制其外观和行为,支持和重要事件交流的事件监听器 详细步骤见:Android 自定义View步骤 效果图展示: 支持的样式 可以通过XML定义影响外边和行为的属性如下 边框圆角值,边框颜色,分割线颜色,边框宽度,密码长度,密码大小,密码颜色 <declare-styleable name="PasswordInputView"> <attr name="borde

随机推荐