使用画布的橡皮擦效果

2023-12-30

我有一个扩展视图的自定义视图类。我正在使用重写的 onDraw 方法在画布上涂鸦。我有一个 POJO 列表,其中包括 Path 和 Paint,借助它们我可以重新创建绘制的旧路径,如下所示:

@Override
protected void onDraw(Canvas canvas){
for (POJO pojo : pojoList {
  canvas.drawPath(pojo.path, pojo.paint);
}
canvas.drawPath(path, paint);
}

我想实现擦除功能,它应该像正确的擦除一样工作。我知道一种方法可以写入位图并使用 setXfermode 来 CLEAR ,这样可以正常工作。但像素化在较小分辨率的设备上看起来不太好。我不想使用白色油漆,因为在这个视图下面我有一个 ImageView,所以将其涂成白色也会影响 ImageView。 任何解决此问题的想法或片段都受到高度赞赏。


这很好用。如果有人找到更好的解决方案。请更新

private Context mContext;
private ArrayList<Draw> mDrawList;
private Paint mPaint;
private Path mPath;
private boolean isErase;
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;

public EraseDoodleView(Context context) {
    super(context);
    init(context);
}

public EraseDoodleView(Context context, AttributeSet attributeSet) {
    super(context, attributeSet);
    init(context);
}

private void init(Context context) {
    mContext = context;
    mDrawList = new ArrayList<Draw>();
    mPath = new Path();
    setupPaint();
    setLayerType(View.LAYER_TYPE_HARDWARE, mPaint);
}

private void setupPaint() {
    mPaint = new Paint();
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setFilterBitmap(true);
    mPaint.setAntiAlias(true);
    mPaint.setStrokeWidth(4);
    mPaint.setColor(ContextCompat.getColor(mContext, android.R.color.black));
    if (isErase) {
        mPaint.setXfermode(new PorterDuffXfermode(
                PorterDuff.Mode.CLEAR));
        mPaint.setStrokeWidth(16);
    }
}

public void setErase(boolean isErase) {
    this.isErase = isErase;
    setupPaint();
}

public boolean getErase() {
    return this.isErase;
}

@Override
protected void onDraw(Canvas canvas) {
    for (Draw draw : mDrawList) {
        canvas.drawPath(draw.path, draw.paint);
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {

    float x = event.getX();
    float y = event.getY();

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            touchStart(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_MOVE:
            touchMove(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            touchUp();
            invalidate();
            break;
    }
    return true;
}

private void touchStart(float x, float y) {
    mPath.reset();
    mPath.moveTo(x, y);
    mDrawList.add(new Draw(mPath, mPaint));
    mX = x;
    mY = y;
}
private void touchMove(float x, float y) {
    float dx = Math.abs(x - mX);
    float dy = Math.abs(y - mY);
    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
        mX = x;
        mY = y;
    }
}

private void touchUp() {
    mPath.lineTo(mX, mY);
    mPath = new Path();
}


class Draw {
    Path path;
    Paint paint;

    public Draw(Path path, Paint paint) {
        this.paint = paint;
        this.path = path;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用画布的橡皮擦效果 的相关文章

  • Android 手机作为 GSM 调制解调器在 PC 上发送/接收短信?

    是否可以将 Android 移动设备用作 PC 上的 GSM 调制解调器 我正在 net下开发应用程序来发送 接收短信等 现在我想通过 USB 将我的 Android 设备连接到我的 PC 并将其用作 GSM 调制解调器来与其通信 这里是参
  • 当 OnFocusChangeListener 应用于包装的 EditText 时,TextInputLayout 没有动画

    不能比标题说得更清楚了 我有一个由文本输入布局包裹的 EditText 我试图在 EditText 失去焦点时触发一个事件 但是 一旦应用了事件侦听器 TextInputLayout 就不再对文本进行动画处理 它只是位于 editText
  • tomcat 中受密码保护的应用程序

    我正在使用 JSP Servlet 开发一个Web应用程序 并且我使用了Tomcat 7 0 33 as a web container 所以我的要求是tomcat中的每个应用程序都会password像受保护的manager applica
  • 如何对不同的参数类型使用相同的java方法?

    我的问题 我有 2 个已定义的记录 创建对象请求 更新对象请求 必须通过实用方法进行验证 由于这两个对象具有相同的字段 因此可以对这两种类型应用相同的验证方法 现在我只是使用两种方法进行重载 但它很冗长 public record Crea
  • Android - AudioRecord类不读取数据,audioData和fftArray返回零

    我是 Android 新手 一直在开发音调分析器应用程序 最低 SDK 8 我读了很多关于如何实现 Audiorecord 类的文章 但我想知道为什么它在我录制时不读取任何数据 我尝试显示 audioData 和 fftArray 的值 但
  • okhttp 获取失败响应

    我已经在我的 android 客户端中实现了 okhttp 来进行网络调用 当我收到失败响应时 我会收到失败代码以及与该代码相关的文本作为消息 但我没有收到服务器发送给我的自定义失败响应 在我实施的代码中的失败响应中 我收到的消息只是 错误
  • 获取文件的总大小(以字节为单位)[重复]

    这个问题在这里已经有答案了 可能的重复 java 高效获取文件大小 https stackoverflow com questions 116574 java get file size efficiently 我有一个名为 filenam
  • 为什么 Java 8 不允许非公共默认方法?

    让我们举个例子 public interface Testerface default public String example return Hello public class Tester implements Testerface
  • Eclipse 选项卡宽度不变

    我浏览了一些与此相关的帖子 但它们似乎并不能帮助我解决我的问题 我有一个项目 其中 java 文件以 2 个空格的宽度缩进 我想将所有内容更改为 4 空格宽度 我尝试了 正确的缩进 选项 但当我将几行修改为 4 空格缩进时 它只是将所有内容
  • 使用 AsyncTask 传递值

    我一直在努力解决这个问题 但我已经到了不知道该怎么办的地步 我想做的是使用一个类下载文件并将其解析为字符串 然后将该字符串发送到另一个类来解析 JSON 内容 所有部件都可以单独工作 并且我已经单独测试了所有部件 我只是不知道如何将值发送到
  • Cucumber 0.4.3 (cuke4duke) 与 java + maven gem 问题

    我最近开始为 Cucumber 安装一个示例项目 并尝试使用 maven java 运行它 我遵循了这个指南 http www goodercode com wp using cucumber tests with maven and ja
  • Android:无法使用 DbHelper 和 Contract 类将数据插入 SQLite

    public class Main2Activity extends AppCompatActivity private EditText editText1 editText2 editText3 editText4 private Bu
  • Python GTK+ 画布

    我目前正在通过 PyGobject 学习 GTK 需要画布之类的东西 我已经搜索了文档 发现两个小部件似乎可以完成这项工作 GtkDrawingArea 和 GtkLayout 我需要一些基本函数 如 fillrect 或 drawline
  • 在命令行上卸载 Android SDK 的选定部分

    这与 卸载旧的 Android SDK 版本 https stackoverflow com questions 15182377 uninstall old android sdk versions 除非我想在无头 Linux CI 服务
  • 通过系统应用程序以编程方式静默安装 apk(无需 root)

    我有带有 android sharedUserId android uid system UID 1000 的系统级应用程序 设备未root INSTALL PACKAGES 权限包含在清单中 我可以静默安装下载的 apk 吗 我已经发现这
  • 如何使用mockito模拟构建器

    我有一个建造者 class Builder private String name private String address public Builder setName String name this name name retur
  • 如何使用 AccessibilityService 在 Android 中模拟按键

    我正在编写一个辅助服务 我一直在尝试在应用程序上进行一些自动搜索 我使用accessibilityservice action paste来填充EditText 然后我需要模拟软键盘上的按键 但我不知道如何做 你们能帮我一下吗 你可以尝试A
  • 我的应用程序中的后退按钮出现问题[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我想在手机关闭时清除共享首选项值 你
  • 双枢轴快速排序和快速排序有什么区别?

    我以前从未见过双枢轴快速排序 是快速排序的升级版吗 双枢轴快速排序和快速排序有什么区别 我在 Java 文档中找到了这个 排序算法是双枢轴快速排序 作者 弗拉基米尔 雅罗斯拉夫斯基 乔恩 本特利和约书亚 布洛赫 这个算法 在许多数据集上提供
  • 有没有任何代码可以在android中设置壁纸而无需裁剪和缩放?

    我正在创建一个画廊应用程序 我的第一个应用程序 这是我的代码 Bitmap bmd BitmapFactory decodeStream is try getApplicationContext setWallpaper bmd catch

随机推荐

  • jQuery Mobile:获取上一页的 ID

    我基本上需要一个自定义函数 仅在例如从主页单击 reviews 页面时使用 这是我当前使用的代码 document bind mobileinit function reviews live pagebeforeshow function
  • phpmyadmin 导出不带 DATABASE_NAME 或算法的视图

    当使用 phpmyadmin 导出 sql 转储时 它会创建如下所示的 VIEW 表 CREATE ALGORITHM UNDEFINED DEFINER root localhost SQL SECURITY DEFINER VIEW d
  • 使用 git,如何将一些未提交的更改从一个分支移动到不同文件夹中的另一个分支?

    我每天使用的同一个软件有两个不同的分支 然而 每次我检查另一个分支时 我的构建过程可能需要长达一个小时 为了解决这个问题 我刚刚在两个单独的文件夹中为每个分支检查了一次项目 我在一个分支中做了一些工作 并在提交之前意识到我位于错误的文件夹中
  • CodeIgniter 中分页的自动加载配置不起作用

    我正在尝试在我的 CI web 应用程序中实现分页 现在我将分页配置放入这样的配置文件中
  • 使用 VB.NET 执行存储过程

    这是我的程序 ALTER PROCEDURE sp addUser UserName nvarchar 50 Prenom nvarchar 50 Nom nvarchar 50 Mail nvarchar 50 Password char
  • “静态合成”是什么意思?

    我正在查看一些从 Java 字节码获得的反汇编代码 我看到一些声明如下 method static synthetic access 0 Lcom package Sample 我不明白是什么synthetic or access 0意思是
  • SQL Server 上的 Int PK 内连接与 Guid PK 内连接。执行计划

    我刚刚对 Int PK join 与 Guid PK 进行了一些测试 表结构和记录数如下所示 在这两种情况下 使用 EF4 进行 CRUD 操作的性能非常相似 众所周知 在连接中使用 Int PK 比字符串具有更好的性能 所以SQL Ser
  • 将 Service Worker 请求中的响应修改为图像

    您好 提前谢谢您 我的问题是关于使用响应网络请求服务工作者 我能够在文本或 html 的情况下处理它 但是当我尝试处理image我失败了 这是我的代码 self addEventListener fetch function event e
  • 本地主机上的 Firebase console.log?

    拿起去年春天我离开的 Firebase 项目 我不记得是怎么做的console log工作在firebase server 我有一个函数 有效 我尝试在其中编写一些调试信息 像这样 exports myfun functions https
  • 获取对象调用层次结构

    假设我有 3 个课程 class A void do A Check object call hierarchy class B void do B A a a do A class C void do C B b b do A 然后我打电
  • Facebook iOS SDK 3.2.1 - [NSError fberrorShouldNotifyUser]:无法识别的选择器发送到实例

    我刚刚将我的应用程序从 Facebook iOS SDK 3 1 升级到 3 2 1 并且我正在尝试利用 NSError 上的新 FBError 类别提供的新错误处理 代码在底部 它编译得很好 但是当发生 FB 错误时 我在运行时得到以下信
  • R从字符串中提取数字

    字符串将是 042 195 143 192 001 145 045 125 125 如何提取最后一组数字 195 192 145 125 125 Try v1 lt c 042 195 143 192 001 145 045 125 125
  • Arduino 上的 Timer1 导致串行打印无法工作

    运行下面的代码 当我从串行监视器向 Arduino 发送任何字符时 Arduino 不会打印 a 我认为timer1代码有问题 但它应该可以工作 因为这段代码是我的C课老师给我的 void setup Serial begin 115200
  • 在 Parquet 中使用嵌套数据类型有什么好处?

    在 Parquet 文件格式中使用嵌套数据类型是否会带来任何性能优势 AFAIK Parquet 文件通常是专门为查询服务创建的 例如Athena 因此创建这些值的过程也可以简单地展平这些值 从而允许更轻松的查询 更简单的模式并保留每列的列
  • 带 proguard 的 Kotlin AAR 库:如何仅保留类和方法名称?

    我正在使用 Kotlin 构建一个 android 库 aar 文件 我需要以第三方用户将看到类和方法名称的方式混淆代码 他必须能够使用它们 它们是公开的 但我需要隐藏 混淆代码本身 我尝试将此文件用于 myLibrary proguard
  • C++ 中的模块是什么?

    该术语是什么意思module在下面的句子中引用 不允许异常跨模块边界传播 这是规则 62C 编码标准 http www gotw ca publications c cs htm作者 赫伯 萨特和安德烈 亚历山德雷斯库 我现在已经阅读了这本
  • 想要 javax.swing 钩子告诉我层次结构中的哪个组件正在执行操作

    如何通过最少的代码丑化在 Swing 程序中编写一个调试挂钩 告诉我层次结构中的哪个组件实际上正在处理每个 KeyStroke 或鼠标单击 并执行在组件的操作映射中映射到它的操作 我们正在编写一个复杂的 GUI 了解这些信息将非常有用 放入
  • 如何在谷歌地图中放置两个距离500m的标记

    我们如何将两个标记放置在 500 米的距离处 假设第一个标记的 latLng 是伦敦 51 0 第二个标记放置在距离该标记 500 米的地方 我已经尝试过任何事情 但无法找到并回答它 任何想法 纬度为 60 海里 但显然经度超出了这个范围
  • WPF DataGrid 组样式

    I have the following DataGrid in WPF with two groups First group is a bool flag which represents if a person is active i
  • 使用画布的橡皮擦效果

    我有一个扩展视图的自定义视图类 我正在使用重写的 onDraw 方法在画布上涂鸦 我有一个 POJO 列表 其中包括 Path 和 Paint 借助它们我可以重新创建绘制的旧路径 如下所示 Override protected void o