android 自定义时钟控件

不点 阅读:751 2021-04-01 10:10:49 评论:0

效果截图:

 

自定义时钟组件源代码:

package com.sky_dreaming.analogic_clock.view; 
 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.content.BroadcastReceiver; 
import android.content.res.Resources; 
 
import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.graphics.drawable.BitmapDrawable; 
import android.graphics.drawable.Drawable; 
 
import android.os.Handler; 
import android.text.format.Time; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.View; 
import android.widget.RemoteViews.RemoteView; 
 
import java.io.InputStream; 
import java.util.TimeZone; 
 
import com.sky_dreaming.analogic_clock.R; 
 
@RemoteView 
public class AnalogClock extends View { 
	//时间 
    private Time mCalendar; 
    //时钟图片 
    private Bitmap mDial; 
    //设置图片 
    private BitmapDrawable mDialDrawable; 
    //时 
    private BitmapDrawable mHourHandDrawable; 
    //分 
    private BitmapDrawable mMinuteHandDrawable; 
    //秒 
    private BitmapDrawable mSecondHandDrawable; 
    //时钟宽度 
    private int mDialWidth; 
    //时钟高度 
    private int mDialHeight; 
    //是否点击 
    private boolean mAttached = false; 
    //现在时间--时 
    private float mHours; 
    //现在时间---分 
    private float mMinutes; 
    //现在时间--秒 
    private float mSeconds; 
    //现在时间字符串 
    private String time_zone; 
     
    public String getTime_zone() { 
		return time_zone; 
	} 
 
	public void setTime_zone(String timeZone) { 
		time_zone = timeZone; 
	} 
	 
	/** 
     *时间是否更改 
     */ 
    private boolean mChanged; 
     
    /** 
     *主线程 
     */ 
    private Handler loopHandler = new Handler(); 
     
    /** 
     *是否运行 
     */ 
    private boolean isRun = false; 
     
    /** 
     * 主线程处理(时间) 
     */ 
    private void run() 
    { 
    	/** 
    	 *时间更改线程 
    	 */ 
    	loopHandler.post(tickRunnable); 
    } 
    private Runnable tickRunnable = new Runnable() {    
        public void run() { 
        	/** 
        	 * 方法待定 
        	 */ 
        	postInvalidate(); 
        	/** 
        	 * 10秒之后放入主线程之中 
        	 */ 
            loopHandler.postDelayed(tickRunnable, 1000);    
        }    
    };    
	/** 
	 * 相关构造方法 
	 */ 
    public AnalogClock(Context context) { 
        this(context, null); 
    } 
 
    public AnalogClock(Context context, AttributeSet attrs) { 
        this(context, attrs, 0); 
    } 
 
    public AnalogClock(Context context, AttributeSet attrs, 
                       int defStyle) { 
        super(context, attrs, defStyle); 
         
        /** 
         * 现在时间实例化 
         */ 
        mCalendar = new Time(); 
        time_zone = mCalendar.timezone; 
         
        Resources r = this.getContext().getResources(); 
		InputStream is =null; 
		 
		/** 
		 * 资源图片读取 
		 */ 
		is = r.openRawResource(R.drawable.clock); 
		mDialDrawable = new BitmapDrawable(is); 
		mDial = mDialDrawable.getBitmap(); 
		 
		is = r.openRawResource(R.drawable.hands); 
		mHourHandDrawable = new BitmapDrawable(is); 
		 
		is = r.openRawResource(R.drawable.hands); 
		mMinuteHandDrawable = new BitmapDrawable(is); 
		 
		is = r.openRawResource(R.drawable.hands); 
		mSecondHandDrawable = new BitmapDrawable(is); 
		 
        /** 
         * 图片大小获取 
         */ 
        mDialWidth = mDialDrawable.getIntrinsicWidth(); 
        mDialHeight = mDialDrawable.getIntrinsicHeight(); 
    } 
    //view 相关覆写方法 
    @Override 
    protected void onAttachedToWindow() { 
        super.onAttachedToWindow(); 
 
        if (!mAttached) { 
            mAttached = true; 
            IntentFilter filter = new IntentFilter(); 
            filter.addAction(Intent.ACTION_TIME_CHANGED); 
            filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); 
            getContext().registerReceiver(mIntentReceiver, filter, null, loopHandler); 
        } 
 
    } 
    //view 相关覆写方法 
    @Override 
    protected void onDetachedFromWindow() { 
        super.onDetachedFromWindow(); 
        if (mAttached) { 
            getContext().unregisterReceiver(mIntentReceiver); 
            mAttached = false; 
        } 
    } 
    //view 相关覆写方法 
    @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); 
 
        float hScale = 1.0f; 
        float vScale = 1.0f; 
 
        if (widthMode != MeasureSpec.UNSPECIFIED && widthSize < mDialWidth) { 
            hScale = (float) widthSize / (float) mDialWidth; 
        } 
 
        if (heightMode != MeasureSpec.UNSPECIFIED && heightSize < mDialHeight) { 
            vScale = (float )heightSize / (float) mDialHeight; 
        } 
 
        float scale = Math.min(hScale, vScale); 
 
        setMeasuredDimension(resolveSize((int) (mDialWidth * scale), widthMeasureSpec), 
                resolveSize((int) (mDialHeight * scale), heightMeasureSpec)); 
    } 
    //view 相关覆写方法 
    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
        super.onSizeChanged(w, h, oldw, oldh); 
        mChanged = true; 
    } 
    //view 相关覆写方法 
    @Override 
    protected void onDraw(Canvas canvas) { 
        super.onDraw(canvas); 
        if(!isRun) 
        { 
        	run(); 
        	isRun = true; 
        	return; 
        } 
        //时间更改函数 
        onTimeChanged(); 
        boolean changed = mChanged; 
        if (changed) { 
            mChanged = false; 
        } 
 
        int availableWidth = mDial.getWidth(); 
        int availableHeight = mDial.getHeight(); 
 
        int x = availableWidth / 2; 
        int y = availableHeight / 2;  
 
        final Drawable dial = mDialDrawable; 
        int w = dial.getIntrinsicWidth(); 
        int h = dial.getIntrinsicHeight(); 
         
        boolean scaled = false; 
 
        if (availableWidth < w || availableHeight < h) { 
            scaled = true; 
            float scale = Math.min((float) availableWidth / (float) w, 
                                   (float) availableHeight / (float) h); 
            canvas.save(); 
 
            canvas.scale(scale, scale, x, y); 
        } 
 
        if (changed) { 
 
            dial.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2)); 
        } 
        dial.draw(canvas); 
 
        canvas.save(); 
 
        canvas.rotate(mHours / 12.0f * 360.0f, x, y); 
        final Drawable hourHand = mHourHandDrawable; 
        if (changed) { 
            w = hourHand.getIntrinsicWidth(); 
            h = hourHand.getIntrinsicHeight(); 
            hourHand.setBounds(x - (w / 2), y - (h * 2 / 3), x + (w / 2), y + (h / 3)); 
        } 
        hourHand.draw(canvas); 
 
        canvas.restore(); 
 
        canvas.save(); 
        canvas.rotate(mMinutes / 60.0f * 360.0f, x, y); 
 
        final Drawable minuteHand = mMinuteHandDrawable; 
        if (changed) { 
            w = minuteHand.getIntrinsicWidth(); 
            h = minuteHand.getIntrinsicHeight(); 
            minuteHand.setBounds(x - (w / 2), y - (h  * 4 / 5), x + (w / 2), y + (h / 5)); 
        } 
        minuteHand.draw(canvas); 
        canvas.restore(); 
 
        canvas.save(); 
        canvas.rotate(mSeconds / 60.0f * 360.0f, x, y); 
 
        final Drawable scendHand = mSecondHandDrawable; 
        if (changed) { 
            w = scendHand.getIntrinsicWidth(); 
            h = scendHand.getIntrinsicHeight(); 
            scendHand.setBounds(x - (w / 2), y - h, x + (w / 2), y); 
        } 
        scendHand.draw(canvas); 
        canvas.restore(); 
 
        if (scaled) { 
            canvas.restore(); 
        } 
    } 
//自定义时间更改函数 
    private void onTimeChanged() { 
 
        mCalendar.setToNow(); 
 
        int hour = mCalendar.hour; 
        int minute = mCalendar.minute; 
        int second = mCalendar.second; 
         
        mSeconds = second; 
        mMinutes = minute + second / 60.0f; 
        mHours = hour + mMinutes / 60.0f; 
         
        mChanged = true; 
    } 
    //自定义广播 
    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 
        @Override 
        public void onReceive(Context context, Intent intent) { 
        	String tz = ""; 
            if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) { 
                tz = intent.getStringExtra("time-zone"); 
                mCalendar = new Time(TimeZone.getTimeZone(tz).getID()); 
                time_zone = mCalendar.timezone; 
            } 
            Log.i("********************",tz); 
            onTimeChanged(); 
            invalidate(); 
        } 
    }; 
}


自定义时钟控件下载地址:http://download.csdn.net/detail/zhouzhiwengang/6366727

 

标签:Android
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号