【Android自定义View】制作老虎机Android版

制作这个自定义控件的思路其实非常简单:
1.写一个继承View,并主要重写ondraw,onmeasure这两个方法
2.启动线程做递增数字
3.停止线程获得最终结果

如下是效果图
图一是一个简单的例子
图三是三个一起,其实和图一并无太大区别
图二是最终可以使用的结果
【Android自定义View】制作老虎机Android版_第1张图片            【Android自定义View】制作老虎机Android版_第2张图片      【Android自定义View】制作老虎机Android版_第3张图片
                                                                          图1                                                                          图2                                                                   图3
其中的线程递增是非常简单的,如下:
<span style="font-size:18px;"><strong>Runnable runnable=new Runnable() {
        @Override
        public void run() {
            while(fg){
                frist++;
                if(frist>=10){
                    frist=0;
                }
                txt_ft=frist+"";
                postInvalidate();
                try {
                    Thread.sleep(200);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    };</strong></span>
跳转速度我们可以在Thread.sleep中调节
另外别忘了刷新整个View
<strong><span style="font-size:18px;">postInvalidate();</span></strong>
说句题外话:
关于postInvalidate()和Invalidate()的区别:

Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用。 

invalidate()是用来刷新View的,必须是在UI线程中进行工作。比如在修改某个view的显示时,调用invalidate()才能看到重新绘制的界面。invalidate()的调用是把之前的旧的view从主UI线程队列中pop掉。 一个Android 程序默认情况下也只有一个进程,但一个进程下却可以有许多个线程。

在这么多线程当中,把主要是负责控制UI界面的显示、更新和控件交互的线程称为UI线程,由于onCreate()方法是由UI线程执行的,所以也可以把UI线程理解为主线程。其余的线程可以理解为工作者线程。

invalidate()得在UI线程中被调动,在工作者线程中可以通过Handler来通知UI线程进行界面更新。
而postInvalidate()在工作者线程中被调用

/************——————————————————————————————————————————————————————******/
其他部分,并未多少觉得需要讲解,以下是源码(其实整个自定义View还有很多可以优化,由于本人平时项目时间紧迫,其他线程销毁等就没有去弄...谅解~)
<span style="font-size:18px;">package ZJ;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;

import com.example.officer.myapplication.R;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

/**
 * Created by officer on 2015/12/8.
 */
public class ZjView extends View{
    private String txt_ft,txt_sd,txt_thr;//分别对应1,2,3位数字
    private int t_color;
    private int t_size;

    private Rect mBound;
    private Paint mPaint;
    private int frist;

    private boolean fg=false;//表示运行状态默认处于暂停

    Thread thread;
    public ZjView(Context mContext){
        this(mContext,null);
    }

    public ZjView(Context mContext,AttributeSet attr){
        this(mContext,attr,0);
    }

    public ZjView(Context mContext,AttributeSet attr,int deyStyle){
        super(mContext,attr,deyStyle);
        TypedArray a=mContext.getTheme()
                .obtainStyledAttributes(attr, R.styleable.ZjView,deyStyle,0);
        int n=a.getIndexCount();
        for(int i=0;i<n;i++){
            int at=a.getIndex(i);
            switch(at){
                case R.styleable.ZjView_titleText:
                    txt_ft=a.getString(at);
                    break;
                case R.styleable.ZjView_tColor:
                    t_color=a.getColor(at, Color.RED);
                    break;
                case R.styleable.ZjView_titleTextSize:
                    t_size=a.getDimensionPixelSize(at,(int) TypedValue.applyDimension(
                            TypedValue.COMPLEX_UNIT_SP,16,getResources().getDisplayMetrics()));
                    break;
            }
        }
        a.recycle();

        thread=new Thread(runnable);
        mPaint=new Paint();
        mPaint.setTextSize(t_size);
        mBound=new Rect();
        mPaint.getTextBounds(txt_ft,0,txt_ft.length(),mBound);

        this.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
               // txt=randomText();
               // postInvalidate();
                frist=0;
                if(fg==true){
                    fg=false;
                }else{
                    fg=true;
                    thread.start();
                }


            }
        });
    }

    Runnable runnable=new Runnable() {
        @Override
        public void run() {
            while(fg){
                frist++;
                if(frist>=10){
                    frist=0;
                }
                txt_ft=frist+"";
                postInvalidate();
                try {
                    Thread.sleep(200);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    };







    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int width;
        int height ;
        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else {
            mPaint.setTextSize(t_size);
            mPaint.getTextBounds(txt_ft, 0, txt_ft.length(), mBound);
            float textWidth = mBound.width();
            int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());
            width = desired;
        }
        if (heightMode == MeasureSpec.EXACTLY)
        {
            height = heightSize;
        } else
        {
            mPaint.setTextSize(t_size);
            mPaint.getTextBounds(txt_ft, 0, txt_ft.length(), mBound);
            float textHeight = mBound.height();
            int desired = (int) (getPaddingTop() + textHeight + getPaddingBottom());
            height = desired;
        }
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        mPaint.setColor(Color.YELLOW);
        canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);

        mPaint.setColor(t_color);
        canvas.drawText(txt_ft, getWidth() / 2 - mBound.width() / 2,
                getHeight() / 2 + mBound.height() / 2, mPaint);
    }




}
</span>



你可能感兴趣的:(android,线程,自定义,控件)