您的位置:首页 > 大数据 > 人工智能

自定义View时,用到Paint Canvas的一些温故,只有想不到没有做不到(实例 1,画一个简单的Activity并且实现他能实现的)

2015-12-30 16:36 656 查看

转载请注明出处:王亟亟的大牛之路

这两天都在写Paint Canvas 昨天前天都写的比较基础的一些只是和一些简单的Demo演示,那今天就写一个“大气磅礴的”(之前几篇没看的可以看下传送门:/article/3594952.html

废话不多,先上效果



YE? 为什么贴2个一模一样的试图,你错了!不带toCopy按钮的那整个Activity都是画的,并且还有点击事件哦!

再贴一下2张图片(上面张为原图,下面一张为效果图,因为为了让大家看清楚效果,这次的效果图都是50%尺寸的,以前都是20%如果占屏了 抱歉)





是不是不仔细看根本看不出2张图片的差距?

贴一下这个自定义View的布局

[code]<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="paintcanvasdemo.pro.wjj.paintcanvasdemo.CopyActivity">

    <paintcanvasdemo.pro.wjj.paintcanvasdemo.CustomView.CustomView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/customView"/>

</RelativeLayout>


确实就只有他,而且是wrap_content,也就说明我们是整张涂抹,OK先说第一部分

画画

整个页面我把它分位4部分。

1,“ActionBar”部分

2,“不要怂,就是干”文字

3,中间的“妹子”

4,下面的按钮

为了让演示和代码可读性更简易,我声明了4个画笔
Paint barPaint, textPaint, bgPaint, buttonPaint;


分别代表 ActionBar的画笔,文字的画笔,背景画笔,按钮画笔

思路:整个图片其实只有2层,背景+控件。

那么先画背景,后画控件,也就不用操作那些试图覆盖的问题了。

实际实现:

[code]  //画背景
  bgPaint = new Paint();
  bgPaint.setColor(getResources().getColor(R.color.White));
  canvas.drawRect(0, 0, ScreenWidth, ScreenHeight, bgPaint);


再是画ActionBar,画之前我们要获取几个参数,1屏幕的长宽,2妹子的长宽,3按钮的长宽。

那么这些参数哪来?

只能从我们的样板,MainActivity来获取控件在正常ImageView,Button的大小:

[code]public class MainActivity extends Activity {
    ImageView imageView;
    Button button3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button toCopy = (Button) findViewById(R.id.toCopy);
        toCopy.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (v.getId() == R.id.toCopy) {
                    Intent intent = new Intent(MainActivity.this, CopyActivity.class);
                    startActivity(intent);
                }
            }
        });
        TypedValue tv = new TypedValue();
        if (this.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
            int actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, this.getResources().getDisplayMetrics());
            Log.d("---> actionBarHeight ", actionBarHeight + "");
        }

        imageView=(ImageView)findViewById(R.id.imageView);
        button3=(Button)findViewById(R.id.button3);
    }

    @Override
    protected void onResume() {
        super.onResume();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        Log.d("-->image的长,宽", "长 " + imageView.getHeight() + "宽 " + imageView.getWidth());
        Log.d("-->button3的长,宽", "长 " + button3.getHeight() + "宽 " + button3.getWidth());
    }
}


OK,那么我们就可以继续我们的创作

先画Bar的背景蓝色区域,144是测量得来的(其实是谷歌设定的一个值,我没有在别的手机上测试过,不知道这个参数会不会有不同适配,反正我们也就是画着玩,不管那些)

[code]  barPaint = new Paint();
  barPaint.setColor(getResources().getColor(R.color.DoderBlue));
  canvas.drawRect(0, 0, ScreenWidth, 144, barPaint);


再画字

[code] //画Title
        barPaint.setTextSize(60);
        barPaint.setColor(getResources().getColor(R.color.White));
//        canvas.drawText("PaintCanvasDemo",0,60,barPaint);将不会出现任何东西drawText第一个参数是你要显示的字符,第二个为 x起点,第三个为底部的Y坐标而不是Y的起点,第四个参数就是你的画笔
        Paint.FontMetricsInt fontMetrics = barPaint.getFontMetricsInt();
        int baseline = (144 - fontMetrics.bottom - fontMetrics.top) / 2;
        canvas.drawText("PaintCanvasDemo", 40, baseline, barPaint);


