2013-05-28 67 views
0

我想要使用互聯網上可用的Android開放源代碼項目使用AnalogClock的源代碼的自定義AnalogClock類。設置時間與自定義android模擬時鐘從它的原始類

我想讓時鐘設置我想要的時間,而不是當前時間。我沒有找到明確的例子,所以這篇文章可能會有用。將源代碼複製到新文件後,出現一些錯誤。下面是AnalogClock的原始源代碼:

/* 
* Copyright (C) 2006 The Android Open Source Project 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 

package android.widget; 

import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.content.BroadcastReceiver; 
import android.content.res.Resources; 
import android.content.res.TypedArray; 
import android.graphics.Canvas; 
import android.graphics.drawable.Drawable; 
import android.os.Handler; 
import android.text.format.Time; 
import android.util.AttributeSet; 
import android.view.View; 
import android.widget.RemoteViews.RemoteView; 

import java.util.TimeZone; 

/** 
* This widget display an analogic clock with two hands for hours and 
* minutes. 
*/ 
@RemoteView 
public class AnalogClock extends View { 
    private Time mCalendar; 

    private Drawable mHourHand; 
    private Drawable mMinuteHand; 
    private Drawable mDial; 

    private int mDialWidth; 
    private int mDialHeight; 

    private boolean mAttached; 

    private final Handler mHandler = new Handler(); 
    private float mMinutes; 
    private float mHour; 
    private boolean mChanged; 

    public AnalogClock(Context context) { 
     this(context, null); 
    } 

    public AnalogClock(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

!!錯誤mContext - >更改mContext上下文(我能做到這一點)?

public AnalogClock(Context context, AttributeSet attrs, 
         int defStyle) { 
     super(context, attrs, defStyle); 
     Resources r = mContext.getResources(); 

!!錯誤com.android.internal.R不能得到解決。 我找到了解決這一問題

mDial = r.getDrawable(Resources.getSystem().getIdentifier("clock_dial","drawable", "android")); 

而且同其他線路只是改變名稱以及繪製或設置樣式。

vvvv ---- 但我仍然有一個問題,下面的代碼。

 TypedArray a = 
       context.obtainStyledAttributes(
         attrs, com.android.internal.R.styleable.AnalogClock, defStyle, 0); 

^^^^ ---- 我不知道如何去改變它,並使其工作

 mDial = a.getDrawable(com.android.internal.R.styleable.AnalogClock_dial); 
     if (mDial == null) { 
      mDial = r.getDrawable(com.android.internal.R.drawable.clock_dial); 
     } 

     mHourHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_hour); 
     if (mHourHand == null) { 
      mHourHand = r.getDrawable(com.android.internal.R.drawable.clock_hand_hour); 
     } 

     mMinuteHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_minute); 
     if (mMinuteHand == null) { 
      mMinuteHand = r.getDrawable(com.android.internal.R.drawable.clock_hand_minute); 
     } 

     mCalendar = new Time(); 

     mDialWidth = mDial.getIntrinsicWidth(); 
     mDialHeight = mDial.getIntrinsicHeight(); 
    } 

    @Override 
    protected void onAttachedToWindow() { 
     super.onAttachedToWindow(); 

     if (!mAttached) { 
      mAttached = true; 
      IntentFilter filter = new IntentFilter(); 

      filter.addAction(Intent.ACTION_TIME_TICK); 
      filter.addAction(Intent.ACTION_TIME_CHANGED); 
      filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); 

      getContext().registerReceiver(mIntentReceiver, filter, null, mHandler); 
     } 

     // NOTE: It's safe to do these after registering the receiver since the receiver always runs 
     // in the main thread, therefore the receiver can't run before this method returns. 

     // The time zone may have changed while the receiver wasn't registered, so update the Time 
     mCalendar = new Time(); 

     // Make sure we update to the current time 
     onTimeChanged(); 
    } 

    @Override 
    protected void onDetachedFromWindow() { 
     super.onDetachedFromWindow(); 
     if (mAttached) { 
      getContext().unregisterReceiver(mIntentReceiver); 
      mAttached = false; 
     } 
    } 

    @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)); 
    } 

    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 
     mChanged = true; 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     boolean changed = mChanged; 
     if (changed) { 
      mChanged = false; 
     } 

!!!錯誤 - 在哪裏呢mRight,MLEFT ,mBotton,mTop從哪裏來?這不是在這個文件中聲明

 int availableWidth = mRight - mLeft; 
     int availableHeight = mBottom - mTop; 

     int x = availableWidth/2; 
     int y = availableHeight/2; 

     final Drawable dial = mDial; 
     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(mHour/12.0f * 360.0f, x, y); 
     final Drawable hourHand = mHourHand; 
     if (changed) { 
      w = hourHand.getIntrinsicWidth(); 
      h = hourHand.getIntrinsicHeight(); 
      hourHand.setBounds(x - (w/2), y - (h/2), x + (w/2), y + (h/2)); 
     } 
     hourHand.draw(canvas); 
     canvas.restore(); 

     canvas.save(); 
     canvas.rotate(mMinutes/60.0f * 360.0f, x, y); 

     final Drawable minuteHand = mMinuteHand; 
     if (changed) { 
      w = minuteHand.getIntrinsicWidth(); 
      h = minuteHand.getIntrinsicHeight(); 
      minuteHand.setBounds(x - (w/2), y - (h/2), x + (w/2), y + (h/2)); 
     } 
     minuteHand.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; 

     mMinutes = minute + second/60.0f; 
     mHour = hour + mMinutes/60.0f; 
     mChanged = true; 
    } 

    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) { 
       String tz = intent.getStringExtra("time-zone"); 
       mCalendar = new Time(TimeZone.getTimeZone(tz).getID()); 
      } 

      onTimeChanged(); 

      invalidate(); 
     } 
    }; 
} 

誰能告訴我:

  1. 我怎樣才能讓這個類的工作像一個正常的AnalogClock
  2. 我怎麼能寫這個類中的方法將適用於我將提供給它的時間?
+0

那堆代碼的哪一部分會給你帶來麻煩? –

+0

@MarcoForberg它顯示在我的帖子上面標有!!!錯誤 – Marek

+0

「mRight,mLeft,mBotton,mTop從哪裏來?它沒有在這個文件中聲明「,因爲這是你應該知道的類,我假設這些值是在超類中聲明的,如'View' –

回答

4

使用setTime()方法工作自定義MyAnalogClock。

花了一些時間後,我終於設法解決了這個問題。 我希望它對某人有用。 只需調用setTime(小時,分鐘,秒)方法即可設置時間。

import android.content.Context; 
import android.content.res.Resources; 
import android.content.res.TypedArray; 
import android.graphics.Canvas; 
import android.graphics.drawable.Drawable; 
import android.text.format.Time; 
import android.util.AttributeSet; 
import android.view.View; 
import android.widget.RemoteViews.RemoteView; 

/** 
* This widget display an analogic clock with two hands for hours and 
* minutes. 
*/ 
@RemoteView 
public class MyAnalogClock extends View { 

    private Drawable mHourHand; 
    private Drawable mMinuteHand; 
    private Drawable mSecondHand; 
    private Drawable mDial; 

    private int mDialWidth; 
    private int mDialHeight; 

    private float mSeconds; 
    private float mMinutes; 
    private float mHour; 

    Context mContext; 

    public MyAnalogClock(Context context) { 
     super(context); 
    } 

    public MyAnalogClock(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public MyAnalogClock(Context context, AttributeSet attrs, 
         int defStyle) { 
     super(context, attrs, defStyle); 
     Resources r = context.getResources(); 
     TypedArray a = 
       context.obtainStyledAttributes(
         attrs, R.styleable.AnalogClock, defStyle, 0); 
     mContext=context; 
     // mDial = a.getDrawable(com.android.internal.R.styleable.AnalogClock_dial); 
     // if (mDial == null) { 
      mDial = r.getDrawable(R.drawable.clock_dial); 
     // } 

     // mHourHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_hour); 
     // if (mHourHand == null) { 
      mHourHand = r.getDrawable(R.drawable.clock_hour); 
     // } 

    // mMinuteHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_minute); 
    // if (mMinuteHand == null) { 
      mMinuteHand = r.getDrawable(R.drawable.clock_minute); 
      mSecondHand = r.getDrawable(R.drawable.clockgoog_minute); 
    // } 

     mDialWidth = mDial.getIntrinsicWidth(); 
     mDialHeight = mDial.getIntrinsicHeight(); 
    } 

    @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)); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     //Here you can set the size of your clock 
     int availableWidth = 70; 
     int availableHeight = 70; 

     //Actual size 
     int x = availableWidth/2; 
     int y = availableHeight/2; 

     final Drawable dial = mDial; 
     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); 
     } 

     dial.setBounds(x - (w/2), y - (h/2), x + (w/2), y + (h/2)); 
     dial.draw(canvas); 

     canvas.save(); 
     canvas.rotate(mHour/12.0f * 360.0f, x, y); 
     w = mHourHand.getIntrinsicWidth(); 
     h = mHourHand.getIntrinsicHeight(); 
     mHourHand.setBounds(x - (w/2), y - (h/2), x + (w/2), y + (h/2)); 
     mHourHand.draw(canvas); 
     canvas.restore(); 

     canvas.save(); 
     canvas.rotate(mMinutes/60.0f * 360.0f, x, y); 
     w = mMinuteHand.getIntrinsicWidth(); 
     h = mMinuteHand.getIntrinsicHeight(); 
     mMinuteHand.setBounds(x - (w/2), y - (h/2), x + (w/2), y + (h/2)); 
     mMinuteHand.draw(canvas); 
     canvas.restore(); 

     canvas.save(); 
     canvas.rotate(mSeconds, x, y); 
     w = mSecondHand.getIntrinsicWidth(); 
     h = mSecondHand.getIntrinsicHeight(); 
     mSecondHand.setBounds(x - (w/2), y - (h/2), x + (w/2), y + (h/2)); 
     mSecondHand.draw(canvas); 
     canvas.restore(); 
     if (scaled) { 
      canvas.restore(); 
     } 
    } 

    public void setTime(int hours, int minutes, int seconds) 
    { 
     mSeconds = 6.0f*seconds; 
     mMinutes = minutes + seconds/60.0f; 
     mHour = hours + mMinutes/60.0f; 
    } 
} 

你也應該把4個繪製文件中繪製的文件夾,並創建(或更新)的值文件夾中的attrs文件用下面的代碼:

<?xml version="1.0" encoding="UTF-8"?> 
<resources> 
    <declare-styleable name="AnalogClock"> 
     <attr name="dial" format="reference"/> 
     <attr name="hand_hour" format="reference"/> 
     <attr name="hand_minute" format="reference"/> 
    </declare-styleable> 
    </resources> 
+0

可繪製:http://speedy.sh/3kSPu/clock-drawable.zip – Marek

+0

感謝您的漂亮代碼,現在我的問題是如何更改時間觸摸方法(偵聽器)或調用setTime()方法。 在此先感謝 –

+0

它取決於什麼時候你想要改變時間(你希望它被改變的聯繫?) – Marek

0
//Here you can set the size of your clock 
int availableWidth = 70; 
int availableHeight = 70; 

在這裏,你可以更改視圖的大小。

相關問題