Android Open Source - android-class Circle Timer View






From Project

Back to project page android-class.

License

The source code is released under:

MIT License

If you think the Android project android-class listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.android.deskclock;
//from   w w  w  .  jav a 2 s.com
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

import com.android.deskclock.stopwatch.Stopwatches;

/**
 * TODO: Insert description here. (generated by isaackatz)
 */
public class CircleTimerView extends View {


    private int mRedColor;
    private int mWhiteColor;
    private long mIntervalTime = 0;
    private long mIntervalStartTime = -1;
    private long mMarkerTime = -1;
    private long mCurrentIntervalTime = 0;
    private long mAccumulatedTime = 0;
    private boolean mPaused = false;
    private boolean mAnimate = false;
    private static float mCircleXCenterLeftPadding = 0;
    private static float mStrokeSize = 4;
    private static float mDiamondStrokeSize = 12;
    private static float mMarkerStrokeSize = 2;
    private final Paint mPaint = new Paint();
    private final Paint mFill = new Paint();
    private final RectF mArcRect = new RectF();
    private float mRectHalfWidth = 6f;
    private Resources mResources;
    private float mRadiusOffset;   // amount to remove from radius to account for markers on circle
    private float mScreenDensity;

    // Class has 2 modes:
    // Timer mode - counting down. in this mode the animation is counter-clockwise and stops at 0
    // Stop watch mode - counting up - in this mode the animation is clockwise and will keep the
    //                   animation until stopped.
    private boolean mTimerMode = false; // default is stop watch view

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

    public CircleTimerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public void setIntervalTime(long t) {
        mIntervalTime = t;
        postInvalidate();
    }

    public void setMarkerTime(long t) {
        mMarkerTime = t;
        postInvalidate();
    }

    public void reset() {
        mIntervalStartTime = -1;
        mMarkerTime = -1;
        postInvalidate();
    }
    public void startIntervalAnimation() {
        mIntervalStartTime = Utils.getTimeNow();
        mAnimate = true;
        invalidate();
        mPaused = false;
    }
    public void stopIntervalAnimation() {
        mAnimate = false;
        mIntervalStartTime = -1;
        mAccumulatedTime = 0;
    }

    public boolean isAnimating() {
        return (mIntervalStartTime != -1);
    }

    public void pauseIntervalAnimation() {
        mAnimate = false;
        mAccumulatedTime += Utils.getTimeNow() - mIntervalStartTime;
        mPaused = true;
    }

    public void abortIntervalAnimation() {
        mAnimate = false;
    }

    public void setPassedTime(long time, boolean drawRed) {
        // The onDraw() method checks if mIntervalStartTime has been set before drawing any red.
        // Without drawRed, mIntervalStartTime should not be set here at all, and would remain at -1
        // when the state is reconfigured after exiting and re-entering the application.
        // If the timer is currently running, this drawRed will not be set, and will have no effect
        // because mIntervalStartTime will be set when the thread next runs.
        // When the timer is not running, mIntervalStartTime will not be set upon loading the state,
        // and no red will be drawn, so drawRed is used to force onDraw() to draw the red portion,
        // despite the timer not running.
        mCurrentIntervalTime = mAccumulatedTime = time;
        if (drawRed) {
            mIntervalStartTime = Utils.getTimeNow();
        }
        postInvalidate();
    }



    private void init(Context c) {

        mResources = c.getResources();
        mCircleXCenterLeftPadding = (mResources.getDimension(R.dimen.timer_circle_width)
                - mResources.getDimension(R.dimen.timer_circle_diameter)) / 2;
        mStrokeSize = mResources.getDimension(R.dimen.circletimer_circle_size);
        mDiamondStrokeSize = mResources.getDimension(R.dimen.circletimer_diamond_size);
        mMarkerStrokeSize = mResources.getDimension(R.dimen.circletimer_marker_size);
        mRadiusOffset = Utils.calculateRadiusOffset(
                mStrokeSize, mDiamondStrokeSize, mMarkerStrokeSize);
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mWhiteColor = mResources.getColor(R.color.clock_white);
        mRedColor = mResources.getColor(R.color.clock_red);
        mScreenDensity = mResources.getDisplayMetrics().density;
        mFill.setAntiAlias(true);
        mFill.setStyle(Paint.Style.FILL);
        mFill.setColor(mRedColor);
        mRectHalfWidth = mDiamondStrokeSize / 2f;
    }

