关于《Android自定义组件开发详解》绘图App例子的问题

来源:互联网
发表时间:2017/1/16 18:00:13
责任编辑:鲁晓倩
字体:
为了帮助网友解决“关于《Android自定义组件开发详解》绘图App例子的问题”相关的问题,mr007通过互联网对“关于《Android自定义组件开发详解》绘图App例子的问题”相关的解决方案进行了整理,用户详细问题包括:onTouchEventBitmapCanvasView自定义《Android自定义组件开发详解》是mr007上关于学习自定义开发组件的一本比较火的教材,书本第四章的实例是一个绘图App例子,里面,主要是应用双缓存画图。实例中各类的作用如下
点击图片看大图mr007 www.xue163.com


而我的问题主要是ImageView和继承ShapeDrawer的子类如何在上面绘图的逻辑有点不懂,本书之前第三章有个很简单的绘图例子就是如下
点击图片看大图

如上面,在View的子类中onTouchEvent方法中不断去绘图,而现在是各种绘图器在view上绘图,但是绘图器的父类ShapeDrawer也会有onTouchEvent这个方法,这让我很疑惑,毕竟ShapeDrawer不是基于View的子类,怎么会有这个方法,就算你定义了这个方法在view上绘图的时候也应该不会起作用。望各位给小弟解疑,谢谢!

相关的两个类是:
ShapeDrawer.java
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.view.View;

/**
 * 绘图的基类
 * Created by ZhiyuLiu on 2017/1/10.
 */

public abstract class ShapeDrawer {
    private View view;
    public ShapeDrawer(View view){
        super();
        this.view=view;
    }

    public View getView() {
        return view;
    }
    /**
     * 用于绘图
     * @param viewCanvas
     * 用于展示结果的画布
     * @return
     */
    public void draw(Canvas viewCanvas){
        Bitmap bitmap=BitmapBuffer.getInstance().getBitmap();
        viewCanvas.drawBitmap(bitmap,0,0,null);
    }
    /**
     * 用于响应触摸事件
     *
     * @param event
     * @return
     */
    public abstract boolean onTouchEvent(MotionEvent event);
    /**
     * 绘图的逻辑
     */
    public abstract void logic();

RectDrawer.java
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.View;

/**
 * 用于绘制矩形
 * Created by ZhiyuLiu on 2017/1/10.
 */

public class RectDrawer extends ShapeDrawer {
    private float firstX;
    private float firstY;
    private float currentX;
    private float currentY;

    public RectDrawer(View view){
        super(view);
    }

    @Override
    public void draw(Canvas viewCanvas){
        super.draw(viewCanvas);
        drawShape(viewCanvas,firstX,firstY,currentX,currentY);
    }
    /**
     * 画当前的形状
     * @param canvas
     */
    protected void drawShape(Canvas canvas,float firstX,float firstY,
                             float currentX,float currentY){
        Paint paint=AttributesTool.getInstance().getPaint();
        if(firstX<currentX&&firstY<currentY){
            canvas.drawRect(firstX,firstY,currentX,currentY,paint);
        }else if(firstX>currentX&&firstY>currentY){
            canvas.drawRect(currentX,currentY,firstX,firstY,paint);
        }else if(firstX>currentX&&firstY<currentY){
            canvas.drawRect(currentX,firstY,firstX,currentY,paint);
        }else if(firstX<currentX&&firstY>currentY){
            canvas.drawRect(firstX,currentY,currentX,firstX,paint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        float x=event.getX();
        float y=event.getY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                firstX=x;
                firstY=y;
                break;
            case MotionEvent.ACTION_MOVE:
                currentX=x;
                currentY=y;
                getView().invalidate();
                break;
            case MotionEvent.ACTION_UP:
                Canvas canvas=BitmapBuffer.getInstance().getCanvas();
                drawShape(canvas,firstX,firstY,currentX,currentY);     //将绘图最终结果绘制到保存绘图历史的保存类BitmapBuffer中
                getView().invalidate();
                BitmapBuffer.getInstance().pushBitmap();
                break;
            default:
                break;
        }
        return true;
    }

    @Override
    public void logic(){

    }
}

ImageView.java
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * 绘图view
 * Created by ZhiyuLiu on 2017/1/10.
 */

public class ImageView extends View {
    private ShapeDrawer shapeDrawer;

    public void setShapeDrawer(ShapeDrawer shapeDrawer){
        this.shapeDrawer=shapeDrawer;
    }
    @Override
    protected void onSizeChanged(int w,int h,int oldw,int oldh){
        super.onSizeChanged(w, h, oldw, oldh);
        SystemParams.areaWidth=this.getMeasuredWidth();
        SystemParams.areaHeight=this.getMeasuredHeight();
    }

    @Override
    protected void onDraw(Canvas canvas){
        if(SystemParams.isRedo){
            canvas.drawBitmap(BitmapBuffer.getInstance().getBitmap(),0,0,null);
            SystemParams.isRedo=false;
        }else {
            shapeDrawer.draw(canvas);
        }
        shapeDrawer.logic();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        return shapeDrawer.onTouchEvent(event);
    }
    public ImageView(Context context, AttributeSet attrs){
        super(context,attrs);
        shapeDrawer=new RectDrawer(this);
    }
}

MainActivity.java
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity {
    private ImageView draw;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        draw=(ImageView)findViewById(R.id.image);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item){
        ShapeDrawer shapeDrawer=null;
        AttributesTool at=AttributesTool.getInstance();

        switch (item.getItemId()){
            case R.id.remove:
                BitmapBuffer.getInstance().redo();
                SystemParams.isRedo=true;
                draw.invalidate();
                break;
            case R.id.rect:
                shapeDrawer=new RectDrawer(draw);
                break;
            case R.id.oval:
                shapeDrawer=new OvalDrawer(draw);
                break;
            default:
                break;
            }
        if (shapeDrawer!=null){
            draw.setShapeDrawer(shapeDrawer);
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu){
        getMenuInflater().inflate(R.menu.main,menu);
        return true;
    },具体解决方案如下:
解决方案1:
点击图片看大图点击图片看大图
解决方案2:
这么长,啥问题吧
解决方案3:
有问题吗 ?
解决方案4:
shapeDrawer中onTouchEvent是自己定义的,就相当于把imageview的onTouchEvent的实现单独提出来实现,然后在imageView中onTouchEvent中调用。shapeDrawer中onTouchEvent方法,可以取名A,也可以取名B。只是imageView中onTouchEvent方法调用的具体实现罢了。取相同名字是方法理解。
解决方案5:
ShapeDrawer是你自己定义的类,里面的方法当然也是你自己定义命名的,像楼上说的那样  shapeDrawer中onTouchEvent方法,可以取名A,也可以取名B,其实关键在于它的参数MotionEvent,虽然ShapeDrawer不是基于View的子类,但是MotionEvent参数是从View的子类的onTouchEvent方法传过来的
解决方案6:
引用 4 楼 dalor 的回复:
shapeDrawer中onTouchEvent是自己定义的,就相当于把imageview的onTouchEvent的实现单独提出来实现,然后在imageView中onTouchEvent中调用。shapeDrawer中onTouchEvent方法,可以取名A,也可以取名B。只是imageView中onTouchEvent方法调用的具体实现罢了。取相同名字是方法理解。
你好,请问你说的“然后在imageView中onTouchEvent中调用”是怎么被调用的,难道是这句代码吗?如果是的话,我无法理解return shapeDrawer.onTouchEvent(event)就调用了方法的具体内容
点击图片看大图
解决方案7:
引用 5 楼 Simple_Simple_Simple 的回复:
ShapeDrawer是你自己定义的类,里面的方法当然也是你自己定义命名的,像楼上说的那样  shapeDrawer中onTouchEvent方法,可以取名A,也可以取名B,其实关键在于它的参数MotionEvent,虽然ShapeDrawer不是基于View的子类,但是MotionEvent参数是从View的子类的onTouchEvent方法传过来的
你好,也就是说因为在下图的代码中shapeDrawer.onTouchEvent(event)的参数是从View子类onTouchEvent的参数传来的,所以调用了shapeDrawer.onTouchEvent的具体内容
点击图片看大图
解决方案8:
引用 7 楼 qq_29838777 的回复:
Quote: 引用 5 楼 Simple_Simple_Simple 的回复:

ShapeDrawer是你自己定义的类,里面的方法当然也是你自己定义命名的,像楼上说的那样  shapeDrawer中onTouchEvent方法,可以取名A,也可以取名B,其实关键在于它的参数MotionEvent,虽然ShapeDrawer不是基于View的子类,但是MotionEvent参数是从View的子类的onTouchEvent方法传过来的
你好,也就是说因为在下图的代码中shapeDrawer.onTouchEvent(event)的参数是从View子类onTouchEvent的参数传来的,所以调用了shapeDrawer.onTouchEvent的具体内容
点击图片看大图


是的,这个代码不就是view的onTouchEvent执行的时候ShapeDrawer的onTouchEvent就执行吗
www.xue163.com true http://www.xue163.com/588880/39207/392075742.html report 18683 关于《Android自定义组件开发详解》绘图App例子的问题:解决方案1:解决方案2:这么长,啥问题吧解决方案3:有问题吗 ?解决方案4:shapeDrawer中onTouchEvent是自己定义的,就相当于把imageview的onTouchEvent的实现单独提出来实现,然后在imageView中onTouchEvent中调用。shapeDrawer中onTouchEvent方法,可以取名A,也可以取名B。只是imageView中onTouchEvent方法调用的具体实现罢了。取相同名字是方法理解。解决方案5:ShapeDrawer是你自己定义的类,里...
最近关注
首页推荐
热门图片
最新添加资讯
24小时热门资讯
精彩资讯
精彩推荐
热点推荐
真视界
精彩图片
社区精粹
关于本站 | 广告服务 | 手机版 | 商务合作 | 免责申明 | 招聘信息 | 联系我们
Copyright © 2004-2016 Xue163.com All Rights Reserved. mr007 版权所有
京ICP备10044368号-1 京公网安备11010802011102号
荐闻 | mr007头条知识问答 | 装修 | 作业 | 荐闻 | mr007头条精彩微信 | mr007 | 软件教室 | 设计大全 | mr007相关 | 英语学习 | 开发编程 | 考试中心 | 参考范文 | 管理文库 | mr007中心 | 站长之家 | IT信息中心 | 商学院 | 数码大全 | 硬件DIY | 企业服务 | 网吧在线 | 问吧 | 百科 | 硬件知识 | 本网视点 | 文库 | 手机 | 平板 | 汽车 | 游戏 | 家电 | 精彩摄影 | 时尚科技 | 现代家居 | IT女人 | 经验 | 每日新闻 | 健康养生 | 图书馆 | 猎奇 | 精彩看点 | 图库 | mr007 | 软件教室 | 设计大全 | mr007相关 | 英语学习 | 开发编程 | 考试中心 | 参考范文 | 管理文库 | mr007中心 | 站长之家 | IT信息中心 | 商学院 | 数码大全 | 硬件DIY | 企业服务 | 网吧在线 | 问吧 | 百科 | 硬件知识 | 本网视点 | 文库 | 手机 | 平板 | 汽车 | 游戏 | 家电 | 精彩摄影 | 时尚科技 | 现代家居 | IT女人 | 经验 | 每日新闻 | 健康养生 | 图书馆 | 精彩微信 | 猎奇 | 精彩看点 | 图库编程 方案 信息windows方案windows answer文档机构教育文档问答中心IT编程数码信息解决方案信息中心IT科技