Android自定义SurfaceView实现画板功能

接触了这么久的View,总不能一直停留在View里,现在开始呢,就要学习一个新的知识点:SurfaceView,实际上SurfaceView与View的原理都差不多,只是效率和渲染方式上,SurfaceView要优于View,这也是我们写这个的原因。今天就看看这个SurfaceView,好了,下面就是今天要说的效果。

界面很简单,就是一个按钮以及一个画板,先看看界面的代码吧

<LinearLayout 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"
  android:orientation="vertical"
 tools:context="com.example.xinxindemo.MainActivity" >

 <com.example.xinxindemo.view.SecondSurfaceView
  android:id="@+id/surfaceview"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:layout_weight="20"
   />

 <LinearLayout
  android:layout_width="match_parent"
  android:layout_height="55dip"
  android:orientation="horizontal"
  android:padding="5dip" >

  <Button
   android:onClick="onClick"
   android:layout_width="wrap_content"
   android:layout_height="match_parent"
   android:text="clean" />
</LinearLayout>

</LinearLayout>

对吧,界面不是很复杂,下面再看看这个SecondSurfaceView是怎么实现的;

/**
 * 2016年7月26日17:20:13
 * @author 小瓶盖 blog
 *
 */
public class SecondSurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable{

 /**
  * 是否处于绘制状态
  */
 private boolean mIsDrawing;
 /**
  * 帮助类
  */
 private SurfaceHolder mHolder;
 /**
  * 画布
  */
 private Canvas mCanvas;
 /**
  * 路径
  */
 private Path mPath;
 /**
  * 画笔
  */
 private Paint mPaint;

 public SecondSurfaceView(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
  initView();
 }

 public SecondSurfaceView(Context context, AttributeSet attrs) {
  super(context, attrs);
  initView();
 }

 public SecondSurfaceView(Context context) {
  super(context);
  initView();
 }
 @Override
 public boolean onTouchEvent(MotionEvent event) {

  int x=(int) event.getX();
  int y=(int) event.getY();
  switch (event.getAction()) {
  case MotionEvent.ACTION_DOWN:
   mPath.moveTo(x, y);
   break;
  case MotionEvent.ACTION_MOVE:
   mPath.lineTo(x, y);
   break;
  case MotionEvent.ACTION_UP:

   break;
  default:
   break;
  }

  return true;
 }

 private void initView() {
  mHolder=getHolder();
  mHolder.addCallback(this);
  setFocusable(true);
  setFocusableInTouchMode(true);
  this.setKeepScreenOn(true);

  mPath=new Path();

  mPaint=new Paint();
  mPaint.setAntiAlias(true);
  mPaint.setColor(Color.BLACK);
  mPaint.setStyle(Style.STROKE);
  mPaint.setStrokeWidth(15);
 }

 @Override
 public void run() {
  long start =System.currentTimeMillis();
  while(mIsDrawing){
   draw();
  }
  long end =System.currentTimeMillis();
  if (end-start<100) {
   try {
    Thread.sleep(100-(end-start));
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
 }

 @Override
 public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {

 }

 @Override
 public void surfaceCreated(SurfaceHolder arg0) {
  mIsDrawing=true;
  new Thread(this).start();
 }

 @Override
 public void surfaceDestroyed(SurfaceHolder arg0) {
  mIsDrawing=false;

 }
 private void draw(){
  try {
   mCanvas=mHolder.lockCanvas();
   mCanvas.drawColor(Color.WHITE);
   mCanvas.drawPath(mPath, mPaint);
  } catch (Exception e) {
   e.printStackTrace();
  }finally{
   if (mCanvas!=null) {
    mHolder.unlockCanvasAndPost(mCanvas);
   }
  }
 }
 /**
  * 清除内容
  */
 public void clean(){
  initView();
 }
}

然后就是MainActivity.java

/**
 * 2016年7月26日17:20:13
 * @author 小瓶盖 blog *
 */
public class MainActivity extends Activity{
 SecondSurfaceView surfaceView;

 @Override
 protected void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  surfaceView=(SecondSurfaceView)findViewById(R.id.surfaceview);
 }

 public void onClick(View v){
  surfaceView.clean();
 }

}

源码下载:http://xiazai.jb51.net/201607/yuanma/SurfaceView(jb51.net).rar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 双缓冲技术实现Android 画板应用

    什么是双缓冲技术?双缓冲技术就是当用户操作界面完成后,会有一个缓冲区保存用户操作的结果. 为什么要使用双缓冲技术?拿Android 游戏开发来说,界面贞每次都是全部重画的,也就说画了新的,旧的就没了,所以需要使用双缓冲技术保存之前的内容. 如何实现双缓冲?使用一个Bitmap对象保留之前的画布即可. package com.example.phonegaptest; import android.content.Context; import android.graphics.Bitmap; i

  • Android实现画板、写字板功能(附源码下载)

    前言 本文给大家分享一个使用Android开发写字板功能Dem.简单操作内存中的图像.对图像进行简单的处理.绘制直线.以达到写字板的效果 效果图如下 XML布局代码 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="

  • Android多媒体之画画板开发案例分享

