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

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

2015-12-08 12:41 701 查看
制作这个自定义控件的思路其实非常简单:
1.写一个继承View,并主要重写ondraw,onmeasure这两个方法
2.启动线程做递增数字
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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息