您的位置:首页 > 移动开发 > Android开发

Android学习2: Android使用SurfaceView绘制一条移动的线段

2015-01-15 13:45 417 查看
今天 学习了一下, 怎样使用 SurfaceView. SurfaceHolder, Canvas 和 Paint 来绘制一条移动的线段

例子, 都是我从网上找的, 只不过是自已简化了一些, 改掉了一些过时的代码.都不是原创的, 只不过能明白原理就好

这个例子在运行时, 还有内存泄露.我怀疑是在 执行SimpleDraw() 函数的时候产生的.

不过现在还没法改.

定时器再次启动时, 需要重置TimerTask, 因为一个TimerTask只能执行一次, 一次性的.



代码:

布局文件:

layout/activity_main.xml

<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" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true">

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <Button
                android:layout_width="150dp"
                android:layout_height="45dp"
                android:text="定时器绘图"
                android:id="@+id/button2" />
        </LinearLayout>

        <SurfaceView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/surfaceView"
            android:layout_gravity="center_horizontal" />

    </LinearLayout>
</RelativeLayout>


com/example/youtwo/testsurfaceview/MainActivity.java

package com.example.youtwo.testsurfaceview;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;

import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends ActionBarActivity {

    // 按钮
    private Button btnTimerDraw;

    // 绘图容器
    private SurfaceView sfv;
    private SurfaceHolder sfh;

    // 定时器
    private Timer mTimer;
    private MyTimerTask mTimerTask;

    // 坐标
    private int pos_h;

    // 屏幕大小
    DisplayMetrics dm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化按钮&绑定按钮点击事件
        btnTimerDraw = (Button) this.findViewById(R.id.button2);
        btnTimerDraw.setOnClickListener(new ClickEvent());

        // 初始化绘图容器
        sfv = (SurfaceView) this.findViewById(R.id.surfaceView);
        sfh = sfv.getHolder();

        // 初始化定时器
        mTimer = new Timer();
        mTimerTask = new MyTimerTask();

        // 初始化坐标
        pos_h = 0;

        // 获取屏幕大小
        dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    // 事件接收
    class ClickEvent implements View.OnClickListener {

        @Override
        public void onClick(View v) {
            if (v == btnTimerDraw) {
                mTimerTask = new MyTimerTask();
                mTimer.schedule(mTimerTask, 0, 5);//动态绘制
            }
        }

    }

    // 绘制类
    class MyTimerTask extends TimerTask {
        @Override
        public void run() {
            SimpleDraw(pos_h);
            pos_h += 5;

            // 如果高度大于屏幕高度
            if (pos_h >= dm.heightPixels) {
                pos_h = 0;
            }
        }

    }

    /*
    * 绘制指定区域
    */
    void SimpleDraw(int pos_h) {
        // 初始化画布,这步是关键
        Canvas canvas = sfh.lockCanvas(new Rect(0, 0,
                dm.widthPixels, dm.heightPixels));

        // 初始化画笔
        Paint mPaint = new Paint();
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        canvas.drawPaint(mPaint);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));

        mPaint.setColor(Color.GREEN);// 画笔为绿色
        mPaint.setStrokeWidth(5);// 设置画笔粗细

        // 绘制线段
        canvas.drawLine(0, pos_h, dm.widthPixels, pos_h, mPaint);
        sfh.unlockCanvasAndPost(canvas);// 解锁画布,提交画好的图像
        mPaint.reset();
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: