<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中调节
<strong><span style="font-size:18px;">postInvalidate();</span></strong>说句题外话:
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()在工作者线程中被调用
<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>