mirror of
https://gitee.com/51danju/workclock.git
synced 2025-07-16 22:07:29 +08:00
增加 计时、倒计时,时间变更动画和几个指针样式
This commit is contained in:
parent
6e9ddaa968
commit
45a2ab6701
@ -12,8 +12,6 @@ import android.os.PowerManager;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.support.v4.app.ActivityCompat;
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.text.Spannable;
|
|
||||||
import android.text.SpannableString;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.GestureDetector;
|
import android.view.GestureDetector;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
@ -40,6 +38,7 @@ import com.luck.picture.lib.entity.LocalMedia;
|
|||||||
|
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
@ -63,13 +62,14 @@ import clock.socoolby.com.clock.widget.animatorview.animator.BubbleWhirlPoolAnim
|
|||||||
import clock.socoolby.com.clock.widget.animatorview.animator.CarrouselAnimator;
|
import clock.socoolby.com.clock.widget.animatorview.animator.CarrouselAnimator;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.ClockAnimator;
|
import clock.socoolby.com.clock.widget.animatorview.animator.ClockAnimator;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.DotsLineAnimator;
|
import clock.socoolby.com.clock.widget.animatorview.animator.DotsLineAnimator;
|
||||||
|
import clock.socoolby.com.clock.widget.animatorview.animator.MagicLineAnimator;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.PhaserBallAnimator;
|
import clock.socoolby.com.clock.widget.animatorview.animator.PhaserBallAnimator;
|
||||||
|
import clock.socoolby.com.clock.widget.animatorview.animator.SawtoothAnimator;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.Wave3DAnimator;
|
import clock.socoolby.com.clock.widget.animatorview.animator.Wave3DAnimator;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.AbstractClock;
|
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.CircleClock;
|
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.CircleClock;
|
||||||
|
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.CircleTwoClock;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.HelixClock;
|
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.HelixClock;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.HexagonalClock;
|
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.HexagonalClock;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.OctagonalClock;
|
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.OvalClock;
|
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.OvalClock;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.SquareClock;
|
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.SquareClock;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.textanimator.EZLedAnimator;
|
import clock.socoolby.com.clock.widget.animatorview.animator.textanimator.EZLedAnimator;
|
||||||
@ -77,7 +77,6 @@ import clock.socoolby.com.clock.widget.animatorview.animator.FireAnimator;
|
|||||||
import clock.socoolby.com.clock.widget.animatorview.animator.FireworkAnimator;
|
import clock.socoolby.com.clock.widget.animatorview.animator.FireworkAnimator;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.FluorescenceAnimator;
|
import clock.socoolby.com.clock.widget.animatorview.animator.FluorescenceAnimator;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.RainAnimator;
|
import clock.socoolby.com.clock.widget.animatorview.animator.RainAnimator;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.RippleAnimator;
|
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.SkyAnimator;
|
import clock.socoolby.com.clock.widget.animatorview.animator.SkyAnimator;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.SnowAnimator;
|
import clock.socoolby.com.clock.widget.animatorview.animator.SnowAnimator;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.StarFallAnimator;
|
import clock.socoolby.com.clock.widget.animatorview.animator.StarFallAnimator;
|
||||||
@ -85,7 +84,6 @@ import clock.socoolby.com.clock.widget.animatorview.animator.VorolayAnimator;
|
|||||||
import clock.socoolby.com.clock.widget.animatorview.animator.WaterAnimator;
|
import clock.socoolby.com.clock.widget.animatorview.animator.WaterAnimator;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.WindmillAnimator;
|
import clock.socoolby.com.clock.widget.animatorview.animator.WindmillAnimator;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.textanimator.EvaporateTextAnimator;
|
import clock.socoolby.com.clock.widget.animatorview.animator.textanimator.EvaporateTextAnimator;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.textanimator.PathEffectTextAnimator;
|
|
||||||
import clock.socoolby.com.clock.widget.textview.AutoScrollTextView;
|
import clock.socoolby.com.clock.widget.textview.AutoScrollTextView;
|
||||||
import clock.socoolby.com.clock.widget.textview.DigitTextView;
|
import clock.socoolby.com.clock.widget.textview.DigitTextView;
|
||||||
|
|
||||||
@ -311,6 +309,14 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
private Integer foregroundColor;
|
private Integer foregroundColor;
|
||||||
private FrameLayout mainBackground;
|
private FrameLayout mainBackground;
|
||||||
|
|
||||||
|
private ImageButton tv_break;
|
||||||
|
private Date countingDateTimeBase =null;
|
||||||
|
|
||||||
|
private ShowTimeType showTimeType=ShowTimeType.TIME;
|
||||||
|
|
||||||
|
public enum ShowTimeType{
|
||||||
|
TIME,COUNTING_DOWN,COUNTING;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setWeather(WeatherResponse weather) {
|
public void setWeather(WeatherResponse weather) {
|
||||||
@ -378,6 +384,21 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tv_break=findViewById(R.id.tv_break);
|
||||||
|
tv_break.setOnClickListener(this);
|
||||||
|
tv_break.setOnLongClickListener(new View.OnLongClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View v) {
|
||||||
|
if(handUpAbla){
|
||||||
|
if(showTimeType==ShowTimeType.COUNTING_DOWN)
|
||||||
|
setCurrentShowTimeType(ShowTimeType.TIME);
|
||||||
|
else
|
||||||
|
setCurrentShowTimeType(ShowTimeType.COUNTING_DOWN);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
tv_handup=findViewById(R.id.tv_hand);
|
tv_handup=findViewById(R.id.tv_hand);
|
||||||
tv_handup.setOnClickListener(this);
|
tv_handup.setOnClickListener(this);
|
||||||
tv_handup.setOnLongClickListener(new View.OnLongClickListener() {
|
tv_handup.setOnLongClickListener(new View.OnLongClickListener() {
|
||||||
@ -702,6 +723,8 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
tv_hand_time.setTextColor(color);
|
tv_hand_time.setTextColor(color);
|
||||||
tv_hours_system.setColorFilter(color);
|
tv_hours_system.setColorFilter(color);
|
||||||
tv_background_image_hand.setColorFilter(color);
|
tv_background_image_hand.setColorFilter(color);
|
||||||
|
|
||||||
|
tv_break.setColorFilter(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setBackGroundColor(Integer color){
|
protected void setBackGroundColor(Integer color){
|
||||||
@ -765,6 +788,13 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
}
|
}
|
||||||
screenLock(!screenLock);
|
screenLock(!screenLock);
|
||||||
break;
|
break;
|
||||||
|
case R.id.tv_break:
|
||||||
|
if(showTimeType!=ShowTimeType.COUNTING){
|
||||||
|
setCurrentShowTimeType(ShowTimeType.COUNTING);
|
||||||
|
}else{
|
||||||
|
setCurrentShowTimeType(ShowTimeType.TIME);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case R.id.tv_descript:
|
case R.id.tv_descript:
|
||||||
setDiscript(SettingActivity.roundAutoQuotes());
|
setDiscript(SettingActivity.roundAutoQuotes());
|
||||||
break;
|
break;
|
||||||
@ -799,6 +829,14 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCurrentShowTimeType(ShowTimeType type){
|
||||||
|
switch (type){
|
||||||
|
case COUNTING:
|
||||||
|
countingDateTimeBase =new Date();
|
||||||
|
}
|
||||||
|
showTimeType=type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void screenLock(boolean locked){
|
public void screenLock(boolean locked){
|
||||||
screenLock=locked;
|
screenLock=locked;
|
||||||
@ -879,6 +917,8 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
tv_foreground_color.setVisibility(View.GONE);
|
tv_foreground_color.setVisibility(View.GONE);
|
||||||
tv_foreground_color1.setVisibility(View.GONE);
|
tv_foreground_color1.setVisibility(View.GONE);
|
||||||
tv_background_image_hand.setVisibility(View.GONE);
|
tv_background_image_hand.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
tv_break.setVisibility(View.GONE);
|
||||||
}else{
|
}else{
|
||||||
if(clockView.isRunning()) {
|
if(clockView.isRunning()) {
|
||||||
//clockView.setAnimator(null);
|
//clockView.setAnimator(null);
|
||||||
@ -893,6 +933,7 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
tv_handup_image.setVisibility(View.VISIBLE);
|
tv_handup_image.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
tv_handup.setVisibility(View.VISIBLE);
|
tv_handup.setVisibility(View.VISIBLE);
|
||||||
|
tv_break.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
if(prevMode==MODE_HANDUP)
|
if(prevMode==MODE_HANDUP)
|
||||||
switchMode(MODE_NORMAL);
|
switchMode(MODE_NORMAL);
|
||||||
@ -914,7 +955,7 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
DotsLineAnimator dotsLineAnimator;
|
DotsLineAnimator dotsLineAnimator;
|
||||||
WaterAnimator waterAnimator;
|
WaterAnimator waterAnimator;
|
||||||
FireAnimator fireAnimator;
|
FireAnimator fireAnimator;
|
||||||
RippleAnimator rippleAnimator;
|
SawtoothAnimator sawtoothAnimator;
|
||||||
WindmillAnimator windmillAnimator;
|
WindmillAnimator windmillAnimator;
|
||||||
VorolayAnimator vorolayAnimator;
|
VorolayAnimator vorolayAnimator;
|
||||||
EZLedAnimator eZLedAnimator;
|
EZLedAnimator eZLedAnimator;
|
||||||
@ -922,6 +963,7 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
PhaserBallAnimator phaserBallAnimator;
|
PhaserBallAnimator phaserBallAnimator;
|
||||||
CarrouselAnimator carrouselAnimator;
|
CarrouselAnimator carrouselAnimator;
|
||||||
Wave3DAnimator wave3DAnimator;
|
Wave3DAnimator wave3DAnimator;
|
||||||
|
MagicLineAnimator magicLineAnimator;
|
||||||
public void changeBackGroundAnimator(int index){
|
public void changeBackGroundAnimator(int index){
|
||||||
switch(index){
|
switch(index){
|
||||||
case 0:
|
case 0:
|
||||||
@ -942,7 +984,7 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
backGroundAnimator= phaserBallAnimator;
|
backGroundAnimator= phaserBallAnimator;
|
||||||
backGroundAnimator.setRandColor(true);
|
backGroundAnimator.setRandColor(true);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 20:
|
||||||
if(rainAnimator==null) {
|
if(rainAnimator==null) {
|
||||||
rainAnimator = new RainAnimator();
|
rainAnimator = new RainAnimator();
|
||||||
rainAnimator.init(animatorView.getContext(),animatorView);
|
rainAnimator.init(animatorView.getContext(),animatorView);
|
||||||
@ -1095,7 +1137,7 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
backGroundAnimator= dotsLineAnimator;
|
backGroundAnimator= dotsLineAnimator;
|
||||||
backGroundAnimator.setRandColor(true);
|
backGroundAnimator.setRandColor(true);
|
||||||
break;
|
break;
|
||||||
case 20:
|
case 3:
|
||||||
if(waterAnimator ==null) {
|
if(waterAnimator ==null) {
|
||||||
waterAnimator = new WaterAnimator();
|
waterAnimator = new WaterAnimator();
|
||||||
waterAnimator.init(animatorView.getContext(),animatorView);
|
waterAnimator.init(animatorView.getContext(),animatorView);
|
||||||
@ -1123,12 +1165,12 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
backGroundAnimator.setRandColor(false);
|
backGroundAnimator.setRandColor(false);
|
||||||
break;
|
break;
|
||||||
case 23:
|
case 23:
|
||||||
if(rippleAnimator ==null) {
|
if(sawtoothAnimator ==null) {
|
||||||
rippleAnimator = new RippleAnimator();
|
sawtoothAnimator = new SawtoothAnimator();
|
||||||
rippleAnimator.init(animatorView.getContext(),animatorView);
|
sawtoothAnimator.init(animatorView.getContext(),animatorView);
|
||||||
rippleAnimator.setColor(foregroundColor);
|
sawtoothAnimator.setColor(foregroundColor);
|
||||||
}
|
}
|
||||||
backGroundAnimator= rippleAnimator;
|
backGroundAnimator= sawtoothAnimator;
|
||||||
backGroundAnimator.setRandColor(true);
|
backGroundAnimator.setRandColor(true);
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
@ -1158,7 +1200,7 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
backGroundAnimator= carrouselAnimator;
|
backGroundAnimator= carrouselAnimator;
|
||||||
backGroundAnimator.setRandColor(true);
|
backGroundAnimator.setRandColor(true);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 27:
|
||||||
if(wave3DAnimator ==null) {
|
if(wave3DAnimator ==null) {
|
||||||
wave3DAnimator = new Wave3DAnimator();
|
wave3DAnimator = new Wave3DAnimator();
|
||||||
wave3DAnimator.init(animatorView.getContext(),animatorView);
|
wave3DAnimator.init(animatorView.getContext(),animatorView);
|
||||||
@ -1167,6 +1209,24 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
backGroundAnimator= wave3DAnimator;
|
backGroundAnimator= wave3DAnimator;
|
||||||
backGroundAnimator.setRandColor(true);
|
backGroundAnimator.setRandColor(true);
|
||||||
break;
|
break;
|
||||||
|
case 28:
|
||||||
|
if(magicLineAnimator ==null) {
|
||||||
|
magicLineAnimator = new MagicLineAnimator();
|
||||||
|
magicLineAnimator.init(animatorView.getContext(),animatorView);
|
||||||
|
magicLineAnimator.setColor(foregroundColor);
|
||||||
|
}
|
||||||
|
backGroundAnimator= magicLineAnimator;
|
||||||
|
backGroundAnimator.setRandColor(true);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if(magicLineAnimator ==null) {
|
||||||
|
magicLineAnimator = new MagicLineAnimator();
|
||||||
|
magicLineAnimator.init(animatorView.getContext(),animatorView);
|
||||||
|
magicLineAnimator.setColor(foregroundColor);
|
||||||
|
}
|
||||||
|
backGroundAnimator= magicLineAnimator;
|
||||||
|
backGroundAnimator.setRandColor(false);
|
||||||
|
break;
|
||||||
|
|
||||||
case 60:
|
case 60:
|
||||||
if(evaporateTextAnimator ==null) {
|
if(evaporateTextAnimator ==null) {
|
||||||
@ -1205,7 +1265,7 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
clockAnimator = new ClockAnimator();
|
clockAnimator = new ClockAnimator();
|
||||||
clockAnimator.init(clockView.getContext(),clockView);
|
clockAnimator.init(clockView.getContext(),clockView);
|
||||||
clockAnimator.setColor(foregroundColor);
|
clockAnimator.setColor(foregroundColor);
|
||||||
if(index>4)
|
if(index>5)
|
||||||
currentClockAnimatorIndex=index=0;
|
currentClockAnimatorIndex=index=0;
|
||||||
|
|
||||||
switch (index) {
|
switch (index) {
|
||||||
@ -1218,13 +1278,13 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
case 1:
|
case 1:
|
||||||
clockAnimator.setClock(new SquareClock());
|
clockAnimator.setClock(new SquareClock());
|
||||||
break;
|
break;
|
||||||
//case 3:
|
|
||||||
// clockAnimator.setClock(new OctagonalClock());
|
|
||||||
// break;
|
|
||||||
case 3:
|
case 3:
|
||||||
clockAnimator.setClock(new HexagonalClock());
|
clockAnimator.setClock(new CircleTwoClock());
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
|
clockAnimator.setClock(new HexagonalClock());
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
clockAnimator.setClock(new HelixClock());
|
clockAnimator.setClock(new HelixClock());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1245,6 +1305,8 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
}else{
|
}else{
|
||||||
this.tv_handup.setColorFilter(R.color.colorPrimaryDark);
|
this.tv_handup.setColorFilter(R.color.colorPrimaryDark);
|
||||||
this.tv_hand_time.setVisibility(View.GONE);
|
this.tv_hand_time.setVisibility(View.GONE);
|
||||||
|
if(showTimeType==ShowTimeType.COUNTING_DOWN)
|
||||||
|
setCurrentShowTimeType(ShowTimeType.TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1354,6 +1416,9 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
handUPDialy--;
|
handUPDialy--;
|
||||||
if(handUPDialy==0) {
|
if(handUPDialy==0) {
|
||||||
switchMode(MODE_NORMAL);
|
switchMode(MODE_NORMAL);
|
||||||
|
if(!isArtificialHiddle&&showTimeType==ShowTimeType.TIME){
|
||||||
|
setCurrentShowTimeType(ShowTimeType.COUNTING);
|
||||||
|
}
|
||||||
}else
|
}else
|
||||||
Player.getInstance().playHandUp(this);
|
Player.getInstance().playHandUp(this);
|
||||||
return;
|
return;
|
||||||
@ -1387,7 +1452,19 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
private void updateTime() {
|
private void updateTime() {
|
||||||
heartbeat=!heartbeat;
|
heartbeat=!heartbeat;
|
||||||
DateModel date = new DateModel();
|
DateModel date = new DateModel();
|
||||||
String timeString = model.isDisplaySecond() ? date.getTimeString(model.isHourSystem12()) : date.getShortTimeString(heartbeat,model.isHourSystem12());
|
String timeString=null;
|
||||||
|
switch (showTimeType){
|
||||||
|
case COUNTING:
|
||||||
|
DateModel temp=new DateModel(countingDateTimeBase);
|
||||||
|
timeString=temp.getTimeString(false);
|
||||||
|
break;
|
||||||
|
case COUNTING_DOWN:
|
||||||
|
timeString=DateModel.getTimeFull(handUpTime);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
timeString = model.isDisplaySecond() ? date.getTimeString(model.isHourSystem12()) : date.getShortTimeString(heartbeat,model.isHourSystem12());
|
||||||
|
break;
|
||||||
|
}
|
||||||
setCurrentTimeToView(timeString);
|
setCurrentTimeToView(timeString);
|
||||||
reportTime(date);
|
reportTime(date);
|
||||||
updateDay(date);
|
updateDay(date);
|
||||||
@ -1607,6 +1684,9 @@ public class MainActivity extends Activity implements Handler.Callback, View.OnC
|
|||||||
if(!isArtificialHiddle) {
|
if(!isArtificialHiddle) {
|
||||||
tv_time.setLinearGradientRandom(!tv_time.isLinearGradientAble());
|
tv_time.setLinearGradientRandom(!tv_time.isLinearGradientAble());
|
||||||
return true;
|
return true;
|
||||||
|
}else if(clockAnimator!=null){
|
||||||
|
clockAnimator.randPointer();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,14 @@ public class DateModel implements Serializable {
|
|||||||
private int second = 0;
|
private int second = 0;
|
||||||
|
|
||||||
public DateModel() {
|
public DateModel() {
|
||||||
setDataString(getNowWithTime());
|
Calendar c1 = Calendar.getInstance(); //当前日期
|
||||||
|
year=c1.get(Calendar.YEAR);
|
||||||
|
month=c1.get(Calendar.MONTH)+1;
|
||||||
|
day=c1.get(Calendar.DAY_OF_MONTH);
|
||||||
|
hour=c1.get(Calendar.HOUR_OF_DAY);
|
||||||
|
minute=c1.get(Calendar.MINUTE);
|
||||||
|
second=c1.get(Calendar.SECOND);
|
||||||
|
//setDataString(getNowWithTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
public DateModel(int year, int month, int day) {
|
public DateModel(int year, int month, int day) {
|
||||||
@ -28,6 +35,15 @@ public class DateModel implements Serializable {
|
|||||||
this.day = day;
|
this.day = day;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DateModel(Date base) {
|
||||||
|
Date date=new Date();
|
||||||
|
int between = new Long(date.getTime() - base.getTime()).intValue();
|
||||||
|
day = between / (24 * 60 * 60 * 1000);
|
||||||
|
hour = (between / (60 * 60 * 1000) - day * 24);
|
||||||
|
minute = ((between / (60 * 1000)) - day * 24 * 60 - hour * 60);
|
||||||
|
second = (between / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param timeString 12:00 || 12:00:00
|
* @param timeString 12:00 || 12:00:00
|
||||||
*/
|
*/
|
||||||
@ -144,6 +160,14 @@ public class DateModel implements Serializable {
|
|||||||
return String.format("%02d:%02d:%02d", hours, minutes, second);
|
return String.format("%02d:%02d:%02d", hours, minutes, second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getTimeFull(int second){
|
||||||
|
long hours = second / 3600;//转换小时数
|
||||||
|
second = second % 3600;//剩余秒数
|
||||||
|
long minutes = second / 60;//转换分钟
|
||||||
|
second = second % 60;//剩余秒数
|
||||||
|
return String.format("%02d:%02d:%02d", hours, minutes, second);
|
||||||
|
}
|
||||||
|
|
||||||
public int minusTime(DateModel strEnd) {
|
public int minusTime(DateModel strEnd) {
|
||||||
SimpleDateFormat df = new SimpleDateFormat("HH:mm");
|
SimpleDateFormat df = new SimpleDateFormat("HH:mm");
|
||||||
Date d1 = null;
|
Date d1 = null;
|
||||||
@ -155,7 +179,6 @@ public class DateModel implements Serializable {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return (int) ((d2.getTime() - d1.getTime()) / DateUtils.SECOND_IN_MILLIS);
|
return (int) ((d2.getTime() - d1.getTime()) / DateUtils.SECOND_IN_MILLIS);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,6 +3,13 @@ package clock.socoolby.com.clock.widget.animatorview.animator;
|
|||||||
|
|
||||||
import clock.socoolby.com.clock.widget.animatorview.AbstractAnimator;
|
import clock.socoolby.com.clock.widget.animatorview.AbstractAnimator;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.AbstractClock;
|
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.AbstractClock;
|
||||||
|
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.pointer.DefaultPointer;
|
||||||
|
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.pointer.LeafPointer;
|
||||||
|
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.pointer.LeafTwoPointer;
|
||||||
|
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.pointer.SecondTailPointer;
|
||||||
|
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.pointer.SwordPointer;
|
||||||
|
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.pointer.TrianglePointer;
|
||||||
|
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.pointer.TwoStepPointer;
|
||||||
|
|
||||||
// 参考自:https://github.com/ifadai/ClockDemo
|
// 参考自:https://github.com/ifadai/ClockDemo
|
||||||
public class ClockAnimator extends AbstractAnimator<AbstractClock> {
|
public class ClockAnimator extends AbstractAnimator<AbstractClock> {
|
||||||
@ -35,4 +42,35 @@ public class ClockAnimator extends AbstractAnimator<AbstractClock> {
|
|||||||
clock.init(width,height,width/2,height/2,minHigh/2,color,textColor);
|
clock.init(width,height,width/2,height/2,minHigh/2,color,textColor);
|
||||||
list.add(clock);
|
list.add(clock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int randPointerIndex=1;
|
||||||
|
public void randPointer(){
|
||||||
|
if(clock==null)
|
||||||
|
return;
|
||||||
|
if(randPointerIndex>6)
|
||||||
|
randPointerIndex=0;
|
||||||
|
switch (randPointerIndex){
|
||||||
|
case 1:
|
||||||
|
clock.setPointer(new SecondTailPointer());
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
clock.setPointer(new TrianglePointer());
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
clock.setPointer(new SwordPointer());
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
clock.setPointer(new TwoStepPointer());
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
clock.setPointer(new LeafPointer());
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
clock.setPointer(new LeafTwoPointer());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
clock.setPointer(new DefaultPointer());
|
||||||
|
}
|
||||||
|
randPointerIndex++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,156 @@
|
|||||||
|
package clock.socoolby.com.clock.widget.animatorview.animator;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import clock.socoolby.com.clock.widget.animatorview.AbstractCacheDifferenceAnimator;
|
||||||
|
import clock.socoolby.com.clock.widget.animatorview.I_AnimatorEntry;
|
||||||
|
|
||||||
|
|
||||||
|
//引用自:https://github.com/zhangyuChen1991/MagicLine
|
||||||
|
public class MagicLineAnimator extends AbstractCacheDifferenceAnimator<MagicLineAnimator.MagicLine, MagicLineAnimator.CorrdinateData> {
|
||||||
|
|
||||||
|
|
||||||
|
public MagicLineAnimator() {
|
||||||
|
super(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MagicLine createNewEntry() {
|
||||||
|
return new MagicLine(width,height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float[][] demos={{400,400,0.05f,200,200,0.35f},
|
||||||
|
{450,450,0.5f,450,450,0.15f},
|
||||||
|
{450,450,1.0f,150,150,0.15f},
|
||||||
|
{320,320,0.025f,320,80,0.06f},
|
||||||
|
{450,450,1.0f,150,150,0.15f},
|
||||||
|
{90, 90,0.5f, 450, 450, 0.15f},
|
||||||
|
{200, 200, 0.55f, 450, 450, 0.15f},
|
||||||
|
{450, 150, 0.15f, 150, 450, 0.05f},
|
||||||
|
{200, 500, 0.4f, 500, 200, 0.4f}
|
||||||
|
};
|
||||||
|
|
||||||
|
public class MagicLine implements I_AnimatorEntry {
|
||||||
|
|
||||||
|
//起点在x、y移动范围
|
||||||
|
private float p1XLength = 400, p1YLength = 20, speedP1 = 0.15f;
|
||||||
|
private float p2XLength = 20, p2YLength = 400, speedP2 = 0.05f;
|
||||||
|
private double angleP1 = 0, angleP2 = 0;
|
||||||
|
private int viewWidth, viewHeight;
|
||||||
|
private Paint paint;
|
||||||
|
//记录移动过的所有点的数据
|
||||||
|
private List<CorrdinateData> corrDatas;
|
||||||
|
//动画绘制的时间
|
||||||
|
private int animDuration = 600;
|
||||||
|
|
||||||
|
public MagicLine(int viewWidth, int viewHeight) {
|
||||||
|
this.viewWidth = viewWidth;
|
||||||
|
this.viewHeight = viewHeight;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void move(int maxWidth, int maxHight) {
|
||||||
|
calculate();
|
||||||
|
animDuration--;
|
||||||
|
if(animDuration==0) {
|
||||||
|
animDuration = 600;
|
||||||
|
reStartDraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDraw(Canvas canvas, Paint mPaint) {
|
||||||
|
for (int i = 0; i < corrDatas.size(); i++) {
|
||||||
|
CorrdinateData cd = corrDatas.get(i);
|
||||||
|
paint.setColor(cd.color);
|
||||||
|
canvas.drawLine(cd.p1X, cd.p1Y, cd.p2X, cd.p2Y, paint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
paint = new Paint();
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
paint.setStrokeWidth(2);
|
||||||
|
paint.setStyle(Paint.Style.FILL);
|
||||||
|
//paint.setColor(Color.WHITE);
|
||||||
|
paint.setAlpha(50);
|
||||||
|
// Shader shader = new LinearGradient(cd.p1X, cd.p1Y, cd.p2X, cd.p2Y, colors, null, Shader.TileMode.MIRROR);
|
||||||
|
// paint.setShader(shader);
|
||||||
|
corrDatas = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始绘制
|
||||||
|
*/
|
||||||
|
public void reStartDraw() {
|
||||||
|
moveToTrashCache(corrDatas);
|
||||||
|
corrDatas.clear();
|
||||||
|
|
||||||
|
int demoIndex=rand.nextInt(demos.length);
|
||||||
|
p1XLength = demos[demoIndex][0];
|
||||||
|
p1YLength = demos[demoIndex][1];
|
||||||
|
speedP1 = demos[demoIndex][2];
|
||||||
|
p2XLength = demos[demoIndex][3];
|
||||||
|
p2YLength = demos[demoIndex][4];
|
||||||
|
speedP2 = demos[demoIndex][5];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算坐标值
|
||||||
|
*/
|
||||||
|
private void calculate() {
|
||||||
|
angleP1 = angleP1 + speedP1;
|
||||||
|
angleP2 = angleP2 + speedP2;
|
||||||
|
|
||||||
|
//两个点的位置更新
|
||||||
|
float nowP1X = (float) (p1XLength * Math.cos(angleP1) + viewWidth / 2f);
|
||||||
|
float nowP1Y = (float) (p1YLength * Math.sin(angleP1) + viewHeight / 2f);
|
||||||
|
float nowP2X = (float) (p2XLength * Math.cos(angleP2) + viewWidth / 2f);
|
||||||
|
float nowP2Y = (float) (p2YLength * Math.sin(angleP2) + viewHeight / 2f);
|
||||||
|
|
||||||
|
CorrdinateData corrdinataData =revectForTrashCache();
|
||||||
|
randomColorIfAble();
|
||||||
|
if(corrdinataData!=null)
|
||||||
|
corrdinataData.init(nowP1X, nowP1Y, nowP2X, nowP2Y,color);
|
||||||
|
else
|
||||||
|
corrdinataData=new CorrdinateData(nowP1X, nowP1Y, nowP2X, nowP2Y,color);
|
||||||
|
corrDatas.add(corrdinataData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置参数
|
||||||
|
*/
|
||||||
|
public void setParam(float p1XLength, float p1YLength, float p2XLength, float p2YLength, float speedP1, float speedP2) {
|
||||||
|
this.p1XLength = p1XLength;
|
||||||
|
this.p1YLength = p1YLength;
|
||||||
|
this.p2XLength = p2XLength;
|
||||||
|
this.p2YLength = p2YLength;
|
||||||
|
this.speedP1 = speedP1;
|
||||||
|
this.speedP2 = speedP2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CorrdinateData {
|
||||||
|
float p1X, p1Y, p2X, p2Y;
|
||||||
|
int color;
|
||||||
|
|
||||||
|
CorrdinateData(float p1X, float p1Y, float p2X, float p2Y,int color) {
|
||||||
|
init(p1X,p1Y,p2X,p2Y,color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(float p1X, float p1Y, float p2X, float p2Y,int color) {
|
||||||
|
this.p1X = p1X;
|
||||||
|
this.p1Y = p1Y;
|
||||||
|
this.p2X = p2X;
|
||||||
|
this.p2Y = p2Y;
|
||||||
|
this.color=color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,314 @@
|
|||||||
|
package clock.socoolby.com.clock.widget.animatorview.animator;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
|
import android.graphics.PorterDuffXfermode;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
|
||||||
|
import clock.socoolby.com.clock.widget.animatorview.AbstractAnimator;
|
||||||
|
import clock.socoolby.com.clock.widget.animatorview.I_AnimatorEntry;
|
||||||
|
|
||||||
|
//参考自:http://refactor.cn/2016/12/26/GearMachine-Canvas绘制漂亮的齿轮装置/
|
||||||
|
public class SawtoothAnimator extends AbstractAnimator<SawtoothAnimator.Sawtooth> {
|
||||||
|
|
||||||
|
public SawtoothAnimator() {
|
||||||
|
super(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Sawtooth createNewEntry() {
|
||||||
|
return new Sawtooth(width,height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int dialyTime() {
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Sawtooth implements I_AnimatorEntry {
|
||||||
|
private static final int X = 0;
|
||||||
|
private static final int Y = 1;
|
||||||
|
|
||||||
|
private float mTopCircleRadius;
|
||||||
|
private float mBottomBigCircleRadius;
|
||||||
|
private Paint mRedPaint, mDarkRedPaint, mStrokePaint, mBeltPaint;
|
||||||
|
|
||||||
|
private Paint mTransitionPaint, mTransitionDarkPaint;
|
||||||
|
private Path mBigSawtoothPath, mSmallSawtoothPath;
|
||||||
|
private Path mLeftTopTrianglePath, mRightTopTrianglePath, mBarPath, mSmallBarPath;
|
||||||
|
|
||||||
|
private float mCurProgress;
|
||||||
|
private RectF mShadeRectF;
|
||||||
|
private PorterDuffXfermode mClearXfermode;
|
||||||
|
|
||||||
|
private int width,hight;
|
||||||
|
|
||||||
|
public Sawtooth(int width, int hight) {
|
||||||
|
this.width = width;
|
||||||
|
this.hight = hight;
|
||||||
|
init();
|
||||||
|
mCurProgress=0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确定四个点
|
||||||
|
* 1. 左上齿轮中心 宽占完整宽度的比例0.237 高占完整宽度的比例 0.102
|
||||||
|
* 2. 右上齿轮中心 宽占完整宽度的比例0.763 高占完整宽度的比例 0.102
|
||||||
|
* 3. 中上齿轮中心 宽占完整宽度的比例0.5 高占完整宽度的比例 0.311
|
||||||
|
* 4. 中下齿轮中心 宽占完整宽度的比例0.5 高占完整宽度的比例 0.597
|
||||||
|
*/
|
||||||
|
private float[] mLeftTopCentre, mRightTopCentre, mTopCentre, mBottomCentre;
|
||||||
|
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
mLeftTopCentre = new float[2];
|
||||||
|
mRightTopCentre = new float[2];
|
||||||
|
mTopCentre = new float[2];
|
||||||
|
mBottomCentre = new float[2];
|
||||||
|
|
||||||
|
mRedPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mRedPaint.setStrokeJoin(Paint.Join.ROUND);
|
||||||
|
mRedPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
mRedPaint.setColor(Color.RED);
|
||||||
|
|
||||||
|
mDarkRedPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mDarkRedPaint.setStrokeJoin(Paint.Join.ROUND);
|
||||||
|
mDarkRedPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
mDarkRedPaint.setStyle(Paint.Style.FILL);
|
||||||
|
mDarkRedPaint.setColor(color);
|
||||||
|
|
||||||
|
mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mStrokePaint.setStrokeJoin(Paint.Join.ROUND);
|
||||||
|
mStrokePaint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
mStrokePaint.setStyle(Paint.Style.STROKE);
|
||||||
|
mStrokePaint.setColor(Color.RED);
|
||||||
|
|
||||||
|
mTransitionPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mTransitionPaint.setStrokeJoin(Paint.Join.ROUND);
|
||||||
|
mTransitionPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
mTransitionPaint.setStyle(Paint.Style.FILL);
|
||||||
|
mTransitionPaint.setColor(color);
|
||||||
|
|
||||||
|
mTransitionDarkPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mTransitionDarkPaint.setStrokeJoin(Paint.Join.ROUND);
|
||||||
|
mTransitionDarkPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
mTransitionDarkPaint.setStyle(Paint.Style.FILL);
|
||||||
|
mTransitionDarkPaint.setColor(Color.DKGRAY);
|
||||||
|
|
||||||
|
mBeltPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mBeltPaint.setStrokeJoin(Paint.Join.ROUND);
|
||||||
|
mBeltPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
mBeltPaint.setStyle(Paint.Style.FILL);
|
||||||
|
mBeltPaint.setColor(Color.RED);
|
||||||
|
|
||||||
|
mClearXfermode = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
|
||||||
|
|
||||||
|
int paddingLeft = 0;
|
||||||
|
int paddingRight = 0;
|
||||||
|
int paddingTop = 0;
|
||||||
|
int paddingBottom = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// 横向有效宽度
|
||||||
|
int validWidth = width - paddingLeft - paddingRight;
|
||||||
|
// 纵向有效高度
|
||||||
|
int validHeight = height - paddingTop - paddingBottom;
|
||||||
|
|
||||||
|
// 左上齿轮中心
|
||||||
|
mLeftTopCentre[X] = (float) (paddingLeft + validWidth * 0.237);
|
||||||
|
mLeftTopCentre[Y] = (float) (paddingTop + validHeight * 0.102);
|
||||||
|
|
||||||
|
// 右上齿轮中心
|
||||||
|
mRightTopCentre[X] = (float) (paddingLeft + validWidth * 0.763);
|
||||||
|
mRightTopCentre[Y] = (float) (paddingTop + validHeight * 0.102);
|
||||||
|
|
||||||
|
// 中上齿轮中心
|
||||||
|
mTopCentre[X] = (float) (paddingLeft + validWidth * 0.5);
|
||||||
|
mTopCentre[Y] = (float) (paddingTop + validHeight * 0.311);
|
||||||
|
|
||||||
|
// 中下齿轮中心
|
||||||
|
mBottomCentre[X] = (float) (paddingLeft + validWidth * 0.5);
|
||||||
|
mBottomCentre[Y] = (float) (paddingTop + validHeight * 0.597);
|
||||||
|
|
||||||
|
// 上部两个齿轮的半径
|
||||||
|
mTopCircleRadius = (float) (validWidth * 0.102);
|
||||||
|
|
||||||
|
// 最大的齿轮stroke size
|
||||||
|
mBottomBigCircleRadius = validWidth / 2 - mTopCircleRadius / 4 * 5;
|
||||||
|
mStrokePaint.setStrokeWidth(mTopCircleRadius / 4 * 5);
|
||||||
|
|
||||||
|
// 传送带stroke size
|
||||||
|
mBeltPaint.setStrokeWidth((float) (validWidth * 0.0077));
|
||||||
|
|
||||||
|
// 大齿轮Path
|
||||||
|
mBigSawtoothPath = new Path();
|
||||||
|
mBigSawtoothPath.moveTo((float) (mBottomCentre[X] - validWidth * 0.03), (float) (mBottomCentre[Y] - mBottomBigCircleRadius - mStrokePaint.getStrokeWidth() / 2 * 0.9)); // 此处的0.9表示未被绘制上的偏移量
|
||||||
|
mBigSawtoothPath.lineTo((float) (mBottomCentre[X] - validWidth * 0.025), (float) (mBottomCentre[Y] - (mBottomBigCircleRadius + mStrokePaint.getStrokeWidth() / 3 * 2.4))); // 此处的mStrokePaint.getStrokeWidth() / 3 * 2.4 代表最大锯齿的高度
|
||||||
|
mBigSawtoothPath.lineTo((float) (mBottomCentre[X] + validWidth * 0.025), (float) (mBottomCentre[Y] - (mBottomBigCircleRadius + mStrokePaint.getStrokeWidth() / 3 * 2.4)));
|
||||||
|
mBigSawtoothPath.lineTo((float) (mBottomCentre[X] + validWidth * 0.03), (float) (mBottomCentre[Y] - mBottomBigCircleRadius - mStrokePaint.getStrokeWidth() / 2 * 0.9));
|
||||||
|
mBigSawtoothPath.close();
|
||||||
|
mBigSawtoothPath.close();
|
||||||
|
|
||||||
|
// 小齿轮Path
|
||||||
|
mSmallSawtoothPath = new Path();
|
||||||
|
mSmallSawtoothPath.moveTo((float) (mBottomCentre[X] - validWidth * 0.01), (float) (mBottomCentre[Y] - (mTopCircleRadius / 2 * 2.8))); // 此处的12 代表梯形底边的一半
|
||||||
|
mSmallSawtoothPath.lineTo((float) (mBottomCentre[X] - validWidth * 0.013), (float) (mBottomCentre[Y] - (mTopCircleRadius / 2 * 3.2))); // 此处的10 代表梯形顶边的一半
|
||||||
|
mSmallSawtoothPath.lineTo((float) (mBottomCentre[X] + validWidth * 0.013), (float) (mBottomCentre[Y] - (mTopCircleRadius / 2 * 3.2))); // 此处的10 代表梯形顶边的一半
|
||||||
|
mSmallSawtoothPath.lineTo((float) (mBottomCentre[X] + validWidth * 0.01), (float) (mBottomCentre[Y] - (mTopCircleRadius / 2 * 2.8)));
|
||||||
|
mSmallSawtoothPath.close();
|
||||||
|
|
||||||
|
// 左上角三角齿轮
|
||||||
|
mLeftTopTrianglePath = new Path();
|
||||||
|
mLeftTopTrianglePath.moveTo((float) (mLeftTopCentre[X] - validWidth * 0.0082), mLeftTopCentre[Y] - (mTopCircleRadius / 4 * 2));
|
||||||
|
mLeftTopTrianglePath.lineTo(mLeftTopCentre[X] , (float) (mLeftTopCentre[Y] - (mTopCircleRadius / 4 * 2.6))); // 此处的10 是三角形底边的一半
|
||||||
|
mLeftTopTrianglePath.lineTo((float) (mLeftTopCentre[X] + validWidth * 0.0082), mLeftTopCentre[Y] - (mTopCircleRadius / 4 * 2));
|
||||||
|
mLeftTopTrianglePath.close();
|
||||||
|
|
||||||
|
// 右上角三角齿轮
|
||||||
|
mRightTopTrianglePath = new Path();
|
||||||
|
mRightTopTrianglePath.moveTo((float) (mRightTopCentre[X] - validWidth * 0.0082), mRightTopCentre[Y] - (mTopCircleRadius / 4 * 2));
|
||||||
|
mRightTopTrianglePath.lineTo(mRightTopCentre[X] , (float) (mRightTopCentre[Y] - (mTopCircleRadius / 4 * 2.6))); // 此处的10 是三角形底边的一半
|
||||||
|
mRightTopTrianglePath.lineTo((float) (mRightTopCentre[X] + validWidth * 0.0082), mRightTopCentre[Y] - (mTopCircleRadius / 4 * 2));
|
||||||
|
mRightTopTrianglePath.close();
|
||||||
|
|
||||||
|
// 上方斜杆
|
||||||
|
mBarPath = new Path();
|
||||||
|
mBarPath.moveTo(mTopCentre[X] - mTopCircleRadius, mTopCentre[Y]);
|
||||||
|
mBarPath.lineTo(mRightTopCentre[X] - mTopCircleRadius, mRightTopCentre[Y]);
|
||||||
|
mBarPath.lineTo(mRightTopCentre[X] + mTopCircleRadius, mRightTopCentre[Y]);
|
||||||
|
mBarPath.lineTo(mTopCentre[X] + mTopCircleRadius, mTopCentre[Y]);
|
||||||
|
mBarPath.close();
|
||||||
|
|
||||||
|
mSmallBarPath = new Path();
|
||||||
|
mSmallBarPath.moveTo((float) (mTopCentre[X] - mTopCircleRadius * 0.3), mTopCentre[Y]);
|
||||||
|
mSmallBarPath.lineTo((float) (mRightTopCentre[X] - mTopCircleRadius * 0.3), mRightTopCentre[Y]);
|
||||||
|
mSmallBarPath.lineTo((float) (mRightTopCentre[X] + mTopCircleRadius * 0.3), mRightTopCentre[Y]);
|
||||||
|
mSmallBarPath.lineTo((float) (mTopCentre[X] + mTopCircleRadius * 0.3), mTopCentre[Y]);
|
||||||
|
mSmallBarPath.close();
|
||||||
|
|
||||||
|
mShadeRectF = new RectF(0, mBottomCentre[Y] - width / 2, width, mBottomCentre[Y] + width / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDraw(Canvas canvas, Paint mPaint) {
|
||||||
|
|
||||||
|
// 中下最大的齿轮
|
||||||
|
canvas.drawCircle(mBottomCentre[X], mBottomCentre[Y], mBottomBigCircleRadius, mStrokePaint);
|
||||||
|
|
||||||
|
canvas.save();
|
||||||
|
canvas.rotate(mCurProgress * 180, mBottomCentre[X], mBottomCentre[Y]);
|
||||||
|
for (int i = 0; i < 18; i ++) {
|
||||||
|
// 中心齿轮最外围的齿轮上的锯齿 梯形
|
||||||
|
canvas.drawPath(mBigSawtoothPath, mRedPaint);
|
||||||
|
canvas.rotate(20.0f, mBottomCentre[X], mBottomCentre[Y]);
|
||||||
|
}
|
||||||
|
canvas.restore();
|
||||||
|
|
||||||
|
// 大齿轮扇形遮罩
|
||||||
|
mDarkRedPaint.setXfermode(mClearXfermode);
|
||||||
|
canvas.drawArc(mShadeRectF, 180, 130, true, mDarkRedPaint);
|
||||||
|
mDarkRedPaint.setXfermode(null);
|
||||||
|
|
||||||
|
// 上方两个齿轮底下的斜向连杆
|
||||||
|
canvas.drawPath(mBarPath, mTransitionPaint);
|
||||||
|
canvas.drawPath(mSmallBarPath, mTransitionDarkPaint);
|
||||||
|
|
||||||
|
// 上方两个齿轮底下的横向连杆
|
||||||
|
canvas.drawRect(mLeftTopCentre[X], mLeftTopCentre[Y] - mTopCircleRadius / 4 * 3, mRightTopCentre[X], mRightTopCentre[Y] + mTopCircleRadius / 4 * 3, mRedPaint);
|
||||||
|
|
||||||
|
// 左上齿轮
|
||||||
|
canvas.drawCircle(mLeftTopCentre[X], mLeftTopCentre[Y], mTopCircleRadius, mRedPaint);
|
||||||
|
canvas.drawCircle(mLeftTopCentre[X], mLeftTopCentre[Y], mTopCircleRadius / 4 * 3, mDarkRedPaint);
|
||||||
|
canvas.save();
|
||||||
|
canvas.rotate(mCurProgress * 360, mLeftTopCentre[X], mLeftTopCentre[Y]);
|
||||||
|
for (int i = 0; i < 24; i ++) {
|
||||||
|
// 齿轮的三角 path
|
||||||
|
canvas.drawPath(mLeftTopTrianglePath, mRedPaint);
|
||||||
|
canvas.rotate(15.0f, mLeftTopCentre[X], mLeftTopCentre[Y]);
|
||||||
|
}
|
||||||
|
canvas.restore();
|
||||||
|
canvas.drawCircle(mLeftTopCentre[X], mLeftTopCentre[Y], mTopCircleRadius / 2, mRedPaint);
|
||||||
|
canvas.drawCircle(mLeftTopCentre[X], mLeftTopCentre[Y], mTopCircleRadius / 5 * 2, mDarkRedPaint);
|
||||||
|
canvas.drawCircle(mLeftTopCentre[X], mLeftTopCentre[Y], mTopCircleRadius / 4, mRedPaint);
|
||||||
|
|
||||||
|
// 右上齿轮
|
||||||
|
canvas.drawCircle(mRightTopCentre[X], mRightTopCentre[Y], mTopCircleRadius, mRedPaint);
|
||||||
|
canvas.drawCircle(mRightTopCentre[X], mRightTopCentre[Y], mTopCircleRadius / 4 * 3, mDarkRedPaint);
|
||||||
|
canvas.save();
|
||||||
|
canvas.rotate(-mCurProgress * 360, mRightTopCentre[X], mRightTopCentre[Y]);
|
||||||
|
for (int i = 0; i < 24; i ++) {
|
||||||
|
// 齿轮的三角 path
|
||||||
|
canvas.drawPath(mRightTopTrianglePath, mRedPaint);
|
||||||
|
canvas.rotate(15.0f, mRightTopCentre[X], mRightTopCentre[Y]);
|
||||||
|
}
|
||||||
|
canvas.restore();
|
||||||
|
canvas.drawCircle(mRightTopCentre[X], mRightTopCentre[Y], mTopCircleRadius / 2, mRedPaint);
|
||||||
|
canvas.drawCircle(mRightTopCentre[X], mRightTopCentre[Y], mTopCircleRadius / 5 * 2, mDarkRedPaint);
|
||||||
|
canvas.drawCircle(mRightTopCentre[X], mRightTopCentre[Y], mTopCircleRadius / 4, mRedPaint);
|
||||||
|
|
||||||
|
// 中上齿轮
|
||||||
|
canvas.drawCircle(mTopCentre[X], mTopCentre[Y], mTopCircleRadius, mRedPaint);
|
||||||
|
canvas.drawCircle(mTopCentre[X], mTopCentre[Y], mTopCircleRadius / 4 * 3, mDarkRedPaint);
|
||||||
|
canvas.drawCircle(mTopCentre[X], mTopCentre[Y], mTopCircleRadius / 4, mRedPaint);
|
||||||
|
canvas.save();
|
||||||
|
canvas.rotate(mCurProgress * 225, mTopCentre[X], mTopCentre[Y]);
|
||||||
|
for (int i = 0; i < 8; i ++) {
|
||||||
|
// 圆盘上的小圆点
|
||||||
|
canvas.drawCircle(mTopCentre[X], mTopCentre[Y] - (mTopCircleRadius / 4 * 2), (float) (mTopCircleRadius * 0.0625), mRedPaint); // 此处的(mTopCircleRadius * 0.125) 表示小圆球的半径
|
||||||
|
canvas.rotate(45.0f, mTopCentre[X], mTopCentre[Y]);
|
||||||
|
}
|
||||||
|
canvas.restore();
|
||||||
|
|
||||||
|
// 中下齿轮
|
||||||
|
canvas.save();
|
||||||
|
canvas.rotate(-mCurProgress * 216, mBottomCentre[X], mBottomCentre[Y]);
|
||||||
|
for (int i = 0; i < 15; i ++) {
|
||||||
|
// 中心齿轮最外围的齿轮上的锯齿 梯形
|
||||||
|
canvas.drawPath(mSmallSawtoothPath, mDarkRedPaint);
|
||||||
|
canvas.rotate(24.0f, mBottomCentre[X], mBottomCentre[Y]);
|
||||||
|
}
|
||||||
|
canvas.restore();
|
||||||
|
|
||||||
|
canvas.drawCircle(mBottomCentre[X], mBottomCentre[Y], mTopCircleRadius / 2 * 3, mDarkRedPaint);
|
||||||
|
canvas.drawCircle(mBottomCentre[X], mBottomCentre[Y], mTopCircleRadius / 16 * 17, mRedPaint);
|
||||||
|
// 投影
|
||||||
|
mRedPaint.setShadowLayer(10.0f, 0f, 6.0f, Color.LTGRAY);
|
||||||
|
canvas.drawCircle(mBottomCentre[X], mBottomCentre[Y], mTopCircleRadius / 80 * 55, mRedPaint);
|
||||||
|
mRedPaint.setShadowLayer(0f, 0f, 0f, Color.LTGRAY);
|
||||||
|
canvas.drawCircle(mBottomCentre[X], mBottomCentre[Y], mTopCircleRadius / 80 * 40, mDarkRedPaint);
|
||||||
|
|
||||||
|
canvas.save();
|
||||||
|
canvas.rotate(mCurProgress * 180, mBottomCentre[X], mBottomCentre[Y]);
|
||||||
|
for (int i = 0; i < 8; i ++) {
|
||||||
|
// 圆盘上的小圆点
|
||||||
|
canvas.drawCircle(mBottomCentre[X], (float) (mBottomCentre[Y] - (mTopCircleRadius / 4 * 1.2)), (float) (mTopCircleRadius * 0.05), mRedPaint);
|
||||||
|
canvas.rotate(45.0f, mBottomCentre[X], mBottomCentre[Y]);
|
||||||
|
}
|
||||||
|
canvas.restore();
|
||||||
|
canvas.drawCircle(mBottomCentre[X], mBottomCentre[Y], mTopCircleRadius / 8, mRedPaint);
|
||||||
|
|
||||||
|
// 左侧传送带
|
||||||
|
canvas.drawLine(mTopCentre[X] - mTopCircleRadius * 0.85f, mTopCentre[Y],
|
||||||
|
mBottomCentre[X] - mTopCircleRadius * 0.6f, mBottomCentre[Y],
|
||||||
|
mBeltPaint);
|
||||||
|
|
||||||
|
// 右侧传送带
|
||||||
|
canvas.drawLine(mTopCentre[X] + mTopCircleRadius * 0.85f, mTopCentre[Y],
|
||||||
|
mBottomCentre[X] + mTopCircleRadius * 0.6f, mBottomCentre[Y],
|
||||||
|
mBeltPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void move(int maxWidth, int maxHight) {
|
||||||
|
mCurProgress +=0.1f;
|
||||||
|
if(mCurProgress>1)
|
||||||
|
mCurProgress=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -2,16 +2,10 @@ package clock.socoolby.com.clock.widget.animatorview.animator;
|
|||||||
|
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.LinearGradient;
|
import android.graphics.DrawFilter;
|
||||||
import android.graphics.Matrix;
|
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.PaintFlagsDrawFilter;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
import android.graphics.Shader;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static java.lang.Float.parseFloat;
|
|
||||||
|
|
||||||
import clock.socoolby.com.clock.widget.animatorview.AbstractAnimator;
|
import clock.socoolby.com.clock.widget.animatorview.AbstractAnimator;
|
||||||
import clock.socoolby.com.clock.widget.animatorview.I_AnimatorEntry;
|
import clock.socoolby.com.clock.widget.animatorview.I_AnimatorEntry;
|
||||||
@ -30,254 +24,93 @@ public class WaterAnimator extends AbstractAnimator<WaterAnimator.Water> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Water createNewEntry() {
|
public Water createNewEntry() {
|
||||||
int startColor=Color.parseColor("#00FFFFFF");
|
//randomColorIfAble();
|
||||||
int waveColor=color;
|
return new Water(0,0,width,height,height*3/4);
|
||||||
randomColorIfAble();
|
|
||||||
return new Water(width,height,waveColor,startColor,color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Water implements I_AnimatorEntry {
|
class Water implements I_AnimatorEntry {
|
||||||
|
private Path mAbovePath, mBelowWavePath;
|
||||||
|
private Paint mAboveWavePaint, mBelowWavePaint;
|
||||||
|
|
||||||
private Paint mPaint = new Paint();
|
private DrawFilter mDrawFilter;
|
||||||
private Matrix mMatrix = new Matrix();
|
|
||||||
private List<Wave> mltWave = new ArrayList<>();
|
|
||||||
private int mWaveHeight;
|
|
||||||
private int mStartColor;
|
|
||||||
private int mCloseColor;
|
|
||||||
private int mGradientAngle;
|
|
||||||
private float mVelocity;
|
|
||||||
private float mColorAlpha;
|
|
||||||
private float mProgress;
|
|
||||||
private long mLastTime = 0;
|
|
||||||
private String tag;
|
|
||||||
|
|
||||||
public Water(int w,int h,int color,int mStartColor,int mCloseColor) {
|
private float φ;
|
||||||
mPaint.setAntiAlias(true);
|
private double ω;
|
||||||
mPaint.setColor(color);
|
private float y, y2;
|
||||||
mWaveHeight = Util.dipToPX(context,50);
|
|
||||||
this.mStartColor = mStartColor;
|
|
||||||
this.mCloseColor = mCloseColor;
|
|
||||||
mColorAlpha = 0.45f;
|
|
||||||
mProgress = 1f;
|
|
||||||
mVelocity = 1f;
|
|
||||||
mGradientAngle = 45;
|
|
||||||
tag="70,25,1.4,1.4,-26\n" +
|
|
||||||
"100,5,1.4,1.2,15\n" +
|
|
||||||
"420,0,1.15,1,-10\n" +
|
|
||||||
"520,10,1.7,1.5,20\n" +
|
|
||||||
"220,0,1,1,-15";
|
|
||||||
|
|
||||||
updateWavePath(w, h);
|
private int width,higth,left,top;
|
||||||
updateLinearGradient(w, h);
|
|
||||||
|
public Water(int left,int top,int width, int higth,int y2) {
|
||||||
|
this.width = width;
|
||||||
|
this.higth = higth;
|
||||||
|
this.left=left;
|
||||||
|
this.top=top;
|
||||||
|
this.y2=y2;
|
||||||
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void runWave() {
|
protected void init() {
|
||||||
|
|
||||||
|
//初始化路径
|
||||||
|
mAbovePath = new Path();
|
||||||
|
mBelowWavePath = new Path();
|
||||||
|
//初始化画笔
|
||||||
|
//上方波浪
|
||||||
|
mAboveWavePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mAboveWavePaint.setAntiAlias(true);
|
||||||
|
mAboveWavePaint.setStyle(Paint.Style.FILL);
|
||||||
|
mAboveWavePaint.setColor(Color.BLUE);
|
||||||
|
//下方波浪
|
||||||
|
mBelowWavePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mBelowWavePaint.setAntiAlias(true);
|
||||||
|
mBelowWavePaint.setStyle(Paint.Style.FILL);
|
||||||
|
mBelowWavePaint.setColor(Color.BLUE);
|
||||||
|
mBelowWavePaint.setAlpha(60);
|
||||||
|
//画布抗锯齿
|
||||||
|
mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateLinearGradient(int width, int height) {
|
|
||||||
//int startColor = Util.getColorWithAlpha(mStartColor, mColorAlpha*255);
|
|
||||||
//int closeColor = Util.getColorWithAlpha(mCloseColor, mColorAlpha*255);
|
|
||||||
//noinspection UnnecessaryLocalVariable
|
|
||||||
//double w = width;
|
|
||||||
//double h = height * mProgress;
|
|
||||||
//double r = Math.sqrt(w * w + h * h) / 2;
|
|
||||||
//double y = r * Math.sin(2 * Math.PI * mGradientAngle / 360);
|
|
||||||
//double x = r * Math.cos(2 * Math.PI * mGradientAngle / 360);
|
|
||||||
//mPaint.setShader(new LinearGradient((int)(w/2-x), (int)(h/2-y), (int)(w/2+x), (int)(h/2+y), startColor, closeColor, Shader.TileMode.CLAMP));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateWavePath(int w, int h) {
|
|
||||||
mltWave.clear();
|
|
||||||
if (tag instanceof String) {
|
|
||||||
String[] waves = tag.toString().split("\\s+");
|
|
||||||
if ("-1".equals(tag)) {
|
|
||||||
waves = "70,25,1.4,1.4,-26\n100,5,1.4,1.2,15\n420,0,1.15,1,-10\n520,10,1.7,1.5,20\n220,0,1,1,-15".split("\\s+");
|
|
||||||
} else if ("-2".equals(tag)) {
|
|
||||||
waves = "0,0,1,0.5,90\n90,0,1,0.5,90".split("\\s+");
|
|
||||||
}
|
|
||||||
for (String wave : waves) {
|
|
||||||
String[] args = wave.split ("\\s*,\\s*");
|
|
||||||
if (args.length == 5) {
|
|
||||||
mltWave.add(new Wave(Util.dipToPX(context,parseFloat(args[0])), Util.dipToPX(context,parseFloat(args[1])), Util.dipToPX(context,parseFloat(args[4])), parseFloat(args[2]), parseFloat(args[3]), w, h, mWaveHeight/2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mltWave.add(new Wave(Util.dipToPX(context,50), Util.dipToPX(context,0), Util.dipToPX(context,5), 1.7f, 2f, w, h, mWaveHeight/2));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void move(int maxWidth, int maxHight) {
|
public void move(int maxWidth, int maxHight) {
|
||||||
runWave();
|
φ -= 0.1f;
|
||||||
|
ω = 2 * Math.PI / width;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDraw(Canvas canvas, Paint paint) {
|
public void onDraw(Canvas canvas, Paint mPaint) {
|
||||||
if (mltWave.size() > 0 && mPaint != null) {
|
canvas.setDrawFilter(mDrawFilter);
|
||||||
long thisTime = System.currentTimeMillis();
|
|
||||||
for (Wave wave : mltWave) {
|
mAbovePath.reset();
|
||||||
mMatrix.reset();
|
mBelowWavePath.reset();
|
||||||
canvas.save();
|
|
||||||
if (mLastTime > 0 && wave.velocity != 0) {
|
mAbovePath.moveTo(left, higth);
|
||||||
float offsetX = (wave.offsetX - (wave.velocity * mVelocity * (thisTime - mLastTime) / 1000f));
|
// mBelowWavePath.moveTo(getLeft(), getBottom() + 15);
|
||||||
if (-wave.velocity > 0) {
|
for (float x = 0; x <= width; x++) {
|
||||||
offsetX %= wave.width / 2;
|
/**
|
||||||
} else {
|
* y=Asin(ωx+φ)+k
|
||||||
while (offsetX < 0) {
|
* A—振幅越大,波形在y轴上最大与最小值的差值越大
|
||||||
offsetX += (wave.width / 2);
|
* ω—角速度, 控制正弦周期(单位角度内震动的次数)
|
||||||
}
|
* φ—初相,反映在坐标系上则为图像的左右移动。这里通过不断改变φ,达到波浪移动效果
|
||||||
}
|
* k—偏距,反映在坐标系上则为图像的上移或下移。
|
||||||
wave.offsetX = offsetX;
|
*/
|
||||||
mMatrix.setTranslate(offsetX, (1 - mProgress) * height);
|
y = (float) (30 * Math.cos(ω * x + φ) + 30)+y2;
|
||||||
canvas.translate(-offsetX, -wave.offsetY - (1 - mProgress) * height);
|
// y2 = (float) (30 * Math.sin(ω * x + φ) + 30);
|
||||||
} else{
|
mAbovePath.lineTo(x, y);
|
||||||
mMatrix.setTranslate(wave.offsetX, (1 - mProgress) * height);
|
// mBelowWavePath.lineTo(x, y2);
|
||||||
canvas.translate(-wave.offsetX, -wave.offsetY - (1 - mProgress) * height);
|
if (x == width / 2) {
|
||||||
}
|
mPaint.setColor(color);
|
||||||
//mPaint.getShader().setLocalMatrix(mMatrix);
|
canvas.drawCircle(x, y-40, 20, mPaint);
|
||||||
canvas.drawPath(wave.path, mPaint);
|
//mWaveAnimationListener.OnWaveAnimation(y);
|
||||||
canvas.restore();
|
|
||||||
}
|
}
|
||||||
mLastTime = thisTime;
|
|
||||||
}
|
}
|
||||||
}
|
//回调 把y坐标的值传出去(在activity里面接收让小机器人随波浪一起摇摆)
|
||||||
}
|
mAbovePath.lineTo(width, higth);
|
||||||
|
// mBelowWavePath.lineTo(getRight(), getBottom() + 15);
|
||||||
/**
|
canvas.drawPath(mAbovePath, mAboveWavePaint);
|
||||||
* 水波对象
|
// canvas.drawPath(mBelowWavePath, mBelowWavePaint);
|
||||||
* Created by SCWANG on 2017/12/11.
|
|
||||||
*/
|
|
||||||
class Wave {
|
|
||||||
|
|
||||||
Path path; //水波路径
|
|
||||||
int width; //画布宽度(2倍波长)
|
|
||||||
int wave; //波幅(振幅)
|
|
||||||
float offsetX; //水波的水平偏移量
|
|
||||||
float offsetY; //水波的竖直偏移量
|
|
||||||
float velocity; //水波移动速度(像素/秒)
|
|
||||||
private float scaleX; //水平拉伸比例
|
|
||||||
private float scaleY; //竖直拉伸比例
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过参数构造一个水波对象
|
|
||||||
*
|
|
||||||
* @param offsetX 水平偏移量
|
|
||||||
* @param offsetY 竖直偏移量
|
|
||||||
* @param velocity 移动速度(像素/秒)
|
|
||||||
* @param scaleX 水平拉伸量
|
|
||||||
* @param scaleY 竖直拉伸量
|
|
||||||
* @param w 波长
|
|
||||||
* @param h 画布高度
|
|
||||||
* @param wave 波幅(波宽度)
|
|
||||||
*/
|
|
||||||
|
|
||||||
public Wave(int offsetX, int offsetY, int velocity, float scaleX, float scaleY, int w, int h, int wave) {
|
|
||||||
|
|
||||||
this.width = (int) (2 * scaleX * w); //画布宽度(2倍波长)
|
|
||||||
this.wave = wave; //波幅(波宽)
|
|
||||||
this.scaleX = scaleX; //水平拉伸量
|
|
||||||
this.scaleY = scaleY; //竖直拉伸量
|
|
||||||
this.offsetX = offsetX; //水平偏移量
|
|
||||||
this.offsetY = offsetY; //竖直偏移量
|
|
||||||
this.velocity = velocity; //移动速度(像素/秒)
|
|
||||||
this.path = buildWavePath(width, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 根据 波长度、中轴线高度、波幅 绘制水波路径
|
|
||||||
*/
|
|
||||||
|
|
||||||
public void updateWavePath(int w, int h, int waveHeight) {
|
|
||||||
this.wave = (wave > 0) ? wave : waveHeight / 2;
|
|
||||||
this.width = (int) (2 * scaleX * w); //画布宽度(2倍波长)
|
|
||||||
this.path = buildWavePath(width, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Path buildWavePath(int width, int height) {
|
|
||||||
int DP = Util.dipToPX(context, 1);//一个dp在当前设备表示的像素量(水波的绘制精度设为一个dp单位)
|
|
||||||
if (DP < 1) {
|
|
||||||
DP = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wave = (int) (scaleY * this.wave);//计算拉伸之后的波幅
|
|
||||||
|
|
||||||
Path path = new Path();
|
|
||||||
//path.moveTo(0, 0);
|
|
||||||
//path.lineTo(0, height - wave);
|
|
||||||
path.moveTo(0, height);
|
|
||||||
path.lineTo(0, height - wave);
|
|
||||||
|
|
||||||
for (int x = DP; x < width; x += DP) {
|
|
||||||
path.lineTo(x, height - wave - wave * (float) Math.sin(4.0 * Math.PI * x / width));
|
|
||||||
}
|
|
||||||
|
|
||||||
path.lineTo(width, height - wave);
|
|
||||||
//path.lineTo(width, 0);
|
|
||||||
path.lineTo(width, height);
|
|
||||||
path.close();
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 绘制外层的刻度
|
|
||||||
*
|
|
||||||
* @param canvas
|
|
||||||
protected void drawOutArc(Canvas canvas) {
|
|
||||||
canvas.save();
|
|
||||||
for (int i = 0; i < 100; i++) {
|
|
||||||
if (i < mPercent) {
|
|
||||||
mOutProgressPaint.setColor(mProgressColor);
|
|
||||||
} else {
|
|
||||||
mOutProgressPaint.setColor(mOutBaseColor);
|
|
||||||
}
|
|
||||||
canvas.rotate(3.6f, width / 2, height / 2);
|
|
||||||
canvas.drawLine(width / 2, 0, height / 2, mDefaultLineLen, mOutProgressPaint);
|
|
||||||
|
|
||||||
}
|
|
||||||
canvas.restore();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据 最高点,获取贝塞尔曲线的 控制点
|
|
||||||
*
|
|
||||||
* @param startPointF 开始点
|
|
||||||
* @param endPointF 结束点
|
|
||||||
* @param bezierPointF 最高点
|
|
||||||
* @return 控制点
|
|
||||||
*/
|
|
||||||
public static Point getControlPointF(Point startPointF, Point endPointF, Point bezierPointF) {
|
|
||||||
//B(t)=(1-t)^2P0+2t(1-t)P1+t^2P2;
|
|
||||||
Point controlPointF = new Point(0l, 0l);
|
|
||||||
float tmp = 0.5F;
|
|
||||||
float t = 0.5F;
|
|
||||||
controlPointF.setX((bezierPointF.x - tmp * tmp * startPointF.y - t * t * endPointF.y) / (2 * t * tmp));
|
|
||||||
controlPointF.setY((bezierPointF.y- tmp * tmp * startPointF.y - t * t * endPointF.y) / (2 * t * tmp));
|
|
||||||
return controlPointF;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Point{
|
|
||||||
public float x,y;
|
|
||||||
public Point(float x,float y){
|
|
||||||
this.x=x;
|
|
||||||
this.y=y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setX(float x){
|
|
||||||
this.x=x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setY(float y){
|
|
||||||
this.y=y;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,32 +6,31 @@ import android.graphics.Paint;
|
|||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
import clock.socoolby.com.clock.widget.animatorview.I_AnimatorEntry;
|
import clock.socoolby.com.clock.widget.animatorview.I_AnimatorEntry;
|
||||||
|
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.pointer.DefaultPointer;
|
||||||
|
|
||||||
public abstract class AbstractClock implements I_AnimatorEntry {
|
public abstract class AbstractClock implements I_AnimatorEntry {
|
||||||
protected int width,hight;
|
protected int width,hight;
|
||||||
|
|
||||||
protected int mCenterX, mCenterY;
|
protected int mCenterX, mCenterY;
|
||||||
|
|
||||||
// 默认刻度画笔、指针画笔、文字画笔;
|
// 默认刻度画笔、文字画笔;
|
||||||
protected Paint mDefaultPaint, mPointerPaint, mTextPaint;
|
protected Paint mDefaultPaint, mTextPaint;
|
||||||
|
|
||||||
// 时钟半径、中心点半径、默认刻度长度、默认刻度宽度、特殊刻度长度、特殊刻度宽度、
|
// 时钟半径、中心点半径、默认刻度长度、默认刻度宽度、特殊刻度长度、特殊刻度宽度
|
||||||
// 时指针长度、时钟指针宽度、分钟指针长度、分钟指针宽度、秒钟指针长度、秒钟指针宽度
|
protected float mRadius,
|
||||||
protected float mRadius, mPointRadius,
|
|
||||||
mDefaultScaleLength, mDefaultScaleWidth,
|
mDefaultScaleLength, mDefaultScaleWidth,
|
||||||
mParticularlyScaleLength, mParticularlyScaleWidth,
|
mParticularlyScaleLength, mParticularlyScaleWidth;
|
||||||
mHourPointerLength, mHourPointerWidth,
|
|
||||||
mMinutePointerLength, mMinutePointerWidth,
|
|
||||||
mSecondPointerLength, mSecondPointerWidth;
|
|
||||||
|
|
||||||
// 当前时、分、秒
|
// 当前时、分、秒
|
||||||
protected int mH, mM, mS;
|
protected int mH, mM, mS;
|
||||||
|
|
||||||
// 时钟颜色、默认刻度颜色、时刻度颜色、时针颜色、分针颜色、秒针颜色
|
// 时钟颜色、默认刻度颜色、时刻度颜色
|
||||||
protected int mClockColor, mColorDefaultScale, mColorParticularyScale, mColorHourPointer,
|
protected int mClockColor, mColorDefaultScale, mColorParticularyScale,textColor;
|
||||||
mColorMinutePointer, mColorSecondPointer,textColor;
|
|
||||||
|
I_Pointer pointer;
|
||||||
|
|
||||||
public AbstractClock() {
|
public AbstractClock() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(int width,int hight,int mCenterX, int mCenterY, float mRadius, int mClockColor,int textColor){
|
public void init(int width,int hight,int mCenterX, int mCenterY, float mRadius, int mClockColor,int textColor){
|
||||||
@ -42,35 +41,51 @@ public abstract class AbstractClock implements I_AnimatorEntry {
|
|||||||
this.mRadius = mRadius;
|
this.mRadius = mRadius;
|
||||||
this.mClockColor = mClockColor;
|
this.mClockColor = mClockColor;
|
||||||
this.textColor=textColor;
|
this.textColor=textColor;
|
||||||
|
initScaleLength();
|
||||||
init();
|
init();
|
||||||
|
setPointer(new DefaultPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
mColorDefaultScale = mClockColor;
|
mColorDefaultScale = mClockColor;
|
||||||
mColorParticularyScale = mClockColor;
|
mColorParticularyScale = mClockColor;
|
||||||
|
|
||||||
mColorHourPointer = mClockColor;
|
|
||||||
mColorMinutePointer = mClockColor;
|
|
||||||
mColorSecondPointer = mClockColor;
|
|
||||||
|
|
||||||
mDefaultPaint = new Paint();
|
mDefaultPaint = new Paint();
|
||||||
mDefaultPaint.setAntiAlias(true);
|
mDefaultPaint.setAntiAlias(true);
|
||||||
mDefaultPaint.setStyle(Paint.Style.STROKE);
|
mDefaultPaint.setStyle(Paint.Style.STROKE);
|
||||||
|
|
||||||
mPointerPaint = new Paint();
|
|
||||||
mPointerPaint.setAntiAlias(true);
|
|
||||||
mPointerPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
|
||||||
mPointerPaint.setTextSize(14);
|
|
||||||
mPointerPaint.setStrokeCap(Paint.Cap.ROUND);
|
|
||||||
|
|
||||||
mTextPaint = new Paint();
|
mTextPaint = new Paint();
|
||||||
mPointerPaint.setAntiAlias(true);
|
mTextPaint.setStrokeWidth(mDefaultScaleWidth / 2);
|
||||||
mPointerPaint.setStyle(Paint.Style.FILL);
|
mTextPaint.setTextSize(mParticularlyScaleWidth * 4);
|
||||||
mPointerPaint.setColor(mClockColor);
|
mTextPaint.setTextAlign(Paint.Align.CENTER);
|
||||||
initClockPointerLength();
|
mTextPaint.setColor(textColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void initScaleLength(){
|
||||||
|
/*
|
||||||
|
* 默认时钟刻度长=半径/10;
|
||||||
|
* 默认时钟刻度宽=长/6;
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
mDefaultScaleLength = mRadius / 10;
|
||||||
|
mDefaultScaleWidth = mDefaultScaleLength / 6;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 特殊时钟刻度长=半径/5;
|
||||||
|
* 特殊时钟刻度宽=长/6;
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
mParticularlyScaleLength = mRadius / 5;
|
||||||
|
mParticularlyScaleWidth = mParticularlyScaleLength / 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setPointer(I_Pointer pointer){
|
||||||
|
this.pointer=pointer;
|
||||||
|
pointer.init(mRadius,mClockColor);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前系统时间
|
* 获取当前系统时间
|
||||||
*/
|
*/
|
||||||
@ -95,21 +110,14 @@ public abstract class AbstractClock implements I_AnimatorEntry {
|
|||||||
mS = s;
|
mS = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据控件的大小,初始化时钟刻度的长度和宽度、指针的长度和宽度、时钟中心点的半径
|
|
||||||
*/
|
|
||||||
protected abstract void initClockPointerLength();
|
|
||||||
|
|
||||||
public void onDraw(Canvas canvas, Paint mPaint) {
|
public void onDraw(Canvas canvas, Paint mPaint) {
|
||||||
|
|
||||||
setTextPaint();
|
|
||||||
drawBorder(canvas);
|
drawBorder(canvas);
|
||||||
drawOrnament(canvas);
|
drawOrnament(canvas);
|
||||||
// 坐标原点移动到View 中心
|
// 坐标原点移动到View 中心
|
||||||
canvas.translate(mCenterX, mCenterY);
|
canvas.translate(mCenterX, mCenterY);
|
||||||
drawText(canvas);
|
drawText(canvas);
|
||||||
drawPointer(canvas);
|
pointer.drawPointer(canvas,mH,mM,mS,mPaint);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -204,83 +212,6 @@ public abstract class AbstractClock implements I_AnimatorEntry {
|
|||||||
canvas.drawText(h, y, 0 + offsetY, mTextPaint);
|
canvas.drawText(h, y, 0 + offsetY, mTextPaint);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setTextPaint() {
|
|
||||||
mTextPaint.setStrokeWidth(mDefaultScaleWidth / 2);
|
|
||||||
mTextPaint.setTextSize(mParticularlyScaleWidth * 4);
|
|
||||||
mTextPaint.setTextAlign(Paint.Align.CENTER);
|
|
||||||
mTextPaint.setColor(textColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 绘制指针
|
|
||||||
*/
|
|
||||||
protected void drawPointer(Canvas canvas) {
|
|
||||||
drawHourPointer(canvas);
|
|
||||||
drawMinutePointer(canvas);
|
|
||||||
drawSecondPointer(canvas);
|
|
||||||
|
|
||||||
mPointerPaint.setColor(mClockColor);
|
|
||||||
// 绘制中心原点,需要在指针绘制完成后才能绘制
|
|
||||||
canvas.drawCircle(0, 0, mPointRadius, mPointerPaint);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 绘制时针
|
|
||||||
*/
|
|
||||||
protected void drawHourPointer(Canvas canvas) {
|
|
||||||
|
|
||||||
mPointerPaint.setStrokeWidth(mHourPointerWidth);
|
|
||||||
mPointerPaint.setColor(mColorHourPointer);
|
|
||||||
|
|
||||||
// 当前时间的总秒数
|
|
||||||
float s = mH * 60 * 60 + mM * 60 + mS;
|
|
||||||
// 百分比
|
|
||||||
float percentage = s / (12 * 60 * 60);
|
|
||||||
// 通过角度计算弧度值,因为时钟的角度起线是y轴负方向,而View角度的起线是x轴正方向,所以要加270度
|
|
||||||
float angle = 270 + 360 * percentage;
|
|
||||||
|
|
||||||
float x = (float) (mHourPointerLength * Math.cos(Math.PI * 2 / 360 * angle));
|
|
||||||
float y = (float) (mHourPointerLength * Math.sin(Math.PI * 2 / 360 * angle));
|
|
||||||
|
|
||||||
canvas.drawLine(0, 0, x, y, mPointerPaint);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 绘制分针
|
|
||||||
*/
|
|
||||||
protected void drawMinutePointer(Canvas canvas) {
|
|
||||||
|
|
||||||
mPointerPaint.setStrokeWidth(mMinutePointerWidth);
|
|
||||||
mPointerPaint.setColor(mColorMinutePointer);
|
|
||||||
|
|
||||||
float s = mM * 60 + mS;
|
|
||||||
float percentage = s / (60 * 60);
|
|
||||||
float angle = 270 + 360 * percentage;
|
|
||||||
|
|
||||||
float x = (float) (mMinutePointerLength * Math.cos(Math.PI * 2 / 360 * angle));
|
|
||||||
float y = (float) (mMinutePointerLength * Math.sin(Math.PI * 2 / 360 * angle));
|
|
||||||
|
|
||||||
canvas.drawLine(0, 0, x, y, mPointerPaint);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 绘制秒针
|
|
||||||
*/
|
|
||||||
protected void drawSecondPointer(Canvas canvas) {
|
|
||||||
|
|
||||||
mPointerPaint.setStrokeWidth(mSecondPointerWidth);
|
|
||||||
mPointerPaint.setColor(mColorSecondPointer);
|
|
||||||
|
|
||||||
float s = mS;
|
|
||||||
float percentage = s / 60;
|
|
||||||
float angle = 270 + 360 * percentage;
|
|
||||||
|
|
||||||
float x = (float) (mSecondPointerLength * Math.cos(Math.PI * 2 / 360 * angle));
|
|
||||||
float y = (float) (mSecondPointerLength * Math.sin(Math.PI * 2 / 360 * angle));
|
|
||||||
|
|
||||||
canvas.drawLine(0, 0, x, y, mPointerPaint);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void move(int maxWidth, int maxHight) {
|
public void move(int maxWidth, int maxHight) {
|
||||||
getTime();
|
getTime();
|
||||||
|
@ -6,53 +6,7 @@ import android.graphics.Paint;
|
|||||||
public class CircleClock extends AbstractClock {
|
public class CircleClock extends AbstractClock {
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据控件的大小,初始化时钟刻度的长度和宽度、指针的长度和宽度、时钟中心点的半径
|
|
||||||
*/
|
|
||||||
protected void initClockPointerLength() {
|
|
||||||
/*
|
|
||||||
* 默认时钟刻度长=半径/10;
|
|
||||||
* 默认时钟刻度宽=长/6;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mDefaultScaleLength = mRadius / 10;
|
|
||||||
mDefaultScaleWidth = mDefaultScaleLength / 6;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 特殊时钟刻度长=半径/5;
|
|
||||||
* 特殊时钟刻度宽=长/6;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mParticularlyScaleLength = mRadius / 5;
|
|
||||||
mParticularlyScaleWidth = mParticularlyScaleLength / 6;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 时针长=半径/3;
|
|
||||||
* 时针宽=特殊时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mHourPointerLength = mRadius / 3;
|
|
||||||
mHourPointerWidth = mParticularlyScaleWidth;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 分针长=半径/2;
|
|
||||||
* 分针宽=特殊时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mMinutePointerLength = mRadius / 2;
|
|
||||||
mMinutePointerWidth = mParticularlyScaleWidth;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 秒针长=半径/3*2;
|
|
||||||
* 秒针宽=默认时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mSecondPointerLength = mRadius / 3 * 2;
|
|
||||||
mSecondPointerWidth = mDefaultScaleWidth;
|
|
||||||
|
|
||||||
// 中心点半径=(默认刻度宽+特殊刻度宽)/2
|
|
||||||
mPointRadius = (mDefaultScaleWidth + mParticularlyScaleWidth) / 2;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 绘制时钟的圆形和刻度
|
* 绘制时钟的圆形和刻度
|
||||||
*/
|
*/
|
||||||
@ -69,14 +23,14 @@ public class CircleClock extends AbstractClock {
|
|||||||
|
|
||||||
mDefaultPaint.setStrokeWidth(mParticularlyScaleWidth);
|
mDefaultPaint.setStrokeWidth(mParticularlyScaleWidth);
|
||||||
mDefaultPaint.setColor(mColorParticularyScale);
|
mDefaultPaint.setColor(mColorParticularyScale);
|
||||||
|
mDefaultPaint.setAlpha(255);
|
||||||
canvas.drawLine(0, -mRadius, 0, -mRadius + mParticularlyScaleLength, mDefaultPaint);
|
canvas.drawLine(0, -mRadius, 0, -mRadius + mParticularlyScaleLength, mDefaultPaint);
|
||||||
|
|
||||||
} else { // 一般时刻
|
} else { // 一般时刻
|
||||||
|
|
||||||
mDefaultPaint.setStrokeWidth(mDefaultScaleWidth);
|
mDefaultPaint.setStrokeWidth(mDefaultScaleWidth);
|
||||||
mDefaultPaint.setColor(mColorDefaultScale);
|
mDefaultPaint.setColor(mColorDefaultScale);
|
||||||
|
mDefaultPaint.setAlpha(100);
|
||||||
canvas.drawLine(0, -mRadius, 0, -mRadius + mDefaultScaleLength, mDefaultPaint);
|
canvas.drawLine(0, -mRadius, 0, -mRadius + mDefaultScaleLength, mDefaultPaint);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
package clock.socoolby.com.clock.widget.animatorview.animator.clockanimator;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
|
||||||
|
public class CircleTwoClock extends AbstractClock {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绘制时钟的圆形和刻度
|
||||||
|
*/
|
||||||
|
protected void drawBorder(Canvas canvas) {
|
||||||
|
canvas.save();
|
||||||
|
canvas.translate(mCenterX, mCenterY);
|
||||||
|
mDefaultPaint.setStrokeWidth(mDefaultScaleWidth);
|
||||||
|
mDefaultPaint.setColor(mClockColor);
|
||||||
|
|
||||||
|
canvas.drawCircle(0, 0, mRadius, mDefaultPaint);
|
||||||
|
|
||||||
|
for (int i = 0; i < 60; i++) {
|
||||||
|
if (i % 5 == 0) { // 特殊时刻
|
||||||
|
mDefaultPaint.setStrokeWidth(mParticularlyScaleWidth);
|
||||||
|
mDefaultPaint.setColor(mColorParticularyScale);
|
||||||
|
mDefaultPaint.setAlpha(255);
|
||||||
|
canvas.drawLine(0, -mRadius+mDefaultScaleWidth*1.2f, 0, -mRadius + mDefaultScaleLength+mDefaultScaleWidth*1.3f, mDefaultPaint);
|
||||||
|
} else { // 一般时刻
|
||||||
|
mDefaultPaint.setStrokeWidth(mDefaultScaleWidth);
|
||||||
|
mDefaultPaint.setColor(mColorDefaultScale);
|
||||||
|
mDefaultPaint.setAlpha(100);
|
||||||
|
canvas.drawLine(0, -mRadius+mDefaultScaleWidth, 0, -mRadius + mDefaultScaleLength, mDefaultPaint);
|
||||||
|
}
|
||||||
|
canvas.rotate(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
mDefaultPaint.setStrokeWidth(mDefaultScaleWidth/2);
|
||||||
|
mDefaultPaint.setAlpha(100);
|
||||||
|
canvas.drawCircle(0, 0, mRadius-mDefaultScaleLength*1.5f, mDefaultPaint);
|
||||||
|
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -7,53 +7,6 @@ import android.graphics.Paint;
|
|||||||
public class HelixClock extends AbstractClock {
|
public class HelixClock extends AbstractClock {
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据控件的大小,初始化时钟刻度的长度和宽度、指针的长度和宽度、时钟中心点的半径
|
|
||||||
*/
|
|
||||||
protected void initClockPointerLength() {
|
|
||||||
/*
|
|
||||||
* 默认时钟刻度长=半径/10;
|
|
||||||
* 默认时钟刻度宽=长/6;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mDefaultScaleLength = mRadius / 10;
|
|
||||||
mDefaultScaleWidth = mDefaultScaleLength / 6;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 特殊时钟刻度长=半径/5;
|
|
||||||
* 特殊时钟刻度宽=长/6;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mParticularlyScaleLength = mRadius / 5;
|
|
||||||
mParticularlyScaleWidth = mParticularlyScaleLength / 6;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 时针长=半径/3;
|
|
||||||
* 时针宽=特殊时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mHourPointerLength = mRadius / 3;
|
|
||||||
mHourPointerWidth = mParticularlyScaleWidth;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 分针长=半径/2;
|
|
||||||
* 分针宽=特殊时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mMinutePointerLength = mRadius / 2;
|
|
||||||
mMinutePointerWidth = mParticularlyScaleWidth;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 秒针长=半径/3*2;
|
|
||||||
* 秒针宽=默认时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mSecondPointerLength = mRadius / 3 * 2;
|
|
||||||
mSecondPointerWidth = mDefaultScaleWidth;
|
|
||||||
|
|
||||||
// 中心点半径=(默认刻度宽+特殊刻度宽)/2
|
|
||||||
mPointRadius = (mDefaultScaleWidth + mParticularlyScaleWidth) / 2;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 绘制时钟的圆形和刻度
|
* 绘制时钟的圆形和刻度
|
||||||
*/
|
*/
|
||||||
|
@ -6,53 +6,7 @@ import android.graphics.Paint;
|
|||||||
//六角形
|
//六角形
|
||||||
public class HexagonalClock extends AbstractClock {
|
public class HexagonalClock extends AbstractClock {
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据控件的大小,初始化时钟刻度的长度和宽度、指针的长度和宽度、时钟中心点的半径
|
|
||||||
*/
|
|
||||||
protected void initClockPointerLength() {
|
|
||||||
/*
|
|
||||||
* 默认时钟刻度长=半径/10;
|
|
||||||
* 默认时钟刻度宽=长/6;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mDefaultScaleLength = mRadius / 10;
|
|
||||||
mDefaultScaleWidth = mDefaultScaleLength / 6;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 特殊时钟刻度长=半径/5;
|
|
||||||
* 特殊时钟刻度宽=长/6;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mParticularlyScaleLength = mRadius / 5;
|
|
||||||
mParticularlyScaleWidth = mParticularlyScaleLength / 6;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 时针长=半径/3;
|
|
||||||
* 时针宽=特殊时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mHourPointerLength = mRadius / 3;
|
|
||||||
mHourPointerWidth = mParticularlyScaleWidth;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 分针长=半径/2;
|
|
||||||
* 分针宽=特殊时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mMinutePointerLength = mRadius / 2;
|
|
||||||
mMinutePointerWidth = mParticularlyScaleWidth;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 秒针长=半径/3*2;
|
|
||||||
* 秒针宽=默认时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mSecondPointerLength = mRadius / 3 * 2;
|
|
||||||
mSecondPointerWidth = mDefaultScaleWidth;
|
|
||||||
|
|
||||||
// 中心点半径=(默认刻度宽+特殊刻度宽)/2
|
|
||||||
mPointRadius = (mDefaultScaleWidth + mParticularlyScaleWidth) / 2;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 绘制时钟的圆形和刻度
|
* 绘制时钟的圆形和刻度
|
||||||
*/
|
*/
|
||||||
@ -89,10 +43,12 @@ public class HexagonalClock extends AbstractClock {
|
|||||||
if (j % 5 == 0) { // 特殊时刻
|
if (j % 5 == 0) { // 特殊时刻
|
||||||
mDefaultPaint.setStrokeWidth(mParticularlyScaleWidth);
|
mDefaultPaint.setStrokeWidth(mParticularlyScaleWidth);
|
||||||
mDefaultPaint.setColor(mColorParticularyScale);
|
mDefaultPaint.setColor(mColorParticularyScale);
|
||||||
|
mDefaultPaint.setAlpha(255);
|
||||||
scaleLength = mParticularlyScaleLength;
|
scaleLength = mParticularlyScaleLength;
|
||||||
} else { // 一般时刻
|
} else { // 一般时刻
|
||||||
mDefaultPaint.setStrokeWidth(mDefaultScaleWidth);
|
mDefaultPaint.setStrokeWidth(mDefaultScaleWidth);
|
||||||
mDefaultPaint.setColor(mColorDefaultScale);
|
mDefaultPaint.setColor(mColorDefaultScale);
|
||||||
|
mDefaultPaint.setAlpha(100);
|
||||||
scaleLength = mDefaultScaleLength;
|
scaleLength = mDefaultScaleLength;
|
||||||
}
|
}
|
||||||
floatLength = radianTanValue * scaleLength;
|
floatLength = radianTanValue * scaleLength;
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package clock.socoolby.com.clock.widget.animatorview.animator.clockanimator;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
|
||||||
|
public interface I_Pointer {
|
||||||
|
|
||||||
|
void init(float mRadius,int mClockColor);
|
||||||
|
|
||||||
|
void drawPointer(Canvas canvas, int mH,int mM,int mS, Paint mPointerPaint);
|
||||||
|
|
||||||
|
}
|
@ -6,54 +6,6 @@ import android.graphics.Paint;
|
|||||||
//八边形
|
//八边形
|
||||||
public class OctagonalClock extends AbstractClock {
|
public class OctagonalClock extends AbstractClock {
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据控件的大小,初始化时钟刻度的长度和宽度、指针的长度和宽度、时钟中心点的半径
|
|
||||||
*/
|
|
||||||
protected void initClockPointerLength() {
|
|
||||||
/*
|
|
||||||
* 默认时钟刻度长=半径/10;
|
|
||||||
* 默认时钟刻度宽=长/6;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mDefaultScaleLength = mRadius / 10;
|
|
||||||
mDefaultScaleWidth = mDefaultScaleLength / 6;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 特殊时钟刻度长=半径/5;
|
|
||||||
* 特殊时钟刻度宽=长/6;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mParticularlyScaleLength = mRadius / 5;
|
|
||||||
mParticularlyScaleWidth = mParticularlyScaleLength / 6;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 时针长=半径/3;
|
|
||||||
* 时针宽=特殊时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mHourPointerLength = mRadius / 3;
|
|
||||||
mHourPointerWidth = mParticularlyScaleWidth;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 分针长=半径/2;
|
|
||||||
* 分针宽=特殊时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mMinutePointerLength = mRadius / 2;
|
|
||||||
mMinutePointerWidth = mParticularlyScaleWidth;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 秒针长=半径/3*2;
|
|
||||||
* 秒针宽=默认时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mSecondPointerLength = mRadius / 3 * 2;
|
|
||||||
mSecondPointerWidth = mDefaultScaleWidth;
|
|
||||||
|
|
||||||
// 中心点半径=(默认刻度宽+特殊刻度宽)/2
|
|
||||||
mPointRadius = (mDefaultScaleWidth + mParticularlyScaleWidth) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绘制时钟的圆形和刻度
|
* 绘制时钟的圆形和刻度
|
||||||
* 分三段
|
* 分三段
|
||||||
@ -95,10 +47,12 @@ public class OctagonalClock extends AbstractClock {
|
|||||||
if (k % 5 == 0) { // 特殊时刻
|
if (k % 5 == 0) { // 特殊时刻
|
||||||
mDefaultPaint.setStrokeWidth(mParticularlyScaleWidth);
|
mDefaultPaint.setStrokeWidth(mParticularlyScaleWidth);
|
||||||
mDefaultPaint.setColor(mColorParticularyScale);
|
mDefaultPaint.setColor(mColorParticularyScale);
|
||||||
|
mDefaultPaint.setAlpha(255);
|
||||||
scaleLength=mParticularlyScaleLength;
|
scaleLength=mParticularlyScaleLength;
|
||||||
} else { // 一般时刻
|
} else { // 一般时刻
|
||||||
mDefaultPaint.setStrokeWidth(mDefaultScaleWidth);
|
mDefaultPaint.setStrokeWidth(mDefaultScaleWidth);
|
||||||
mDefaultPaint.setColor(mColorDefaultScale);
|
mDefaultPaint.setColor(mColorDefaultScale);
|
||||||
|
mDefaultPaint.setAlpha(100);
|
||||||
scaleLength=mDefaultScaleLength;
|
scaleLength=mDefaultScaleLength;
|
||||||
}
|
}
|
||||||
floatLength=radianTanValue*scaleLength;
|
floatLength=radianTanValue*scaleLength;
|
||||||
|
@ -6,54 +6,6 @@ import android.graphics.Paint;
|
|||||||
//(假)椭圆
|
//(假)椭圆
|
||||||
public class OvalClock extends AbstractClock {
|
public class OvalClock extends AbstractClock {
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据控件的大小,初始化时钟刻度的长度和宽度、指针的长度和宽度、时钟中心点的半径
|
|
||||||
*/
|
|
||||||
protected void initClockPointerLength() {
|
|
||||||
/*
|
|
||||||
* 默认时钟刻度长=半径/10;
|
|
||||||
* 默认时钟刻度宽=长/6;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mDefaultScaleLength = mRadius / 10;
|
|
||||||
mDefaultScaleWidth = mDefaultScaleLength / 6;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 特殊时钟刻度长=半径/5;
|
|
||||||
* 特殊时钟刻度宽=长/6;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mParticularlyScaleLength = mRadius / 5;
|
|
||||||
mParticularlyScaleWidth = mParticularlyScaleLength / 6;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 时针长=半径/3;
|
|
||||||
* 时针宽=特殊时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mHourPointerLength = mRadius / 3;
|
|
||||||
mHourPointerWidth = mParticularlyScaleWidth;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 分针长=半径/2;
|
|
||||||
* 分针宽=特殊时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mMinutePointerLength = mRadius / 2;
|
|
||||||
mMinutePointerWidth = mParticularlyScaleWidth;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 秒针长=半径/3*2;
|
|
||||||
* 秒针宽=默认时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mSecondPointerLength = mRadius / 3 * 2;
|
|
||||||
mSecondPointerWidth = mDefaultScaleWidth;
|
|
||||||
|
|
||||||
// 中心点半径=(默认刻度宽+特殊刻度宽)/2
|
|
||||||
mPointRadius = (mDefaultScaleWidth + mParticularlyScaleWidth) / 2;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 绘制时钟的圆形和刻度
|
* 绘制时钟的圆形和刻度
|
||||||
*/
|
*/
|
||||||
@ -70,14 +22,14 @@ public class OvalClock extends AbstractClock {
|
|||||||
|
|
||||||
mDefaultPaint.setStrokeWidth(mParticularlyScaleWidth);
|
mDefaultPaint.setStrokeWidth(mParticularlyScaleWidth);
|
||||||
mDefaultPaint.setColor(mColorParticularyScale);
|
mDefaultPaint.setColor(mColorParticularyScale);
|
||||||
|
mDefaultPaint.setAlpha(255);
|
||||||
canvas.drawLine(0, -mRadius, 0, -mRadius + mParticularlyScaleLength, mDefaultPaint);
|
canvas.drawLine(0, -mRadius, 0, -mRadius + mParticularlyScaleLength, mDefaultPaint);
|
||||||
|
|
||||||
} else { // 一般时刻
|
} else { // 一般时刻
|
||||||
|
|
||||||
mDefaultPaint.setStrokeWidth(mDefaultScaleWidth);
|
mDefaultPaint.setStrokeWidth(mDefaultScaleWidth);
|
||||||
mDefaultPaint.setColor(mColorDefaultScale);
|
mDefaultPaint.setColor(mColorDefaultScale);
|
||||||
|
mDefaultPaint.setAlpha(100);
|
||||||
canvas.drawLine(0, -mRadius, 0, -mRadius + mDefaultScaleLength, mDefaultPaint);
|
canvas.drawLine(0, -mRadius, 0, -mRadius + mDefaultScaleLength, mDefaultPaint);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,54 +6,6 @@ import android.graphics.Paint;
|
|||||||
//方型
|
//方型
|
||||||
public class SquareClock extends AbstractClock {
|
public class SquareClock extends AbstractClock {
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据控件的大小,初始化时钟刻度的长度和宽度、指针的长度和宽度、时钟中心点的半径
|
|
||||||
*/
|
|
||||||
protected void initClockPointerLength() {
|
|
||||||
/*
|
|
||||||
* 默认时钟刻度长=半径/10;
|
|
||||||
* 默认时钟刻度宽=长/6;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mDefaultScaleLength = mRadius / 10;
|
|
||||||
mDefaultScaleWidth = mDefaultScaleLength / 6;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 特殊时钟刻度长=半径/5;
|
|
||||||
* 特殊时钟刻度宽=长/6;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mParticularlyScaleLength = mRadius / 5;
|
|
||||||
mParticularlyScaleWidth = mParticularlyScaleLength / 6;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 时针长=半径/3;
|
|
||||||
* 时针宽=特殊时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mHourPointerLength = mRadius / 3;
|
|
||||||
mHourPointerWidth = mParticularlyScaleWidth;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 分针长=半径/2;
|
|
||||||
* 分针宽=特殊时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mMinutePointerLength = mRadius / 2;
|
|
||||||
mMinutePointerWidth = mParticularlyScaleWidth;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 秒针长=半径/3*2;
|
|
||||||
* 秒针宽=默认时钟刻度宽;
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
mSecondPointerLength = mRadius / 3 * 2;
|
|
||||||
mSecondPointerWidth = mDefaultScaleWidth;
|
|
||||||
|
|
||||||
// 中心点半径=(默认刻度宽+特殊刻度宽)/2
|
|
||||||
mPointRadius = (mDefaultScaleWidth + mParticularlyScaleWidth) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绘制时钟的外型形和刻度
|
* 绘制时钟的外型形和刻度
|
||||||
*/
|
*/
|
||||||
@ -82,10 +34,12 @@ public class SquareClock extends AbstractClock {
|
|||||||
if (j % 5 == 0) { // 特殊时刻
|
if (j % 5 == 0) { // 特殊时刻
|
||||||
mDefaultPaint.setStrokeWidth(mParticularlyScaleWidth);
|
mDefaultPaint.setStrokeWidth(mParticularlyScaleWidth);
|
||||||
mDefaultPaint.setColor(mColorParticularyScale);
|
mDefaultPaint.setColor(mColorParticularyScale);
|
||||||
|
mDefaultPaint.setAlpha(255);
|
||||||
scaleLength=mParticularlyScaleLength;
|
scaleLength=mParticularlyScaleLength;
|
||||||
} else { // 一般时刻
|
} else { // 一般时刻
|
||||||
mDefaultPaint.setStrokeWidth(mDefaultScaleWidth);
|
mDefaultPaint.setStrokeWidth(mDefaultScaleWidth);
|
||||||
mDefaultPaint.setColor(mColorDefaultScale);
|
mDefaultPaint.setColor(mColorDefaultScale);
|
||||||
|
mDefaultPaint.setAlpha(100);
|
||||||
scaleLength=mDefaultScaleLength;
|
scaleLength=mDefaultScaleLength;
|
||||||
}
|
}
|
||||||
floatLength=radianTanValue*scaleLength;
|
floatLength=radianTanValue*scaleLength;
|
||||||
@ -113,10 +67,12 @@ public class SquareClock extends AbstractClock {
|
|||||||
if (j % 5 == 0) { // 特殊时刻
|
if (j % 5 == 0) { // 特殊时刻
|
||||||
mDefaultPaint.setStrokeWidth(mParticularlyScaleWidth);
|
mDefaultPaint.setStrokeWidth(mParticularlyScaleWidth);
|
||||||
mDefaultPaint.setColor(mColorParticularyScale);
|
mDefaultPaint.setColor(mColorParticularyScale);
|
||||||
|
mDefaultPaint.setAlpha(255);
|
||||||
scaleLength=mParticularlyScaleLength;
|
scaleLength=mParticularlyScaleLength;
|
||||||
} else { // 一般时刻
|
} else { // 一般时刻
|
||||||
mDefaultPaint.setStrokeWidth(mDefaultScaleWidth);
|
mDefaultPaint.setStrokeWidth(mDefaultScaleWidth);
|
||||||
mDefaultPaint.setColor(mColorDefaultScale);
|
mDefaultPaint.setColor(mColorDefaultScale);
|
||||||
|
mDefaultPaint.setAlpha(100);
|
||||||
scaleLength=mDefaultScaleLength;
|
scaleLength=mDefaultScaleLength;
|
||||||
}
|
}
|
||||||
floatLength=radianTanValue*scaleLength;
|
floatLength=radianTanValue*scaleLength;
|
||||||
@ -127,7 +83,6 @@ public class SquareClock extends AbstractClock {
|
|||||||
canvas.drawLine(width,startY-stepLeng, width - scaleLength,startY-stepLeng+floatLength, mDefaultPaint);
|
canvas.drawLine(width,startY-stepLeng, width - scaleLength,startY-stepLeng+floatLength, mDefaultPaint);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,177 @@
|
|||||||
|
package clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.pointer;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
|
||||||
|
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.I_Pointer;
|
||||||
|
|
||||||
|
public abstract class AbstractPointer implements I_Pointer {
|
||||||
|
|
||||||
|
protected Paint mPointerPaint;
|
||||||
|
|
||||||
|
protected float mRadius, mPointRadius,
|
||||||
|
mHourPointerLength, mHourPointerWidth,
|
||||||
|
mMinutePointerLength, mMinutePointerWidth,
|
||||||
|
mSecondPointerLength, mSecondPointerWidth;
|
||||||
|
|
||||||
|
|
||||||
|
protected int mClockColor, mColorHourPointer,mColorMinutePointer, mColorSecondPointer;
|
||||||
|
|
||||||
|
// 当前时、分、秒
|
||||||
|
protected int mH, mM, mS;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(float mRadius,int mClockColor) {
|
||||||
|
this.mRadius = mRadius;
|
||||||
|
this.mClockColor = mClockColor;
|
||||||
|
mColorHourPointer=mColorMinutePointer=mColorSecondPointer=mClockColor;
|
||||||
|
initPaint();
|
||||||
|
initPointerLength(mRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void initPaint(){
|
||||||
|
mPointerPaint = new Paint();
|
||||||
|
mPointerPaint.setAntiAlias(true);
|
||||||
|
mPointerPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||||
|
mPointerPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
mPointerPaint.setColor(mClockColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void initPointerLength(float mRadius){
|
||||||
|
/*
|
||||||
|
* 默认时钟刻度长=半径/10;
|
||||||
|
* 默认时钟刻度宽=长/6;
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
float mDefaultScaleLength = mRadius / 10;
|
||||||
|
float mDefaultScaleWidth = mDefaultScaleLength / 6;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 特殊时钟刻度长=半径/5;
|
||||||
|
* 特殊时钟刻度宽=长/6;
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
float mParticularlyScaleLength = mRadius / 5;
|
||||||
|
float mParticularlyScaleWidth = mParticularlyScaleLength / 6;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 时针长=半径/3;
|
||||||
|
* 时针宽=特殊时钟刻度宽;
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
mHourPointerLength = mRadius / 3;
|
||||||
|
mHourPointerWidth = mParticularlyScaleWidth;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 分针长=半径/2;
|
||||||
|
* 分针宽=特殊时钟刻度宽;
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
mMinutePointerLength = mRadius / 2;
|
||||||
|
mMinutePointerWidth = mParticularlyScaleWidth;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 秒针长=半径/3*2;
|
||||||
|
* 秒针宽=默认时钟刻度宽;
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
mSecondPointerLength = mRadius / 3 * 2;
|
||||||
|
mSecondPointerWidth = mDefaultScaleWidth;
|
||||||
|
|
||||||
|
// 中心点半径=(默认刻度宽+特殊刻度宽)/2
|
||||||
|
mPointRadius = (mDefaultScaleWidth + mParticularlyScaleWidth) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绘制指针
|
||||||
|
*/
|
||||||
|
public void drawPointer(Canvas canvas, int mH,int mM,int mS, Paint paint) {
|
||||||
|
this.mH=mH;
|
||||||
|
this.mM=mM;
|
||||||
|
this.mS=mS;
|
||||||
|
|
||||||
|
drawHourPointer(canvas);
|
||||||
|
drawMinutePointer(canvas);
|
||||||
|
drawSecondPointer(canvas);
|
||||||
|
|
||||||
|
drawCenterCircle(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绘制中心原点,需要在指针绘制完成后才能绘制
|
||||||
|
protected void drawCenterCircle(Canvas canvas){
|
||||||
|
canvas.drawCircle(0, 0, mPointRadius, mPointerPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绘制时针
|
||||||
|
*/
|
||||||
|
protected void drawHourPointer(Canvas canvas) {
|
||||||
|
|
||||||
|
mPointerPaint.setStrokeWidth(mHourPointerWidth);
|
||||||
|
mPointerPaint.setColor(mColorHourPointer);
|
||||||
|
|
||||||
|
// 当前时间的总秒数
|
||||||
|
float s = mH * 60 * 60 + mM * 60 + mS;
|
||||||
|
// 百分比
|
||||||
|
float percentage = s / (12 * 60 * 60);
|
||||||
|
// 通过角度计算弧度值,因为时钟的角度起线是y轴负方向,而View角度的起线是x轴正方向,所以要加270度
|
||||||
|
float angle = calcAngle(percentage);
|
||||||
|
|
||||||
|
float x = calcX(mHourPointerLength , angle);
|
||||||
|
float y = calcY(mHourPointerLength , angle);
|
||||||
|
|
||||||
|
canvas.drawLine(0, 0, x, y, mPointerPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绘制分针
|
||||||
|
*/
|
||||||
|
protected void drawMinutePointer(Canvas canvas) {
|
||||||
|
mPointerPaint.setStrokeWidth(mMinutePointerWidth);
|
||||||
|
mPointerPaint.setColor(mColorMinutePointer);
|
||||||
|
|
||||||
|
float s = mM * 60 + mS;
|
||||||
|
float percentage = s / (60 * 60);
|
||||||
|
float angle = calcAngle(percentage);
|
||||||
|
|
||||||
|
float x = calcX(mMinutePointerLength , angle);
|
||||||
|
float y = calcY(mMinutePointerLength , angle);
|
||||||
|
|
||||||
|
canvas.drawLine(0, 0, x, y, mPointerPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绘制秒针
|
||||||
|
*/
|
||||||
|
protected void drawSecondPointer(Canvas canvas) {
|
||||||
|
|
||||||
|
mPointerPaint.setStrokeWidth(mSecondPointerWidth);
|
||||||
|
mPointerPaint.setColor(mColorSecondPointer);
|
||||||
|
|
||||||
|
float s = mS;
|
||||||
|
float percentage = s / 60;
|
||||||
|
float angle = calcAngle(percentage);
|
||||||
|
|
||||||
|
float x = calcX(mSecondPointerLength , angle);
|
||||||
|
float y = calcY(mSecondPointerLength , angle);
|
||||||
|
|
||||||
|
canvas.drawLine(0, 0, x, y, mPointerPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float calcAngle(float percentage){
|
||||||
|
return 270 + 360 * percentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float calcX(float baseLength,float angle){
|
||||||
|
return (float)(baseLength * Math.cos(Math.PI * 2 / 360 * angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float calcY(float baseLength,float angle){
|
||||||
|
return (float) (baseLength * Math.sin(Math.PI * 2 / 360 * angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.pointer;
|
||||||
|
|
||||||
|
public class DefaultPointer extends AbstractPointer {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
package clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.pointer;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Path;
|
||||||
|
|
||||||
|
public class LeafPointer extends SecondTailPointer {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initPointerLength(float mRadius) {
|
||||||
|
super.initPointerLength(mRadius);
|
||||||
|
mMinutePointerWidth=mMinutePointerWidth/3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawHourPointer(Canvas canvas) {
|
||||||
|
mPointerPaint.setStrokeWidth(mHourPointerWidth);
|
||||||
|
mPointerPaint.setColor(mColorHourPointer);
|
||||||
|
|
||||||
|
// 当前时间的总秒数
|
||||||
|
float s = mH * 60 * 60 + mM * 60 + mS;
|
||||||
|
// 百分比
|
||||||
|
float percentage = s / (12 * 60 * 60);
|
||||||
|
// 通过角度计算弧度值,因为时钟的角度起线是y轴负方向,而View角度的起线是x轴正方向,所以要加270度
|
||||||
|
float angle = calcAngle(percentage);
|
||||||
|
|
||||||
|
float x = calcX(mHourPointerLength, angle);
|
||||||
|
float y = calcY(mHourPointerLength, angle);
|
||||||
|
|
||||||
|
float minLength = mHourPointerLength / 2;
|
||||||
|
|
||||||
|
float x1 = calcX(minLength, angle + 20);
|
||||||
|
float y1 = calcY(minLength, angle + 20);
|
||||||
|
|
||||||
|
float x2 = calcX(minLength, angle - 20);
|
||||||
|
float y2 = calcY(minLength, angle - 20);
|
||||||
|
|
||||||
|
|
||||||
|
Path path = new Path();
|
||||||
|
path.cubicTo(0, 0, x1, y1, x, y);
|
||||||
|
path.cubicTo(x, y, x2, y2, 0, 0);
|
||||||
|
|
||||||
|
canvas.drawPath(path, mPointerPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawMinutePointer(Canvas canvas) {
|
||||||
|
mPointerPaint.setStrokeWidth(mMinutePointerWidth);
|
||||||
|
mPointerPaint.setColor(mColorMinutePointer);
|
||||||
|
|
||||||
|
float s = mM * 60 + mS;
|
||||||
|
float percentage = s / (60 * 60);
|
||||||
|
float angle = calcAngle(percentage);
|
||||||
|
|
||||||
|
float x = calcX(mMinutePointerLength, angle);
|
||||||
|
float y = calcY(mMinutePointerLength, angle);
|
||||||
|
|
||||||
|
float minLength = mMinutePointerLength / 2;
|
||||||
|
|
||||||
|
float x1 = calcX(minLength, angle + 10);
|
||||||
|
float y1 = calcY(minLength, angle + 10);
|
||||||
|
|
||||||
|
float x2 = calcX(minLength, angle - 10);
|
||||||
|
float y2 = calcY(minLength, angle - 10);
|
||||||
|
|
||||||
|
|
||||||
|
Path path = new Path();
|
||||||
|
path.cubicTo(0, 0, x1, y1, x, y);
|
||||||
|
path.cubicTo(x, y, x2, y2, 0, 0);
|
||||||
|
|
||||||
|
canvas.drawPath(path, mPointerPaint);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.pointer;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Path;
|
||||||
|
|
||||||
|
public class LeafTwoPointer extends SecondTailPointer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initPointerLength(float mRadius) {
|
||||||
|
super.initPointerLength(mRadius);
|
||||||
|
mMinutePointerWidth=mMinutePointerWidth/3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawHourPointer(Canvas canvas) {
|
||||||
|
mPointerPaint.setStrokeWidth(mHourPointerWidth);
|
||||||
|
mPointerPaint.setColor(mColorHourPointer);
|
||||||
|
|
||||||
|
// 当前时间的总秒数
|
||||||
|
float s = mH * 60 * 60 + mM * 60 + mS;
|
||||||
|
// 百分比
|
||||||
|
float percentage = s / (12 * 60 * 60);
|
||||||
|
// 通过角度计算弧度值,因为时钟的角度起线是y轴负方向,而View角度的起线是x轴正方向,所以要加270度
|
||||||
|
float angle = calcAngle(percentage);
|
||||||
|
|
||||||
|
float x = calcX(mHourPointerLength, angle);
|
||||||
|
float y = calcY(mHourPointerLength, angle);
|
||||||
|
|
||||||
|
float minLength = mHourPointerLength / 2;
|
||||||
|
|
||||||
|
float x1 = calcX(minLength, angle + 20);
|
||||||
|
float y1 = calcY(minLength, angle + 20);
|
||||||
|
|
||||||
|
float x2 = calcX(minLength, angle - 20);
|
||||||
|
float y2 = calcY(minLength, angle - 20);
|
||||||
|
|
||||||
|
|
||||||
|
Path path = new Path();
|
||||||
|
path.cubicTo(0, 0, x1, y1, x, y);
|
||||||
|
path.cubicTo(0, 0, x2, y2,x, y );
|
||||||
|
|
||||||
|
canvas.drawPath(path, mPointerPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawMinutePointer(Canvas canvas) {
|
||||||
|
mPointerPaint.setStrokeWidth(mMinutePointerWidth);
|
||||||
|
mPointerPaint.setColor(mColorMinutePointer);
|
||||||
|
|
||||||
|
float s = mM * 60 + mS;
|
||||||
|
float percentage = s / (60 * 60);
|
||||||
|
float angle = calcAngle(percentage);
|
||||||
|
|
||||||
|
float x = calcX(mMinutePointerLength, angle);
|
||||||
|
float y = calcY(mMinutePointerLength, angle);
|
||||||
|
|
||||||
|
float minLength = mMinutePointerLength / 2;
|
||||||
|
|
||||||
|
float x1 = calcX(minLength, angle + 10);
|
||||||
|
float y1 = calcY(minLength, angle + 10);
|
||||||
|
|
||||||
|
float x2 = calcX(minLength, angle - 10);
|
||||||
|
float y2 = calcY(minLength, angle - 10);
|
||||||
|
|
||||||
|
|
||||||
|
Path path = new Path();
|
||||||
|
path.cubicTo(0, 0, x1, y1, x, y);
|
||||||
|
path.cubicTo(0, 0,x2, y2, x, y);
|
||||||
|
|
||||||
|
canvas.drawPath(path, mPointerPaint);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.pointer;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
|
||||||
|
public class SecondTailPointer extends AbstractPointer{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initPointerLength(float mRadius) {
|
||||||
|
super.initPointerLength(mRadius);
|
||||||
|
mHourPointerLength = mRadius / 8*4.5f;
|
||||||
|
mMinutePointerLength = mRadius / 8*6;
|
||||||
|
mSecondPointerLength = mRadius / 8 * 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawCenterCircle(Canvas canvas) {
|
||||||
|
super.drawCenterCircle(canvas);
|
||||||
|
mPointerPaint.setColor(Color.BLACK);
|
||||||
|
canvas.drawCircle(0, 0, mPointRadius/2, mPointerPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawSecondPointer(Canvas canvas) {
|
||||||
|
super.drawSecondPointer(canvas);
|
||||||
|
|
||||||
|
mPointerPaint.setStrokeWidth(mSecondPointerWidth*1.5f);
|
||||||
|
|
||||||
|
float s = mS;
|
||||||
|
float percentage = s / 60;
|
||||||
|
float angle = calcAngle(percentage)+180;
|
||||||
|
|
||||||
|
float x = calcX(mSecondPointerLength/5 , angle);
|
||||||
|
float y = calcY(mSecondPointerLength/5 , angle);
|
||||||
|
|
||||||
|
canvas.drawLine(0, 0, x, y, mPointerPaint);
|
||||||
|
|
||||||
|
canvas.drawCircle(0,0,mSecondPointerWidth*2,mPointerPaint);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
package clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.pointer;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Path;
|
||||||
|
|
||||||
|
public class SwordPointer extends SecondTailPointer{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initPointerLength(float mRadius) {
|
||||||
|
super.initPointerLength(mRadius);
|
||||||
|
mHourPointerWidth=mHourPointerWidth/4;
|
||||||
|
mMinutePointerWidth=mMinutePointerWidth/4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawHourPointer(Canvas canvas) {
|
||||||
|
mPointerPaint.setStrokeWidth(mHourPointerWidth);
|
||||||
|
mPointerPaint.setColor(mColorHourPointer);
|
||||||
|
|
||||||
|
// 当前时间的总秒数
|
||||||
|
float s = mH * 60 * 60 + mM * 60 + mS;
|
||||||
|
// 百分比
|
||||||
|
float percentage = s / (12 * 60 * 60);
|
||||||
|
// 通过角度计算弧度值,因为时钟的角度起线是y轴负方向,而View角度的起线是x轴正方向,所以要加270度
|
||||||
|
float angle = calcAngle(percentage);
|
||||||
|
|
||||||
|
float x = calcX(mHourPointerLength , angle);
|
||||||
|
float y = calcY(mHourPointerLength , angle);
|
||||||
|
|
||||||
|
float minLength=mHourPointerLength*4/5;
|
||||||
|
|
||||||
|
float x3 = calcX(minLength , angle+10);
|
||||||
|
float y3 = calcY(minLength , angle+10);
|
||||||
|
|
||||||
|
float x4 = calcX(minLength , angle-10);
|
||||||
|
float y4 = calcY(minLength , angle-10);
|
||||||
|
|
||||||
|
minLength=mHourPointerLength/5;
|
||||||
|
|
||||||
|
float x1=calcX(minLength , angle+180+20);
|
||||||
|
float y1 = calcY(minLength , angle+180+20);
|
||||||
|
|
||||||
|
float x2=calcX(minLength, angle+180-20);
|
||||||
|
float y2 = calcY(minLength , angle+180-20);
|
||||||
|
|
||||||
|
|
||||||
|
Path path=new Path();
|
||||||
|
path.lineTo(x1,y1);
|
||||||
|
path.lineTo(x2,y2);
|
||||||
|
path.lineTo(0,0);
|
||||||
|
path.lineTo(x3,y3);
|
||||||
|
path.lineTo(x,y);
|
||||||
|
path.lineTo(x4,y4);
|
||||||
|
path.lineTo(0,0);
|
||||||
|
|
||||||
|
canvas.drawPath(path,mPointerPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawMinutePointer(Canvas canvas) {
|
||||||
|
mPointerPaint.setStrokeWidth(mMinutePointerWidth);
|
||||||
|
mPointerPaint.setColor(mColorMinutePointer);
|
||||||
|
|
||||||
|
float s = mM * 60 + mS;
|
||||||
|
float percentage = s / (60 * 60);
|
||||||
|
float angle = calcAngle(percentage);
|
||||||
|
|
||||||
|
float x = calcX(mMinutePointerLength , angle);
|
||||||
|
float y = calcY(mMinutePointerLength , angle);
|
||||||
|
|
||||||
|
float minLength=mMinutePointerLength*4/5;
|
||||||
|
|
||||||
|
float x3 = calcX(minLength , angle+6);
|
||||||
|
float y3 = calcY(minLength , angle+6);
|
||||||
|
|
||||||
|
float x4 = calcX(minLength , angle-6);
|
||||||
|
float y4 = calcY(minLength , angle-6);
|
||||||
|
|
||||||
|
minLength=mMinutePointerLength/5;
|
||||||
|
|
||||||
|
float x1=calcX(minLength , angle+180+10);
|
||||||
|
float y1 = calcY(minLength , angle+180+10);
|
||||||
|
|
||||||
|
float x2=calcX(minLength, angle+180-10);
|
||||||
|
float y2 = calcY(minLength , angle+180-10);
|
||||||
|
|
||||||
|
|
||||||
|
Path path=new Path();
|
||||||
|
path.lineTo(x1,y1);
|
||||||
|
path.lineTo(x2,y2);
|
||||||
|
path.lineTo(0,0);
|
||||||
|
path.lineTo(x3,y3);
|
||||||
|
path.lineTo(x,y);
|
||||||
|
path.lineTo(x4,y4);
|
||||||
|
path.lineTo(0,0);
|
||||||
|
|
||||||
|
canvas.drawPath(path,mPointerPaint);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
package clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.pointer;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Path;
|
||||||
|
|
||||||
|
public class TrianglePointer extends SecondTailPointer{
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawHourPointer(Canvas canvas) {
|
||||||
|
mPointerPaint.setStrokeWidth(mHourPointerWidth);
|
||||||
|
mPointerPaint.setColor(mColorHourPointer);
|
||||||
|
|
||||||
|
// 当前时间的总秒数
|
||||||
|
float s = mH * 60 * 60 + mM * 60 + mS;
|
||||||
|
// 百分比
|
||||||
|
float percentage = s / (12 * 60 * 60);
|
||||||
|
// 通过角度计算弧度值,因为时钟的角度起线是y轴负方向,而View角度的起线是x轴正方向,所以要加270度
|
||||||
|
float angle = calcAngle(percentage);
|
||||||
|
|
||||||
|
float x = calcX(mHourPointerLength , angle);
|
||||||
|
float y = calcY(mHourPointerLength , angle);
|
||||||
|
|
||||||
|
float minLength=mHourPointerLength/5;
|
||||||
|
|
||||||
|
float x1=calcX(minLength , angle+180+20);
|
||||||
|
float y1 = calcY(minLength , angle+180+20);
|
||||||
|
|
||||||
|
float x2=calcX(minLength, angle+180-20);
|
||||||
|
float y2 = calcY(minLength , angle+180-20);
|
||||||
|
|
||||||
|
|
||||||
|
Path path=new Path();
|
||||||
|
path.moveTo(x1,y1);
|
||||||
|
path.lineTo(x2,y2);
|
||||||
|
path.lineTo(x,y);
|
||||||
|
path.lineTo(x1,y1);
|
||||||
|
|
||||||
|
canvas.drawPath(path,mPointerPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawMinutePointer(Canvas canvas) {
|
||||||
|
mPointerPaint.setStrokeWidth(mMinutePointerWidth);
|
||||||
|
mPointerPaint.setColor(mColorMinutePointer);
|
||||||
|
|
||||||
|
float s = mM * 60 + mS;
|
||||||
|
float percentage = s / (60 * 60);
|
||||||
|
float angle = calcAngle(percentage);
|
||||||
|
|
||||||
|
float x = calcX(mMinutePointerLength , angle);
|
||||||
|
float y = calcY(mMinutePointerLength , angle);
|
||||||
|
|
||||||
|
float minLength=mMinutePointerLength/5;
|
||||||
|
|
||||||
|
float x1=calcX(minLength , angle+180+20);
|
||||||
|
float y1 = calcY(minLength , angle+180+20);
|
||||||
|
|
||||||
|
float x2=calcX(minLength, angle+180-20);
|
||||||
|
float y2 = calcY(minLength , angle+180-20);
|
||||||
|
|
||||||
|
|
||||||
|
Path path=new Path();
|
||||||
|
path.moveTo(x1,y1);
|
||||||
|
path.lineTo(x2,y2);
|
||||||
|
path.lineTo(x,y);
|
||||||
|
path.lineTo(x1,y1);
|
||||||
|
|
||||||
|
canvas.drawPath(path,mPointerPaint);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.pointer;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
|
||||||
|
public class TwoStepPointer extends SecondTailPointer{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绘制时针
|
||||||
|
*/
|
||||||
|
protected void drawHourPointer(Canvas canvas) {
|
||||||
|
|
||||||
|
mPointerPaint.setStrokeWidth(mHourPointerWidth*2);
|
||||||
|
mPointerPaint.setColor(mColorHourPointer);
|
||||||
|
|
||||||
|
// 当前时间的总秒数
|
||||||
|
float s = mH * 60 * 60 + mM * 60 + mS;
|
||||||
|
// 百分比
|
||||||
|
float percentage = s / (12 * 60 * 60);
|
||||||
|
// 通过角度计算弧度值,因为时钟的角度起线是y轴负方向,而View角度的起线是x轴正方向,所以要加270度
|
||||||
|
float angle = calcAngle(percentage);
|
||||||
|
|
||||||
|
float x = calcX(mHourPointerLength , angle);
|
||||||
|
float y = calcY(mHourPointerLength , angle);
|
||||||
|
|
||||||
|
float x1 = calcX(mHourPointerLength/4 , angle);
|
||||||
|
float y1 = calcY(mHourPointerLength/4 , angle);
|
||||||
|
|
||||||
|
canvas.drawLine(x1, y1, x, y, mPointerPaint);
|
||||||
|
|
||||||
|
mPointerPaint.setStrokeWidth(mHourPointerWidth/4);
|
||||||
|
canvas.drawLine(0,0,x1, y1, mPointerPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绘制分针
|
||||||
|
*/
|
||||||
|
protected void drawMinutePointer(Canvas canvas) {
|
||||||
|
mPointerPaint.setStrokeWidth(mMinutePointerWidth*2);
|
||||||
|
mPointerPaint.setColor(mColorMinutePointer);
|
||||||
|
|
||||||
|
float s = mM * 60 + mS;
|
||||||
|
float percentage = s / (60 * 60);
|
||||||
|
float angle = calcAngle(percentage);
|
||||||
|
|
||||||
|
float x = calcX(mMinutePointerLength , angle);
|
||||||
|
float y = calcY(mMinutePointerLength , angle);
|
||||||
|
|
||||||
|
float x1 = calcX(mMinutePointerLength/4 , angle);
|
||||||
|
float y1 = calcY(mMinutePointerLength/4 , angle);
|
||||||
|
|
||||||
|
canvas.drawLine(x1, y1, x, y, mPointerPaint);
|
||||||
|
|
||||||
|
mPointerPaint.setStrokeWidth(mMinutePointerWidth/4);
|
||||||
|
canvas.drawLine(0,0,x1, y1, mPointerPaint);
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ import android.content.Context;
|
|||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.LinearGradient;
|
import android.graphics.LinearGradient;
|
||||||
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Shader;
|
import android.graphics.Shader;
|
||||||
import android.text.TextPaint;
|
import android.text.TextPaint;
|
||||||
@ -12,8 +13,15 @@ import android.util.AttributeSet;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
import clock.socoolby.com.clock.widget.textview.charanimator.AbstractCharAnimator;
|
||||||
|
import clock.socoolby.com.clock.widget.textview.charanimator.CharAnimatorEnum;
|
||||||
|
import clock.socoolby.com.clock.widget.textview.charanimator.Down2UpCharAnimator;
|
||||||
|
import clock.socoolby.com.clock.widget.textview.charanimator.Marquee3DCharAnimator;
|
||||||
|
import clock.socoolby.com.clock.widget.textview.charanimator.Up2DownCharAnimator;
|
||||||
|
|
||||||
public class DigitTextView extends android.support.v7.widget.AppCompatTextView {
|
public class DigitTextView extends android.support.v7.widget.AppCompatTextView {
|
||||||
public static final String Tag=DigitTextView.class.getSimpleName();
|
public static final String Tag=DigitTextView.class.getSimpleName();
|
||||||
|
|
||||||
@ -29,6 +37,8 @@ public class DigitTextView extends android.support.v7.widget.AppCompatTextView {
|
|||||||
|
|
||||||
int textWidth=0;
|
int textWidth=0;
|
||||||
|
|
||||||
|
private CharSequence preString=null;
|
||||||
|
|
||||||
public DigitTextView(Context context) {
|
public DigitTextView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
@ -49,10 +59,13 @@ public class DigitTextView extends android.support.v7.widget.AppCompatTextView {
|
|||||||
|
|
||||||
boolean isLinearGradientPosAble=false;
|
boolean isLinearGradientPosAble=false;
|
||||||
|
|
||||||
|
boolean isReflectedAble=false;
|
||||||
|
|
||||||
public void setLinearGradientRandom(boolean able){
|
public void setLinearGradientRandom(boolean able){
|
||||||
if(able){
|
if(able){
|
||||||
linearGradientColors= new int[]{roundColor(), roundColor(), roundColor(), roundColor(), roundColor(), roundColor(), roundColor()};
|
linearGradientColors= new int[]{roundColor(), roundColor(), roundColor(), roundColor(), roundColor(), roundColor(), roundColor()};
|
||||||
isLinearGradientPosAble=rand.nextBoolean();
|
isLinearGradientPosAble=rand.nextBoolean();
|
||||||
|
isReflectedAble=rand.nextBoolean();
|
||||||
}
|
}
|
||||||
setLinearGradientAble(able);
|
setLinearGradientAble(able);
|
||||||
setShadowType(rand.nextInt(3));
|
setShadowType(rand.nextInt(3));
|
||||||
@ -83,8 +96,9 @@ public class DigitTextView extends android.support.v7.widget.AppCompatTextView {
|
|||||||
case 1://阴影效果
|
case 1://阴影效果
|
||||||
setShadowLayer(4, 10, 10, Color.BLACK);
|
setShadowLayer(4, 10, 10, Color.BLACK);
|
||||||
break;
|
break;
|
||||||
case 2://浮雕效果
|
case 2:
|
||||||
setShadowLayer(1, 0.5f, 0.5f, Color.argb(200,204,204,204));
|
//setShadowLayer(1, 0.5f, 0.5f, Color.argb(200,204,204,204));//浮雕效果
|
||||||
|
setShadowLayer(10, 0, 0, Color.parseColor("#FF4141"));//边缘模糊
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
setShadowLayer(0,0,0,getPaint().getColor());
|
setShadowLayer(0,0,0,getPaint().getColor());
|
||||||
@ -115,6 +129,25 @@ public class DigitTextView extends android.support.v7.widget.AppCompatTextView {
|
|||||||
this.linearGradientColors = linearGradientColors;
|
this.linearGradientColors = linearGradientColors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CharAnimatorEnum getCurrentCharAnimatorType() {
|
||||||
|
return currentCharAnimatorType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentCharAnimatorType(CharAnimatorEnum currentCharAnimatorType) {
|
||||||
|
this.currentCharAnimatorType = currentCharAnimatorType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int textHight;
|
||||||
|
private int baseCharWidth;
|
||||||
|
private int flagCharwidth;
|
||||||
|
private int smallTextHight;
|
||||||
|
private int smallCharWidth;
|
||||||
|
private int textLength;
|
||||||
|
private int textSmallSpan;
|
||||||
|
private HashMap<Integer, AbstractCharAnimator> charAnimatorHashMap=new HashMap<>();
|
||||||
|
|
||||||
|
private CharAnimatorEnum currentCharAnimatorType= CharAnimatorEnum.Marquee3D_Up;
|
||||||
|
|
||||||
protected void onDraw(Canvas canvas) {
|
protected void onDraw(Canvas canvas) {
|
||||||
int color = getCurrentTextColor();
|
int color = getCurrentTextColor();
|
||||||
|
|
||||||
@ -126,15 +159,15 @@ public class DigitTextView extends android.support.v7.widget.AppCompatTextView {
|
|||||||
|
|
||||||
Paint.FontMetricsInt fm=mTextPaint.getFontMetricsInt();
|
Paint.FontMetricsInt fm=mTextPaint.getFontMetricsInt();
|
||||||
|
|
||||||
int baseCharWidth= getCharWidth("8",mTextPaint);
|
baseCharWidth= getCharWidth("8",mTextPaint);
|
||||||
int flagCharwidth=getCharWidth(":",mTextPaint);
|
flagCharwidth=getCharWidth(":",mTextPaint);
|
||||||
int textHight=-fm.descent - fm.ascent;
|
textHight=-fm.descent - fm.ascent;
|
||||||
int smallTextHight=0;
|
smallTextHight=0;
|
||||||
int smallCharWidth=0;
|
smallCharWidth=0;
|
||||||
Paint smallCharPaint=null;
|
Paint smallCharPaint=null;
|
||||||
|
|
||||||
int textLength=textToDraw.length();
|
textLength=textToDraw.length();
|
||||||
int textSmallSpan=0;
|
textSmallSpan=0;
|
||||||
|
|
||||||
if(textLength>4){
|
if(textLength>4){
|
||||||
textWidth=baseCharWidth*4+flagCharwidth;
|
textWidth=baseCharWidth*4+flagCharwidth;
|
||||||
@ -152,6 +185,8 @@ public class DigitTextView extends android.support.v7.widget.AppCompatTextView {
|
|||||||
float startX=(getWidth()-textWidth-textSmallSpan)/2;
|
float startX=(getWidth()-textWidth-textSmallSpan)/2;
|
||||||
float startY=(getHeight()+textHight)/2;
|
float startY=(getHeight()+textHight)/2;
|
||||||
|
|
||||||
|
AbstractCharAnimator charAnimator;
|
||||||
|
|
||||||
for(int i=0;i<textLength;i++){
|
for(int i=0;i<textLength;i++){
|
||||||
String c=String.valueOf(textToDraw.charAt(i));
|
String c=String.valueOf(textToDraw.charAt(i));
|
||||||
if(i<5){
|
if(i<5){
|
||||||
@ -160,7 +195,24 @@ public class DigitTextView extends android.support.v7.widget.AppCompatTextView {
|
|||||||
startX+=flagCharwidth;
|
startX+=flagCharwidth;
|
||||||
}else{
|
}else{
|
||||||
int charWidth= getCharWidth(c,mTextPaint);
|
int charWidth= getCharWidth(c,mTextPaint);
|
||||||
canvas.drawText(c, startX+(baseCharWidth-charWidth)/2, startY+baseLineDown, mTextPaint);
|
if(currentCharAnimatorType!= CharAnimatorEnum.NOSETUP) {
|
||||||
|
charAnimator = charAnimatorHashMap.get(i);
|
||||||
|
if (charAnimator != null && !charAnimator.isCharAnimatorRuning()) {
|
||||||
|
charAnimatorHashMap.remove(i);
|
||||||
|
charAnimator=null;
|
||||||
|
}
|
||||||
|
if (charAnimator == null&&preString != null&&preString.length()==textToDraw.length() && textToDraw.charAt(i) != preString.charAt(i)) {
|
||||||
|
charAnimator=createCharAnimator(String.valueOf(preString.charAt(i)), c, currentCharAnimatorType);
|
||||||
|
charAnimatorHashMap.put(i, charAnimator);
|
||||||
|
}
|
||||||
|
if (charAnimator != null) {
|
||||||
|
charAnimator.drawCharAnimator(canvas, startX + (baseCharWidth - charWidth) / 2, startY + baseLineDown, mTextPaint);
|
||||||
|
Log.d(Tag,"charAnimator index i:"+i+"\tanimator percent:");
|
||||||
|
invalidate();
|
||||||
|
}else
|
||||||
|
drawChar(canvas, c, startX + (baseCharWidth - charWidth) / 2, startY + baseLineDown, mTextPaint);
|
||||||
|
}else
|
||||||
|
drawChar(canvas, c, startX + (baseCharWidth - charWidth) / 2, startY + baseLineDown, mTextPaint);
|
||||||
startX+=baseCharWidth;
|
startX+=baseCharWidth;
|
||||||
}
|
}
|
||||||
}else if(i==5) {
|
}else if(i==5) {
|
||||||
@ -168,11 +220,54 @@ public class DigitTextView extends android.support.v7.widget.AppCompatTextView {
|
|||||||
} else {
|
} else {
|
||||||
float centerY=(getHeight()+smallTextHight)/2;
|
float centerY=(getHeight()+smallTextHight)/2;
|
||||||
centerY=centerY+(startY-centerY)/2+smallCharPaint.getFontMetrics().descent;
|
centerY=centerY+(startY-centerY)/2+smallCharPaint.getFontMetrics().descent;
|
||||||
canvas.drawText(c, startX, centerY+baseLineDown, smallCharPaint);
|
drawChar(canvas,c, startX, centerY+baseLineDown, smallCharPaint);
|
||||||
startX+=smallCharWidth;
|
startX+=smallCharWidth;
|
||||||
//Log.d(Tag,"view hight:"+getHeight()+"\t startY:"+startY+"\t text hight:"+textHight+"small text hight:"+smallTextHight);
|
//Log.d(Tag,"view hight:"+getHeight()+"\t startY:"+startY+"\t text hight:"+textHight+"small text hight:"+smallTextHight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
preString=textToDraw;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawChar(Canvas canvas,String c,float startX,float startY,Paint mTextPaint){
|
||||||
|
if(isReflectedAble)
|
||||||
|
drawCharReflected(canvas,c, startX, startY, mTextPaint);
|
||||||
|
canvas.drawText(c, startX, startY, mTextPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void drawCharReflected(Canvas canvas,String c,float startX,float startY,Paint mTextPaint){
|
||||||
|
canvas.save();
|
||||||
|
Paint paint = new Paint(mTextPaint);
|
||||||
|
LinearGradient shader = new LinearGradient(startX,
|
||||||
|
-startY, startX,
|
||||||
|
-startY-textHight*6/5,
|
||||||
|
Color.BLACK, 0x00ffffff, Shader.TileMode.MIRROR);// 创建线性渐变LinearGradient对象
|
||||||
|
Matrix matrix = new Matrix();
|
||||||
|
matrix.preScale(1, -1); // 实现图片的反转
|
||||||
|
paint.setShader(shader); // 绘制
|
||||||
|
paint.setAlpha(50);
|
||||||
|
canvas.setMatrix(matrix);
|
||||||
|
canvas.drawText(c, startX, -startY, paint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
private AbstractCharAnimator createCharAnimator(String preString, String currentString, CharAnimatorEnum type){
|
||||||
|
AbstractCharAnimator charAnimator=null;
|
||||||
|
switch (type){
|
||||||
|
case DOWN2UP:
|
||||||
|
charAnimator= new Down2UpCharAnimator(preString,currentString);
|
||||||
|
break;
|
||||||
|
case UP2DOWN:
|
||||||
|
charAnimator= new Up2DownCharAnimator(preString,currentString);
|
||||||
|
break;
|
||||||
|
case Marquee3D_Up:
|
||||||
|
charAnimator=new Marquee3DCharAnimator(preString,currentString,Marquee3DCharAnimator.D2U);
|
||||||
|
break;
|
||||||
|
case Marquee3D_Down:
|
||||||
|
charAnimator=new Marquee3DCharAnimator(preString,currentString,Marquee3DCharAnimator.U2D);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return charAnimator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package clock.socoolby.com.clock.widget.textview.charanimator;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
|
||||||
|
public abstract class AbstractCharAnimator {
|
||||||
|
protected boolean charAnimatorRuning;
|
||||||
|
protected float charAnimatorPercent;
|
||||||
|
|
||||||
|
protected String preString,currentString;
|
||||||
|
|
||||||
|
public AbstractCharAnimator(String preString, String currentString) {
|
||||||
|
this.preString = preString;
|
||||||
|
this.currentString = currentString;
|
||||||
|
charAnimatorRuning=true;
|
||||||
|
charAnimatorPercent=0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawCharAnimator(Canvas canvas, float startX, float startY, Paint mTextPaint){
|
||||||
|
drawCharPre(canvas, preString, startX, startY, mTextPaint,charAnimatorPercent);
|
||||||
|
drawCharCurrent(canvas, currentString, startX, startY, mTextPaint,charAnimatorPercent);
|
||||||
|
move();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void drawCharPre(Canvas canvas,String strToDraw, float startX, float startY, Paint mTextPaint,final float percent);
|
||||||
|
|
||||||
|
public abstract void drawCharCurrent(Canvas canvas,String strToDraw, float startX, float startY, Paint mTextPaint,final float percent);
|
||||||
|
|
||||||
|
public void move(){
|
||||||
|
charAnimatorPercent+=0.05f;
|
||||||
|
if(charAnimatorPercent>1)
|
||||||
|
charAnimatorRuning=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCharAnimatorRuning() {
|
||||||
|
return charAnimatorRuning;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package clock.socoolby.com.clock.widget.textview.charanimator;
|
||||||
|
|
||||||
|
public enum CharAnimatorEnum{
|
||||||
|
NOSETUP,UP2DOWN,DOWN2UP,Marquee3D_Up,Marquee3D_Down;
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package clock.socoolby.com.clock.widget.textview.charanimator;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
|
||||||
|
public class Down2UpCharAnimator extends AbstractCharAnimator {
|
||||||
|
public Down2UpCharAnimator(String preString, String currentString) {
|
||||||
|
super(preString, currentString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawCharPre(Canvas canvas, String strToDraw, float startX, float startY, Paint mTextPaint, float percent) {
|
||||||
|
canvas.drawText(strToDraw, startX, startY-startY*percent, mTextPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawCharCurrent(Canvas canvas, String strToDraw, float startX, float startY, Paint mTextPaint, float percent) {
|
||||||
|
canvas.drawText(strToDraw, startX, 2*startY-startY*percent, mTextPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,113 @@
|
|||||||
|
package clock.socoolby.com.clock.widget.textview.charanimator;
|
||||||
|
|
||||||
|
import android.graphics.Camera;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Matrix;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
|
||||||
|
//参考:https://github.com/xiangcman/Marquee3DView
|
||||||
|
public class Marquee3DCharAnimator extends AbstractCharAnimator {
|
||||||
|
|
||||||
|
//从下到上进行旋转滚动
|
||||||
|
public static final int D2U = 1;
|
||||||
|
//从上到下进行旋转滚动
|
||||||
|
public static final int U2D = 2;
|
||||||
|
|
||||||
|
//负责围绕那个轴进行旋转
|
||||||
|
private Camera camera;
|
||||||
|
//负责控制旋转点
|
||||||
|
private Matrix matrix;
|
||||||
|
|
||||||
|
private float changeRotate;
|
||||||
|
|
||||||
|
private float translateY;
|
||||||
|
|
||||||
|
private int direction;
|
||||||
|
|
||||||
|
public Marquee3DCharAnimator(String preString, String currentString,int direction) {
|
||||||
|
super(preString, currentString);
|
||||||
|
this.direction=direction;
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initialize() {
|
||||||
|
camera = new Camera();
|
||||||
|
matrix = new Matrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void move() {
|
||||||
|
super.move();
|
||||||
|
changeRotate = 90*charAnimatorPercent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawCharPre(Canvas canvas, String strToDraw, float startX, float startY, Paint mTextPaint, float percent) {
|
||||||
|
//从0到height的一个过程
|
||||||
|
translateY = startY *charAnimatorPercent;
|
||||||
|
|
||||||
|
int alpha = (int) (255 - percent * 255);
|
||||||
|
mTextPaint.setAlpha(alpha);
|
||||||
|
|
||||||
|
float width=startX;
|
||||||
|
float height=startY;
|
||||||
|
|
||||||
|
canvas.save();
|
||||||
|
camera.save();
|
||||||
|
if (direction == D2U) {
|
||||||
|
//当前的item是往里面转动的,因此角度是增大的
|
||||||
|
camera.rotateX(changeRotate);//0到90度的过程
|
||||||
|
} else {
|
||||||
|
camera.rotateX(-changeRotate);
|
||||||
|
}
|
||||||
|
camera.getMatrix(matrix);
|
||||||
|
camera.restore();
|
||||||
|
if (direction == D2U) {
|
||||||
|
matrix.preTranslate(-width / 2, -height);
|
||||||
|
matrix.postTranslate(width / 2, height - translateY);//最后跑到0的位置了
|
||||||
|
} else {
|
||||||
|
matrix.preTranslate(-width / 2, 0);
|
||||||
|
matrix.postTranslate(width / 2, translateY);
|
||||||
|
}
|
||||||
|
canvas.setMatrix(matrix);
|
||||||
|
canvas.drawText(strToDraw, startX, startY, mTextPaint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawCharCurrent(Canvas canvas, String strToDraw, float startX, float startY, Paint mTextPaint, float percent) {
|
||||||
|
|
||||||
|
translateY = startY *charAnimatorPercent;
|
||||||
|
|
||||||
|
float width=startX;
|
||||||
|
float height=startY;
|
||||||
|
|
||||||
|
int alpha = (int) (percent * 255);
|
||||||
|
mTextPaint.setAlpha(alpha);
|
||||||
|
|
||||||
|
canvas.save();
|
||||||
|
camera.save();
|
||||||
|
if (direction == D2U) {
|
||||||
|
//从-90度到0度的过程
|
||||||
|
camera.rotateX(-90 + changeRotate);
|
||||||
|
} else {
|
||||||
|
//从上到下是90度到0度的过程
|
||||||
|
camera.rotateX(90 - changeRotate);
|
||||||
|
}
|
||||||
|
camera.getMatrix(matrix);
|
||||||
|
camera.restore();
|
||||||
|
|
||||||
|
if (direction == D2U) {
|
||||||
|
matrix.preTranslate(-width / 2, 0);
|
||||||
|
matrix.postTranslate(width / 2, height + (-translateY));
|
||||||
|
} else {
|
||||||
|
matrix.preTranslate(-width / 2, -height);
|
||||||
|
matrix.postTranslate(width / 2, translateY);
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.setMatrix(matrix);
|
||||||
|
|
||||||
|
canvas.drawText(strToDraw, startX, startY, mTextPaint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package clock.socoolby.com.clock.widget.textview.charanimator;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
|
||||||
|
public class Up2DownCharAnimator extends AbstractCharAnimator {
|
||||||
|
public Up2DownCharAnimator(String preString, String currentString) {
|
||||||
|
super(preString, currentString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawCharPre(Canvas canvas, String strToDraw, float startX, float startY, Paint mTextPaint, float percent) {
|
||||||
|
canvas.drawText(strToDraw, startX, startY+startY*percent, mTextPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawCharCurrent(Canvas canvas, String strToDraw, float startX, float startY, Paint mTextPaint, float percent) {
|
||||||
|
canvas.drawText(strToDraw, startX, startY*percent, mTextPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
18
app/src/main/res/drawable/ic_alarm_clock.xml
Normal file
18
app/src/main/res/drawable/ic_alarm_clock.xml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:pathData="M3.7526,0.8136c-0.6062,0.1332 -0.7349,0.2251 -1.9243,1.4054c-0.6521,0.6475 -1.1666,1.194 -1.2538,1.3411c-0.078,0.1332 -0.1884,0.4042 -0.2388,0.6017c-0.2206,0.859 -0.101,1.1666 0.7992,2.0806c0.3262,0.3353 0.6154,0.6108 0.643,0.6108c0.0643,-0 4.5744,-4.5101 4.5744,-4.5744c0,-0.0734 -1.0426,-1.0747 -1.295,-1.2492c-0.4183,-0.2849 -0.7399,-0.3401 -1.3046,-0.216Z"
|
||||||
|
android:fillColor="#FFF"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M19.2895,0.8321c-0.1241,0.0504 -0.2986,0.1469 -0.3905,0.2158c-0.2388,0.179 -1.2492,1.1758 -1.2492,1.2355c0,0.0643 4.5101,4.5696 4.5742,4.5696c0.0276,-0 0.3168,-0.2755 0.6475,-0.6108c0.8957,-0.9139 1.0104,-1.2262 0.7946,-2.076c-0.0504,-0.1975 -0.1469,-0.4546 -0.2112,-0.5695c-0.1517,-0.2573 -2.1677,-2.3009 -2.4526,-2.4847c-0.4958,-0.312 -1.2996,-0.4452 -1.7129,-0.2798Z"
|
||||||
|
android:fillColor="#FFF"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M10.5084,2.3981c-2.1494,0.3307 -4.014,1.2446 -5.5618,2.7235c-2.7326,2.6086 -3.7937,6.4663 -2.7924,10.1268c0.2388,0.8726 0.7118,1.9428 1.2079,2.7418c0.0506,0.0826 -0.0458,0.3262 -0.7716,1.9702l-0.8314,1.8739l0,0.7073l0,0.7073l0.7118,-0l0.7118,-0l1.4698,-1.1712c0.8083,-0.643 1.4789,-1.1712 1.4926,-1.1712c0.0091,-0 0.179,0.1056 0.3766,0.2342c0.473,0.3122 1.5293,0.822 2.1079,1.0195c1.1393,0.395 2.1175,0.5558 3.3713,0.5558c0.9691,-0 1.5799,-0.0689 2.4341,-0.2803c0.9967,-0.2388 2.0988,-0.7073 2.9578,-1.2446c0.2479,-0.1562 0.4594,-0.2849 0.4685,-0.2849c0.0091,-0 0.6797,0.5282 1.488,1.1712l1.4698,1.1712l0.7118,-0l0.7118,-0l0,-0.7073l0,-0.7027l-0.8311,-1.8785l-0.8316,-1.878l0.0826,-0.1378c0.9552,-1.6075 1.4146,-3.0449 1.5341,-4.7626c0.2479,-3.6511 -1.4789,-7.1232 -4.579,-9.2129c-0.9185,-0.6199 -2.2366,-1.1803 -3.3571,-1.4282c-1.1251,-0.2527 -2.6638,-0.3079 -3.7522,-0.1426ZM12.6946,4.8782c1.8691,0.193 3.3938,0.9139 4.7074,2.2229c1.3502,1.3502 2.0666,2.9026 2.232,4.836c0.115,1.3457 -0.1195,2.5949 -0.7255,3.8717c-1.0517,2.2044 -3.0494,3.743 -5.4883,4.2346c-0.7531,0.1469 -2.0806,0.1469 -2.8337,-0c-3.2239,-0.6478 -5.6443,-3.1416 -6.1634,-6.3473c-0.2434,-1.511 0.0322,-3.2378 0.7394,-4.6433c0.7164,-1.4376 2.0851,-2.7739 3.5364,-3.4582c1.2538,-0.5971 2.6683,-0.8496 3.9958,-0.7164Z"
|
||||||
|
android:fillColor="#FFF"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M11.4499,5.8886c-3.0221,0.2479 -5.447,2.489 -6.0026,5.5342c-0.101,0.5556 -0.101,1.6534 0,2.2138c0.2525,1.3824 0.8635,2.549 1.8691,3.5549c0.9691,0.9691 2.0345,1.5478 3.3986,1.837c0.6384,0.1378 1.8324,0.1471 2.4571,0.023c2.448,-0.4822 4.3675,-2.154 5.1391,-4.4825c0.2342,-0.7073 0.3168,-1.2401 0.3168,-2.0438c0,-1.6258 -0.5098,-3.0403 -1.5614,-4.3034c-1.3502,-1.6212 -3.4812,-2.5078 -5.6167,-2.333ZM12.5062,9.7006l0,2.8015l0.2525,-0l0.2527,-0l0,0.2527l0,0.2525l0.2525,-0l0.2525,-0l0,0.2527l0,0.2527l0.2527,-0l0.2479,-0l0.0137,0.2618l0.0137,0.2664l0.2664,0.0137l0.2618,0.0139l0,0.2474l0,0.2525l0.2525,-0l0.2527,-0l0,0.5052l0,0.5052l-0.505,-0l-0.5052,-0l0,-0.2525l0,-0.2479l-0.2618,-0.0137l-0.2664,-0.0137l-0.0137,-0.2388l-0.0137,-0.2388l-0.2388,-0.0139l-0.2388,-0.0137l-0.0137,-0.2388l-0.0137,-0.2388l-0.239,-0.0139l-0.2388,-0.0137l-0.0137,-0.2664l-0.0137,-0.2618l-0.2479,-0l-0.2525,-0l0,-0.2527l0,-0.2527l-0.2525,-0l-0.2525,-0l0,-3.054l0,-3.054l0.5052,-0l0.5052,-0l0,2.8015Z"
|
||||||
|
android:fillColor="#FFF"/>
|
||||||
|
</vector>
|
@ -1,5 +1,5 @@
|
|||||||
<vector android:height="32dp" android:viewportHeight="1000"
|
<vector android:height="24dp" android:viewportHeight="1000"
|
||||||
android:viewportWidth="1000" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:viewportWidth="1000" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="#FFF" android:pathData="M377.54,13.12c-15.63,8.11 -17.8,16.82 -18,66.87c0,41.74 1.58,50.45 10.29,59.74c8.11,8.31 18.6,10.48 52.03,10.48l26.71,-0l0,15.83l0,15.63l-7.32,1.19c-32.84,5.54 -64.49,13.85 -89.02,23.54c-6.92,2.77 -12.86,3.96 -13.65,2.97c-2.57,-4.35 -14.84,-8.31 -39.96,-12.86c-32.64,-5.74 -45.7,-5.94 -60.54,-0.79c-16.42,5.54 -21.96,9.5 -52.23,36.8c-35.61,32.25 -45.11,45.3 -50.05,67.66c-2.57,12.86 2.37,70.23 6.92,79.13c3.17,6.13 3.17,6.53 -6.53,25.52c-28.29,56.57 -41.74,114.93 -41.74,180.61c0,138.68 68.65,264.5 185.96,340.86c45.9,29.67 98.72,50.05 157.27,60.14c27.7,4.75 96.94,4.75 124.63,-0c44.71,-7.72 80.52,-19.39 118.7,-38.38c89.02,-44.51 157.87,-119.09 195.85,-211.87c18.79,-46.29 28.69,-98.13 28.69,-151.74c0,-64.89 -13.45,-123.05 -41.74,-179.63c-9.69,-18.99 -9.69,-19.39 -6.53,-25.52c2.18,-4.15 4.16,-17.41 6.13,-38.77c2.77,-31.65 2.57,-33.04 -1.19,-46.09c-2.37,-7.32 -7.52,-18.2 -11.47,-24.13c-7.52,-11.28 -58.16,-58.95 -70.63,-66.47c-11.27,-7.12 -28.69,-12.07 -41.54,-12.07c-24.73,-0 -73.2,11.08 -77.15,17.61c-0.59,0.99 -8.9,-1.19 -18.4,-4.75c-21.76,-8.11 -49.85,-15.83 -72.41,-19.78c-9.69,-1.58 -18.4,-3.36 -19.39,-4.15c-0.99,-0.59 -1.78,-7.52 -1.78,-15.63l0,-14.64l7.12,-1.39c3.96,-0.79 13.06,-0.79 20.58,-0.4c7.32,0.59 20.77,0.4 29.67,-0.4c14.64,-1.19 16.62,-1.98 22.75,-7.91c9.69,-9.5 11.28,-19.98 10.48,-67.85c-0.59,-43.92 -1.78,-48.47 -14.04,-57.57c-5.54,-4.15 -7.12,-4.15 -123.64,-4.75c-109.4,-0.41 -118.69,-0.21 -124.83,2.96ZM555.99,308.28c26.11,5.54 46.09,12.46 69.24,24.14c27.1,13.45 46.69,27.3 69.44,49.26c25.92,25.12 42.14,47.08 57.57,78.14c20.76,41.94 29.27,78.54 29.27,125.62c0,43.92 -8.7,82.1 -27.3,121.47c-17.41,36.8 -52.42,79.53 -84.87,103.47c-38.18,28.29 -85.07,47.68 -131.36,54.2c-21.56,2.97 -75.57,1.19 -95.16,-3.16c-114.54,-25.52 -200.01,-113.95 -220.98,-228.49c-4.55,-25.32 -4.55,-72.01 0,-95.95c10.88,-57.57 35.02,-105.25 74.19,-146c46.29,-48.47 104.85,-78.34 168.75,-86.45c22.76,-2.78 68.85,-1 91.21,3.75Z"/>
|
<path android:fillColor="#FFF" android:pathData="M377.54,13.12c-15.63,8.11 -17.8,16.82 -18,66.87c0,41.74 1.58,50.45 10.29,59.74c8.11,8.31 18.6,10.48 52.03,10.48l26.71,-0l0,15.83l0,15.63l-7.32,1.19c-32.84,5.54 -64.49,13.85 -89.02,23.54c-6.92,2.77 -12.86,3.96 -13.65,2.97c-2.57,-4.35 -14.84,-8.31 -39.96,-12.86c-32.64,-5.74 -45.7,-5.94 -60.54,-0.79c-16.42,5.54 -21.96,9.5 -52.23,36.8c-35.61,32.25 -45.11,45.3 -50.05,67.66c-2.57,12.86 2.37,70.23 6.92,79.13c3.17,6.13 3.17,6.53 -6.53,25.52c-28.29,56.57 -41.74,114.93 -41.74,180.61c0,138.68 68.65,264.5 185.96,340.86c45.9,29.67 98.72,50.05 157.27,60.14c27.7,4.75 96.94,4.75 124.63,-0c44.71,-7.72 80.52,-19.39 118.7,-38.38c89.02,-44.51 157.87,-119.09 195.85,-211.87c18.79,-46.29 28.69,-98.13 28.69,-151.74c0,-64.89 -13.45,-123.05 -41.74,-179.63c-9.69,-18.99 -9.69,-19.39 -6.53,-25.52c2.18,-4.15 4.16,-17.41 6.13,-38.77c2.77,-31.65 2.57,-33.04 -1.19,-46.09c-2.37,-7.32 -7.52,-18.2 -11.47,-24.13c-7.52,-11.28 -58.16,-58.95 -70.63,-66.47c-11.27,-7.12 -28.69,-12.07 -41.54,-12.07c-24.73,-0 -73.2,11.08 -77.15,17.61c-0.59,0.99 -8.9,-1.19 -18.4,-4.75c-21.76,-8.11 -49.85,-15.83 -72.41,-19.78c-9.69,-1.58 -18.4,-3.36 -19.39,-4.15c-0.99,-0.59 -1.78,-7.52 -1.78,-15.63l0,-14.64l7.12,-1.39c3.96,-0.79 13.06,-0.79 20.58,-0.4c7.32,0.59 20.77,0.4 29.67,-0.4c14.64,-1.19 16.62,-1.98 22.75,-7.91c9.69,-9.5 11.28,-19.98 10.48,-67.85c-0.59,-43.92 -1.78,-48.47 -14.04,-57.57c-5.54,-4.15 -7.12,-4.15 -123.64,-4.75c-109.4,-0.41 -118.69,-0.21 -124.83,2.96ZM555.99,308.28c26.11,5.54 46.09,12.46 69.24,24.14c27.1,13.45 46.69,27.3 69.44,49.26c25.92,25.12 42.14,47.08 57.57,78.14c20.76,41.94 29.27,78.54 29.27,125.62c0,43.92 -8.7,82.1 -27.3,121.47c-17.41,36.8 -52.42,79.53 -84.87,103.47c-38.18,28.29 -85.07,47.68 -131.36,54.2c-21.56,2.97 -75.57,1.19 -95.16,-3.16c-114.54,-25.52 -200.01,-113.95 -220.98,-228.49c-4.55,-25.32 -4.55,-72.01 0,-95.95c10.88,-57.57 35.02,-105.25 74.19,-146c46.29,-48.47 104.85,-78.34 168.75,-86.45c22.76,-2.78 68.85,-1 91.21,3.75Z"/>
|
||||||
<path android:fillColor="#FFF" android:pathData="M651.34,411.35c-3.76,1.19 -32.64,28.69 -82.5,78.54l-76.76,76.76l-53.41,-53.82c-57.17,-57.57 -57.96,-58.16 -74.19,-55.2c-7.91,1.58 -19.58,10.88 -23.94,19.19c-3.56,7.12 -3.56,20.18 0,27.1c5.14,9.5 136.11,138.48 142.24,140.06c8.51,1.98 22.35,-0.2 27.5,-4.55c2.57,-2.18 44.91,-44.51 94.37,-93.97l89.81,-90.21l-0.99,-11.87c-0.59,-9.1 -2.18,-13.65 -6.33,-18.99c-8.7,-11.46 -23.34,-16.8 -35.8,-13.04Z"/>
|
<path android:fillColor="#FFF" android:pathData="M651.34,411.35c-3.76,1.19 -32.64,28.69 -82.5,78.54l-76.76,76.76l-53.41,-53.82c-57.17,-57.57 -57.96,-58.16 -74.19,-55.2c-7.91,1.58 -19.58,10.88 -23.94,19.19c-3.56,7.12 -3.56,20.18 0,27.1c5.14,9.5 136.11,138.48 142.24,140.06c8.51,1.98 22.35,-0.2 27.5,-4.55c2.57,-2.18 44.91,-44.51 94.37,-93.97l89.81,-90.21l-0.99,-11.87c-0.59,-9.1 -2.18,-13.65 -6.33,-18.99c-8.7,-11.46 -23.34,-16.8 -35.8,-13.04Z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
@ -24,6 +24,14 @@
|
|||||||
android:background="#00FFFFFF"
|
android:background="#00FFFFFF"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<clock.socoolby.com.clock.widget.textview.DigitTextView
|
||||||
|
android:id="@+id/tv_time"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="#fff"
|
||||||
|
/>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/rel_main"
|
android:id="@+id/rel_main"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -91,10 +99,11 @@
|
|||||||
android:layout_below="@+id/tv_weather"
|
android:layout_below="@+id/tv_weather"
|
||||||
android:layout_marginLeft="100dp"
|
android:layout_marginLeft="100dp"
|
||||||
android:layout_marginTop="10dp"
|
android:layout_marginTop="10dp"
|
||||||
android:src="@drawable/ic_handup" />
|
android:src="@drawable/ic_alarm_clock" />
|
||||||
|
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/tv_hours_system"
|
android:id="@+id/tv_break"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="#00FFFFFF"
|
android:background="#00FFFFFF"
|
||||||
@ -102,8 +111,7 @@
|
|||||||
android:layout_below="@+id/tv_weather"
|
android:layout_below="@+id/tv_weather"
|
||||||
android:layout_marginLeft="25dp"
|
android:layout_marginLeft="25dp"
|
||||||
android:layout_marginTop="10dp"
|
android:layout_marginTop="10dp"
|
||||||
android:src="@drawable/ic_am"
|
android:src="@drawable/ic_handup"
|
||||||
android:visibility="gone"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
@ -111,7 +119,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="#00FFFFFF"
|
android:background="#00FFFFFF"
|
||||||
android:layout_toRightOf="@+id/tv_hours_system"
|
android:layout_toRightOf="@+id/tv_break"
|
||||||
android:layout_below="@+id/tv_weather"
|
android:layout_below="@+id/tv_weather"
|
||||||
android:layout_marginLeft="40dp"
|
android:layout_marginLeft="40dp"
|
||||||
android:layout_marginTop="10dp"
|
android:layout_marginTop="10dp"
|
||||||
@ -171,6 +179,19 @@
|
|||||||
android:textSize="26sp" />
|
android:textSize="26sp" />
|
||||||
|
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/tv_hours_system"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="#00FFFFFF"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_marginLeft="40dp"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:src="@drawable/ic_am"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -215,15 +236,6 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
<clock.socoolby.com.clock.widget.textview.DigitTextView
|
|
||||||
android:id="@+id/tv_time"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:textColor="#fff"
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
|
||||||
<clock.socoolby.com.clock.widget.animatorview.AnimatorView
|
<clock.socoolby.com.clock.widget.animatorview.AnimatorView
|
||||||
android:id="@+id/tv_foreground_animatorview"
|
android:id="@+id/tv_foreground_animatorview"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user