白色的比,垂直居中操作

需要注意的地方标注已写清楚了。

然后再是话我们的文字

[code]         //画 不要怂,就是干
        textPaint = new Paint();
        textPaint.setColor(getResources().getColor(R.color.Black));
        textPaint.setTextSize(80);
        canvas.drawText("不要怂,就是干", 0, 144 + 80, textPaint);


高度就是再我们刚才的Bar下面再加上字高,因为我们的”模版“里没有X向的间距,所以我们也不空了

再接下来就是画妹子了,因为我们妹子图本身是200*200(我记的是),所以我们把她整体的放大了1.5倍,然后再剧中显示,在上一个Activity我们测试出来了,妹子的长宽都是 900,绘画从左上角开始所以都-(2分之一)的边长

[code]        // 定义矩阵对象
        Matrix matrix = new Matrix();
        // 缩放原图
        matrix.postScale(1.5f, 1.5f);
        Bitmap meizi = BitmapFactory.decodeResource(getResources(),
                R.drawable.bg2).copy(Bitmap.Config.ARGB_8888, true);
        Bitmap newMeiZi = Bitmap.createBitmap(meizi, 0, 0, meizi.getWidth(), meizi.getHeight(),
                matrix, true);
        //画妹子
        canvas.drawBitmap(newMeiZi, ScreenWidth / 2 - 450, ScreenHeight / 2 - 450, new Paint());


再之后就是画我们的3个按钮(我只给一个加了点击时间,其实就是坐标的按钮计算很简单,大家一看就明白)

先画灰色的3个背景色块,这边在Y轴方向为了空一些与屏幕底部的间隙我把整个Canvas上移了一些位置,让呈现更符合要求(美感,美感)

每一个按钮都和前一个相距15+自身宽的差距,保持统一性

[code]        buttonPaint = new Paint();
        buttonPaint.setColor(getResources().getColor(R.color.LightGrey));
        canvas.translate(0, -70);
        canvas.drawRect(15, ScreenHeight - 144, 231, ScreenHeight, buttonPaint);
        canvas.drawRect(15 + 231, ScreenHeight - 144, 231 * 2, ScreenHeight, buttonPaint);
        canvas.drawRect(15 + 231 + 231, ScreenHeight - 144, 231 * 3, ScreenHeight, buttonPaint);
        Log.d("--->drawRect1", "15  " + (ScreenHeight - 144) + "  231  " + ScreenHeight);


再是画字,这边的30 的位置差是大致算下来的可能产生误差买单时肉眼不会太明显,强迫症的画。。那您自己算吧

[code]        //居中画字
        buttonPaint.setColor(getResources().getColor(R.color.Black));
        buttonPaint.setTextSize(65);
        canvas.drawText("按钮1", 15 + 30, ScreenHeight - 144 + baseline, buttonPaint);
        canvas.drawText("按钮2", 15 + 30+231, ScreenHeight - 144 + baseline, buttonPaint);
        canvas.drawText("按钮3", 15 + 30+(231*2), ScreenHeight - 144 + baseline, buttonPaint);


点击事件

分析:因为我们的的View一是一个整体,所以不可能把单独的一个”控件“做事件处理,那只能把每一个控件所处的位置的”矩阵“制造成热区的概念,像Html的map标签 (我记的是哦,不对请纠正)

那具体看代码,我再做解释