    public void setTimerMode(boolean mode) {
        mTimerMode = mode;
    }

    @Override
    public void onDraw(Canvas canvas) {
        int xCenter = getWidth() / 2 + 1;
        int yCenter = getHeight() / 2;

        mPaint.setStrokeWidth(mStrokeSize);
        float radius = Math.min(xCenter, yCenter) - mRadiusOffset;

        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            xCenter = (int) (radius + mRadiusOffset);
            if (mTimerMode) {
                xCenter += mCircleXCenterLeftPadding;
            }
        }

        if (mIntervalStartTime == -1) {
            // just draw a complete white circle, no red arc needed
            mPaint.setColor(mWhiteColor);
            canvas.drawCircle (xCenter, yCenter, radius, mPaint);
            if (mTimerMode) {
                drawRedDiamond(canvas, 0f, xCenter, yCenter, radius);
            }
        } else {
            if (mAnimate) {
                mCurrentIntervalTime = Utils.getTimeNow() - mIntervalStartTime + mAccumulatedTime;
            }
            //draw a combination of red and white arcs to create a circle
            mArcRect.top = yCenter - radius;
            mArcRect.bottom = yCenter + radius;
            mArcRect.left =  xCenter - radius;
            mArcRect.right = xCenter + radius;
            float redPercent = (float)mCurrentIntervalTime / (float)mIntervalTime;
            // prevent timer from doing more than one full circle
            redPercent = (redPercent > 1 && mTimerMode) ? 1 : redPercent;

            float whitePercent = 1 - (redPercent > 1 ? 1 : redPercent);
            // draw red arc here
            mPaint.setColor(mRedColor);
            if (mTimerMode){
                canvas.drawArc (mArcRect, 270, - redPercent * 360 , false, mPaint);
            } else {
                canvas.drawArc (mArcRect, 270, + redPercent * 360 , false, mPaint);
            }

            // draw white arc here
            mPaint.setStrokeWidth(mStrokeSize);
            mPaint.setColor(mWhiteColor);
            if (mTimerMode) {
                canvas.drawArc(mArcRect, 270, + whitePercent * 360, false, mPaint);
            } else {
                canvas.drawArc(mArcRect, 270 + (1 - whitePercent) * 360,
                        whitePercent * 360, false, mPaint);
            }

            if (mMarkerTime != -1 && radius > 0 && mIntervalTime != 0) {
                mPaint.setStrokeWidth(mMarkerStrokeSize);
                float angle = (float)(mMarkerTime % mIntervalTime) / (float)mIntervalTime * 360;
                // draw 2dips thick marker
                // the formula to draw the marker 1 unit thick is:
                // 180 / (radius * Math.PI)
                // after that we have to scale it by the screen density
                canvas.drawArc (mArcRect, 270 + angle, mScreenDensity *
                        (float) (360 / (radius * Math.PI)) , false, mPaint);
            }
            drawRedDiamond(canvas, redPercent, xCenter, yCenter, radius);
        }
        if (mAnimate) {
            invalidate();
        }
   }

    protected void drawRedDiamond(
            Canvas canvas, float degrees, int xCenter, int yCenter, float radius) {
        mPaint.setColor(mRedColor);
        float diamondPercent;
        if (mTimerMode) {
            diamondPercent = 270 - degrees * 360;
        } else {
            diamondPercent = 270 + degrees * 360;
        }

        canvas.save();
        final double diamondRadians = Math.toRadians(diamondPercent);
        canvas.translate(xCenter + (float) (radius * Math.cos(diamondRadians)),
                yCenter + (float) (radius * Math.sin(diamondRadians)));
        canvas.rotate(diamondPercent + 45f);
        canvas.drawRect(-mRectHalfWidth, -mRectHalfWidth, mRectHalfWidth, mRectHalfWidth, mFill);
        canvas.restore();
    }

    public static final String PREF_CTV_PAUSED  = "_ctv_paused";
    public static final String PREF_CTV_INTERVAL  = "_ctv_interval";
    public static final String PREF_CTV_INTERVAL_START = "_ctv_interval_start";
    public static final String PREF_CTV_CURRENT_INTERVAL = "_ctv_current_interval";
    public static final String PREF_CTV_ACCUM_TIME = "_ctv_accum_time";
    public static final String PREF_CTV_TIMER_MODE = "_ctv_timer_mode";
    public static final String PREF_CTV_MARKER_TIME = "_ctv_marker_time";

    // Since this view is used in multiple places, use the key to save different instances
    public void writeToSharedPref(SharedPreferences prefs, String key) {
        SharedPreferences.Editor editor = prefs.edit();
        editor.putBoolean (key + PREF_CTV_PAUSED, mPaused);
        editor.putLong (key + PREF_CTV_INTERVAL, mIntervalTime);
        editor.putLong (key + PREF_CTV_INTERVAL_START, mIntervalStartTime);
        editor.putLong (key + PREF_CTV_CURRENT_INTERVAL, mCurrentIntervalTime);
        editor.putLong (key + PREF_CTV_ACCUM_TIME, mAccumulatedTime);
        editor.putLong (key + PREF_CTV_MARKER_TIME, mMarkerTime);
        editor.putBoolean (key + PREF_CTV_TIMER_MODE, mTimerMode);
        editor.apply();
    }

    public void readFromSharedPref(SharedPreferences prefs, String key) {
        mPaused = prefs.getBoolean(key + PREF_CTV_PAUSED, false);
        mIntervalTime = prefs.getLong(key + PREF_CTV_INTERVAL, 0);
        mIntervalStartTime = prefs.getLong(key + PREF_CTV_INTERVAL_START, -1);
        mCurrentIntervalTime = prefs.getLong(key + PREF_CTV_CURRENT_INTERVAL, 0);
        mAccumulatedTime = prefs.getLong(key + PREF_CTV_ACCUM_TIME, 0);
        mMarkerTime = prefs.getLong(key + PREF_CTV_MARKER_TIME, -1);
        mTimerMode = prefs.getBoolean(key + PREF_CTV_TIMER_MODE, false);
        mAnimate = (mIntervalStartTime != -1 && !mPaused);
    }

    public void clearSharedPref(SharedPreferences prefs, String key) {
        SharedPreferences.Editor editor = prefs.edit();
        editor.remove (Stopwatches.PREF_START_TIME);
        editor.remove (Stopwatches.PREF_ACCUM_TIME);
        editor.remove (Stopwatches.PREF_STATE);
        editor.remove (key + PREF_CTV_PAUSED);
        editor.remove (key + PREF_CTV_INTERVAL);
        editor.remove (key + PREF_CTV_INTERVAL_START);
        editor.remove (key + PREF_CTV_CURRENT_INTERVAL);
        editor.remove (key + PREF_CTV_ACCUM_TIME);
        editor.remove (key + PREF_CTV_MARKER_TIME);
        editor.remove (key + PREF_CTV_TIMER_MODE);
        editor.apply();
    }
}