    先看看效果: 其实画画板的原理很简单,就是首先记录下按下屏幕的点,然后每移动一下就让这两次移动的点连线,周而复始,图像就由很多条直线构成了. 核心代码 : public class MainActivity extends Activity implements OnClickListener,OnSeekBarChangeListener { private View red_view,green_view,blue_view; //控制画笔颜色的三块区域 private SeekBar se

  • Android画画板的制作方法

    本文实例为大家分享了Android画画板展示的具体代码,供大家参考,具体内容如下 main.xml布局 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_w

  • android实现简单的画画板实例代码

    直接看代码,注释都写清楚了 复制代码 代码如下: public class MainActivity extends Activity { private ImageView iv; private Bitmap baseBitmap; private Canvas canvas; private Paint paint; @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedIns

  • Android采用双缓冲技术实现画板

    本文实例为大家分享了Android实现画板的具体代码,采用的技术是双缓冲技术,供大家参考,具体内容如下 1.双缓冲技术的概念 所谓的双缓冲技术其实很简单,当程序需要在指定的View上进行绘制时,程序并不需要直接绘制到该View组件,而是先绘制到一个内存中的Bitmap图片上(就是缓冲),等内存中的Bitmap绘制好之后,再一次性将Bitmap绘制到View组件上. 2.Android采用双缓冲实现画板  实现的思路: 1).定义一个内存中图片,将他作为缓冲区Bitmap cacheBitmap

  • Android自定义SurfaceView实现画板功能

    接触了这么久的View,总不能一直停留在View里,现在开始呢,就要学习一个新的知识点:SurfaceView,实际上SurfaceView与View的原理都差不多,只是效率和渲染方式上,SurfaceView要优于View,这也是我们写这个的原因.今天就看看这个SurfaceView,好了,下面就是今天要说的效果. 界面很简单,就是一个按钮以及一个画板,先看看界面的代码吧 <LinearLayout xmlns:android="http://schemas.android.com/ap

  • Android自定义View展开菜单功能的实现

    先给大家展示下效果图,如果大家感觉不错,请参考实现代码. 思路 1.下角Button的父View加入一个FrameLayout,也就是图中全屏透明灰色部分. 菜单没有弹出的时候设置为不可见. 设置FrameLayout点击事件,点击的时候缩回菜单. 对应init() 2.rameLayout中加入菜单按钮,也就是弹出的那三个. 菜单没有弹出的时候设置为不可见. 对应addElement()和freshElement() 3.右下角的按钮,旋转图标(也可以不旋转). 对应setRotateAnim

  • Android自定义processor实现bindView功能的实例

    一.简介 在现阶段的Android开发中,注解越来越流行起来,比如ButterKnife,Retrofit,Dragger,EventBus等等都选择使用注解来配置.按照处理时期,注解又分为两种类型,一种是运行时注解,另一种是编译时注解,运行时注解由于性能问题被一些人所诟病.编译时注解的核心依赖APT(Annotation Processing Tools)实现,原理是在某些代码元素上(如类型.函数.字段等)添加注解,在编译时编译器会检查AbstractProcessor的子类,并且调用该类型的

  • Android自定义view实现标签栏功能(只支持固定两个标签)

    实现效果图 主要代码 完整源代码 class TabView(context: Context, attributeSet: AttributeSet?) : LinearLayout(context, attributeSet) { private lateinit var firstTab: View private lateinit var secondTab: View private val firstTabIndex = 0 private val secondTabIndex =

  • Android 自定义图片地图坐标功能的实现

    一.前言 最近项目要求实现一个在自定义地图图片上添加坐标信息的功能,类似于在图片做标注的功能.如下图所示.坐标的位置是相对于图片宽高的百分比 二.思路 改功能主要分为三个视图,1.继承FrameLayout作为父容器:2.添加一个铺满父布局的ImageView显示地图图片:3.动态添加自定义坐标视图 三.代码实现 1. 自定义坐标视图 <?xml version="1.0" encoding="utf-8"?> <androidx.constrai

  • Android自定义View画圆功能

    本文实例为大家分享了Android自定义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&q

  • Android自定义Camera实现拍照功能

    本文记录了用自定义Camera实现的简单拍照功能. Camera类在5.0以后不推荐使用了,取而代之的是android.hardware.camera2包下的类,本文使用Camera. 我们首先自定义一个View去继承SurfaceView: public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Camera.AutoFocusCallback { private Surface

  • Android自定义ImageView实现圆角功能

    使用自定义ImageView,实现圆角功能,供大家参考,具体内容如下 1.自定义属性attrs.xml <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="RoundCornerImageView"> <attr name="radius" format="dimension&

  • Android 自定义SurfaceView详解

    本文简单讨论以后Android游戏引擎模板的架构问题.在Android游戏开发教程之二:View类与SurfaceView类中我们已经谈到,SurfaceView类是有很多优势的,所以在Android游戏开发中还是选择SurfaceView. 这里我们直接继承SurfaceView,实现SurfaceHolder.Callback接口,处理surfaceCreated.surfaceChanged以及surfaceDestroyed方法,这里我们并没有把按键控制传入,最终游戏的控制方面仍然由Vi

  • Android自定义View实现时钟功能

    最近在练习自定义view, 想起之前面试的时候笔试有道题是写出自定义一个时钟的关键代码. 今天就来实现一下. 步骤依然是先分析, 再上代码. 实现效果 View分析 时钟主要分为五个部分: 1.中心点: 圆心位置2.圆盘: 以中心点为圆心,drawCircle画个圆3.刻度: paint有个aip, setPathEffect可以根据path画特效, 那么刻度就可以根据圆的path画一个矩形path的特效, 并且这个api只会画特效, 不会画出圆. /** * shape: 特效的path, 这

随机推荐