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

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

2015-12-30 16:36 876 查看

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

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

废话不多,先上效果



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

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





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

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

<?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层,背景+控件。

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

实际实现:

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


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

那么这些参数哪来?

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

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是测量得来的(其实是谷歌设定的一个值,我没有在别的手机上测试过,不知道这个参数会不会有不同适配,反正我们也就是画着玩,不管那些)

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);


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

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

// 定义矩阵对象
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+自身宽的差距,保持统一性

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 的位置差是大致算下来的可能产生误差买单时肉眼不会太明显,强迫症的画。。那您自己算吧

//居中画字
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标签 (我记的是哦,不对请纠正)

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

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

记得点个赞哦

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