[code]public class CustomView extends View implements View.OnTouchListener{

    public static interface OnViewOnTouchListener {
        void onTouchClick(View view,MotionEvent event);
    }
    private OnViewOnTouchListener mOnTouchClickListener = null;

    public void setOnTouchClickListener(OnViewOnTouchListener listener) {
        this.mOnTouchClickListener = listener;
    }

    Context context;
    int ScreenWidth, ScreenHeight;
    Paint barPaint, textPaint, bgPaint, buttonPaint;

    public CustomView(Context context) {
        super(context);
    }

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
        setOnTouchListener(this);
    }

    public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
        setOnTouchListener(this);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public CustomView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs);
        setOnTouchListener(this);
    }

    private void init(Context context, AttributeSet attrs) {
        ScreenWidth = tools.getScreenWidth(context);
        ScreenHeight = tools.getScreenHeight(context);
        Log.d("--->Bar高,宽,长", "Bar高度等于 " + 144 + "ScreenWidth等于 " + ScreenWidth + "ScreenHeight等于 " + ScreenHeight);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画背景色
        bgPaint = new Paint();
        bgPaint.setColor(getResources().getColor(R.color.White));
        canvas.drawRect(0, 0, ScreenWidth, ScreenHeight, bgPaint);

        barPaint = new Paint();
        barPaint.setColor(getResources().getColor(R.color.DoderBlue));
        canvas.drawRect(0, 0, ScreenWidth, 144, barPaint);
        //画Title
        barPaint.setTextSize(60);
        barPaint.setColor(getResources().getColor(R.color.White));
//        canvas.drawText("PaintCanvasDemo",0,60,barPaint);将不会出现任何东西drawText第一个参数是你要显示的字符,第二个为 x起点,第三个为底部的Y坐标而不是Y的起点,第四个参数就是你的画笔
        Paint.FontMetricsInt fontMetrics = barPaint.getFontMetricsInt();
        int baseline = (144 - fontMetrics.bottom - fontMetrics.top) / 2;
        canvas.drawText("PaintCanvasDemo", 40, baseline, barPaint);
        //画 不要怂,就是干
        textPaint = new Paint();
        textPaint.setColor(getResources().getColor(R.color.Black));
        textPaint.setTextSize(80);
        canvas.drawText("不要怂,就是干", 0, 144 + 80, textPaint);
        //画妹子
        // 定义矩阵对象
        Matrix matrix = new Matrix();
        // 缩放原图
        matrix.postScale(1.5f, 1.5f);
        Bitmap meizi = BitmapFactory.decodeResource(getResources(),
                R.drawable.bg2).copy(Bitmap.Config.ARGB_8888, true);
        Bitmap newMeiZi = Bitmap.createBitmap(meizi, 0, 0, meizi.getWidth(), meizi.getHeight(),
                matrix, true);
        //画妹子
        canvas.drawBitmap(newMeiZi, ScreenWidth / 2 - 450, ScreenHeight / 2 - 450, new Paint());

        buttonPaint = new Paint();
        buttonPaint.setColor(getResources().getColor(R.color.LightGrey));
        canvas.translate(0, -70);
        canvas.drawRect(15, ScreenHeight - 144, 231, ScreenHeight, buttonPaint);
        canvas.drawRect(15 + 231, ScreenHeight - 144, 231 * 2, ScreenHeight, buttonPaint);
        canvas.drawRect(15 + 231 + 231, ScreenHeight - 144, 231 * 3, ScreenHeight, buttonPaint);
        Log.d("--->drawRect1", "10  " + (ScreenHeight - 144) + "  231  " + ScreenHeight);
        //居中画字
        buttonPaint.setColor(getResources().getColor(R.color.Black));
        buttonPaint.setTextSize(65);
        canvas.drawText("按钮1", 15 + 30, ScreenHeight - 144 + baseline, buttonPaint);
        canvas.drawText("按钮2", 15 + 30+231, ScreenHeight - 144 + baseline, buttonPaint);
        canvas.drawText("按钮3", 15 + 30+(231*2), ScreenHeight - 144 + baseline, buttonPaint);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (mOnTouchClickListener != null) {
            //注意这里使用getTag方法获取数据
            mOnTouchClickListener.onTouchClick(v,event);
        }
        return true;
    }
}


我们做了个接口。然后这个接口吃了View.OnTouchListener的事件触发,然后我们的调用类去Set一下,那么这个回路就通了。

业务逻辑都在调用类那里做,当然你要写死的画就写到自定义View那去吧。

实现就是如此,是不是很简单啊?

之后考虑做一些动画效果,容我再思索下

源码地址:https://github.com/ddwhan0123/BlogSample/tree/master/PaintCanvasDemo

记得点个赞哦

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: