草庐IT

android - Canvas Eraser 正在绘制一条黑线

coder 2023-11-26 原文

我用谷歌搜索了这个问题并提出了各种解决方案。
但是,没有一个对我有用。

我在应用程序中有一个绘图 Canvas 。
在使用自定义 View (drawView)的Activity中将canvas的背景设置为png图片;

Bundle extras = intent.getExtras();
    if (extras != null) {
        if (extras.containsKey("background")) {

            //set the background to the resource in the extras
            int imageResource = intent.getIntExtra("background",-1);
            Drawable image = getResources().getDrawable(imageResource);
            drawView.setBackground(image);
        }
    }

在 DrawingView 类(drawview 是实例)中,我将绘制的路径存储在 PathPaint 的集合中,该集合具有 3 个属性(路径、使用的油漆以及是否为橡皮擦);

private ArrayList<PathPaint> paths = new ArrayList<PathPaint>();

然后我尝试在 OnDraw 中循环遍历这些路径,并每次使用绘制它们时所用的颜料(多种颜色)重新绘制它们;

protected void onDraw(Canvas canvas) {

    //if the drawing is new - dont draw any paths
    if (isNew != true) {

        //go through every previous path and draw them
        for (PathPaint p : paths) {

            if (!p.isErase)
            {
                canvas.drawPath(p.myPath, p.myPaint);
            }
            else
            {
                //Paint eraserPaint = setDefaultPaint();
                //eraserPaint.setAlpha(0xFF);
                //eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
                //eraserPaint.setColor(Color.TRANSPARENT);
                //canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
                canvas.drawPath(p.myPath, p.myPaint);
            }
            canvas.drawBitmap(canvasBitmap, 0, 0, null);

        }
    }

我在网上尝试了很多建议的选项,但都无济于事。

我已经尝试在绘图路径上设置绘画以设置所有各种注释掉的属性。

我尝试在位图上绘图,然后将该位图加载到 Canvas (canvas.drawBitmap(canvasBitmap, 0, 0, null))

我已经在这个类的构造函数中关闭了硬件加速

setLayerType(View.LAYER_TYPE_SOFTWARE, null);

但是要么没有画线,要么当集合重画路径时,橡皮擦画了一条黑线;

有趣的是,如果我在没有循环方面使用位图执行删除 - 橡皮擦会按预期工作;

//If we are making a new drawing we don't want to go through all the paths
    if (isNew != true && erase ==false) {

        //go through every previous path and draw them


        for (PathPaint p : paths) {

            if (!p.isErase)
            {
                canvas.drawPath(p.myPath, p.myPaint);
            }
            //this section now takes place in the elseIF
            else
            {
                Paint eraserPaint = setDefaultPaint();
                eraserPaint.setAlpha(0xFF);
                eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
                eraserPaint.setColor(Color.TRANSPARENT);


                canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
                canvas.drawPath(p.myPath, p.myPaint);
            }
        }
    }
    else if (isNew != true && erase ==true)
    {   
        //This works correctly for Erasing but I dont have the ability to Undo/Redo with this approach! 
        canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
        canvas.drawPath(drawPath, drawPaint);

    }

然而,这是一个问题,因为我希望能够撤消/重做删除(因此是收藏的重点)

谁能帮帮我?

最佳答案

看起来您只使用了一个 View (图层),您首先在其中放置背景图像,然后绘制替换背景的路径。如果是这样,当您删除时,您将从那个唯一的 View /图层中删除,其中包括路径和背景。如果您使用两层(Framelayout 中的两个 View ),一层在后面加载背景,另一层在前面放​​置所有路径,然后删除顶层只会删除路径和背景通过。

分层有不同的方法。例如,这个 FrameLayout 替换了当前持有背景和绘制路径的 View (在代码中称为 XXXView。)

<FrameLayout
   android:layout_width= ...copy from the existing XXXView ...
   android:layout_height= ...copy from the existing XXXView ... >

   <ImageView 
      android:id = "@+id/background"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      ...
      ... the background is loaded here />


   <XXXView (this the existing view where the paths are drawn onto)
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      ...
      ... no background here />

</FrameLayout>

关于android - Canvas Eraser 正在绘制一条黑线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37378268/

有关android - Canvas Eraser 正在绘制一条黑线的更多相关文章

  1. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  2. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  3. ruby - 如何测试正在使用 RSpec 和 Mocha 调用的混合类方法? - 2

    我有一个模块:moduleMyModuledefdo_something#...endend由类使用如下:classMyCommandextendMyModuledefself.execute#...do_somethingendend如何验证MyCommand.execute调用了do_something?我已经尝试使用mocha进行部分模拟,但是当未调用do_something时它不会失败:it"callsdo_something"doMyCommand.stubs(:do_something)MyCommand.executeend 最佳答案

  4. ruby - Ruby 脚本如何检测到它正在 irb 中运行? - 2

    我有一个定义类的Ruby脚本。我希望脚本执行语句BoolParser.generate:file_base=>'bool_parser'仅当脚本作为可执行文件被调用时,而不是当它被irbrequire(或通过-r在命令行上传递)时。我可以用什么来包装上面的语句,以防止它在我的Ruby文件加载时执行? 最佳答案 条件$0==__FILE__...!/usr/bin/ruby1.8classBoolParserdefself.generate(args)p['BoolParser.generate',args]endendif$0==_

  5. ruby-on-rails - 模型范围正在破坏 rake db :migrate - rails 3. 2.3 postgres 9.1.3 - 2

    我在新的Rails应用程序(3.2.3)中运行迁移时遇到了问题。我们正在使用postrgres9.1.3和-pg(0.13.2)-当我运行rakedb:create,然后运行​​rakedb:migrate,我得到->1.9.3-p194(master)rakedb:migrate--trace**Invokedb:migrate(first_time)**Invokeenvironment(first_time)**Executeenvironmentrakeaborted!PG::Error:ERROR:relation"roles"doesnotexistLINE4:WHEREa

  6. javascript - jQuery 的 jquery-1.10.2.min.map 正在触发 404(未找到) - 2

    我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文

  7. ruby-on-rails - Heroku 正在为 Rails 5 应用程序提供旧 Assets - 2

    我在Heroku上部署了一个新版本的Rails5应用程序,在cedar-14堆栈上运行。它在部署时没有预编译,所以我手动执行了herokurunrakeassets:precompile。不过,我可以看到它包含旧Assets,同时需要css和js文件。我的文件在app/assets中,所以该目录不可能不在Assets编译路径中。我在application.rb和production.rb上的配置:config.assets.compile=true#Icheckedtheenvironmentvariable,itrespondsto'enabled',#whichwouldretur

  8. ruby-on-rails - 检测 Rails 是否正在运行站点 - 2

    我所在的团队负责管理公司面向公众的云平台。我们拥有大量运行面向互联网的VM的用户群。我想对我们的地址空间进行自动扫描,看看是否有人在运行Rails应用程序,这样我就可以通知他们升级他们的Rails版本,以避免本周出现的严重安全漏洞。我注意到在某些Apache部署中,有一个有用的PassengerHeader:X-Powered-By:PhusionPassenger(mod_rails/mod_rack)2.0.3然而,这并不可靠。我想知道是否有一种可靠的方法来检测在Web服务器后面运行的Rails,无论是使用响应header还是某种可以确定的GET/POST。谢谢!

  9. ruby-on-rails - 如何在正在运行的 ruby​​ 进程中更改 Date.today 的值 - 2

    我知道这是个坏主意,但我有很多遗留代码,我想运行一些历史批处理作业。我不想更改系统日期,因为其他东西在同一系统上运行。有什么方法可以更改Date.today仅在给定进程的生命周期内返回的值。这里的想法是倒带并运行一些用于处理Date.today的旧批处理脚本。谢谢乔尔 最佳答案 您可以像Nikolaus向您展示的那样对Ruby进行猴子补丁,也可以使用TimeCopgem。它旨在使编写测试更容易,但您也可以在普通代码中使用它。#Setthetimewhereyouwanttogo.t=Time.local(2008,9,1,10,5,

  10. ruby-on-rails - 如何限制模型每天创建一条记录? - 2

    业务逻辑:用户每天只能为日记创建一个条目。在创建条目之前,它必须查询记录以确定是否已经为今天创建了条目。我正在寻找解决此问题的最佳方法的建议。我对如何在客户端实现它有一些想法,但我真的很想在模型层进行验证。任何帮助将不胜感激。 最佳答案 在日志表上创建唯一索引:add_index:journal_entries,[:user_id,:created_on],unique:true然后只能创建一条具有给定user_id和日期的记录,如果违反,数据库将引发异常。请注意,created_on必须是date列,而不是datetime。这是唯

随机推荐