Java Source Code List

com.android.alarmclock.AnalogAppWidgetProvider.java
com.android.alarmclock.DigitalAppWidgetProvider.java
com.android.alarmclock.DigitalAppWidgetService.java
com.android.alarmclock.DigitalWidgetViewsFactory.java
com.android.alarmclock.WidgetUtils.java
com.android.deskclock.AlarmAlertFullScreen.java
com.android.deskclock.AlarmAlertWakeLock.java
com.android.deskclock.AlarmAlert.java
com.android.deskclock.AlarmClock.java
com.android.deskclock.AlarmDatabaseHelper.java
com.android.deskclock.AlarmInitReceiver.java
com.android.deskclock.AlarmKlaxon.java
com.android.deskclock.AlarmListeners.java
com.android.deskclock.AlarmPreference.java
com.android.deskclock.AlarmProvider.java
com.android.deskclock.AlarmReceiver.java
com.android.deskclock.AlarmTimePickerDialogFragment.java
com.android.deskclock.AlarmUtils.java
com.android.deskclock.Alarm.java
com.android.deskclock.Alarms.java
com.android.deskclock.AnalogClock.java
com.android.deskclock.AndroidClockTextView.java
com.android.deskclock.AsyncHandler.java
com.android.deskclock.CircleButtonsLinearLayout.java
com.android.deskclock.CircleTimerView.java
com.android.deskclock.ClockFragment.java
com.android.deskclock.DeskClockFragment.java
com.android.deskclock.DeskClock.java
com.android.deskclock.DigitalClock.java
com.android.deskclock.DontPressWithParentLayout.java
com.android.deskclock.HandleSetAlarm.java
com.android.deskclock.LabelDialogFragment.java
com.android.deskclock.Log.java
com.android.deskclock.RepeatPreference.java
com.android.deskclock.ScreensaverActivity.java
com.android.deskclock.ScreensaverSettingsActivity.java
com.android.deskclock.Screensaver.java
com.android.deskclock.SetAlarm.java
com.android.deskclock.SettingsActivity.java
com.android.deskclock.SnoozeLengthDialog.java
com.android.deskclock.TimePicker.java
com.android.deskclock.TimerRingService.java
com.android.deskclock.TimerSetupView.java
com.android.deskclock.ToastMaster.java
com.android.deskclock.Utils.java
com.android.deskclock.ZeroTopPaddingTextView.java
com.android.deskclock.stopwatch.StopwatchFragment.java
com.android.deskclock.stopwatch.StopwatchService.java
com.android.deskclock.stopwatch.Stopwatches.java
com.android.deskclock.timer.CountingTimerView.java
com.android.deskclock.timer.TimerAlertFullScreen.java
com.android.deskclock.timer.TimerFragment.java
com.android.deskclock.timer.TimerListItem.java
com.android.deskclock.timer.TimerObj.java
com.android.deskclock.timer.TimerReceiver.java
com.android.deskclock.timer.TimerView.java
com.android.deskclock.timer.Timers.java
com.android.deskclock.widget.ActionableToastBar.java
com.android.deskclock.widget.EllipsizeLayout.java
com.android.deskclock.widget.multiwaveview.Ease.java
com.android.deskclock.widget.multiwaveview.GlowPadView.java
com.android.deskclock.widget.multiwaveview.PointCloud.java
com.android.deskclock.widget.multiwaveview.TargetDrawable.java
com.android.deskclock.widget.multiwaveview.Tweener.java
com.android.deskclock.widget.swipeablelistview.LogTag.java
com.android.deskclock.widget.swipeablelistview.LogUtils.java
com.android.deskclock.widget.swipeablelistview.SwipeHelper.java
com.android.deskclock.widget.swipeablelistview.SwipeLayout.java
com.android.deskclock.widget.swipeablelistview.SwipeableListView.java
com.android.deskclock.widget.swipeablelistview.Utils.java
com.android.deskclock.worldclock.CitiesActivity.java
com.android.deskclock.worldclock.Cities.java
com.android.deskclock.worldclock.CityObj.java
com.android.deskclock.worldclock.WorldClockAdapter.java
com.google.android.wikinotes.Eula.java
com.google.android.wikinotes.WikiActivityHelper.java
com.google.android.wikinotes.WikiNoteEditor.java
com.google.android.wikinotes.WikiNotesList.java
com.google.android.wikinotes.WikiNotes.java
com.google.android.wikinotes.db.WikiNote.java
com.google.android.wikinotes.db.WikiNotesProvider.java
com.mamlambo.article.simplecalc.MainActivity.java
course.examples.theanswer.TheAnswer.java
course.examples.theanswer.TheAnswer.java
us.clanryan.coursera.myfirstapp.MainActivity.java
us.clanryan.paceconverter.MainActivity.java