1
0
mirror of https://gitee.com/51danju/workclock.git synced 2025-06-07 19:34:05 +08:00

添加2字体,及更多自定义项

This commit is contained in:
wushunlian 2019-07-02 11:34:52 +08:00
parent 78e56b54ba
commit ec64ecb921
17 changed files with 524 additions and 234 deletions

View File

@ -65,15 +65,7 @@ dependencies {
// ViewModel and LiveData
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
implementation('com.gitee.51danju.e-odbo:e-odbo-jdbc:V1.0-beta.3')
{
exclude(group: 'org.apache.logging.log4j', module: '*')
//exclude(group: 'org.apache.logging.log4j', module: 'log4j-core')
//exclude(group: 'org.apache.logging.log4j', module: 'log4j-api')
//exclude(group: 'org.apache.logging.log4j', module: 'log4j-jcl')
//exclude(group: 'org.apache.logging.log4j', module: 'log4j-slf4j-impl')
//exclude(group: 'org.slf4j', module: 'slf4j-api')
}
implementation('com.gitee.51danju.e-odbo:e-odbo-jdbc:1.0-beta.13')
implementation 'org.slf4j:slf4j-android:1.7.26'
//implementation 'com.github.tony19:logback-android-core:1.0.7-1'

Binary file not shown.

Binary file not shown.

View File

@ -111,4 +111,12 @@ public class FontManager {
e.printStackTrace();
}
}
public void addCoustomFontStyle(List<TimeFontStyle> coustomFontStyleList){
this.fontStyleList.addAll(coustomFontStyleList);
}
public void addCoustomFontStyle(TimeFontStyle coustomFontStyleList){
this.fontStyleList.add(coustomFontStyleList);
}
}

View File

@ -54,7 +54,6 @@ import clock.socoolby.com.clock.protocol.WeatherResponse;
import clock.socoolby.com.clock.service.ProximityService;
import clock.socoolby.com.clock.state.ClockModeEnum;
import clock.socoolby.com.clock.state.ClockStateMachine;
import clock.socoolby.com.clock.state.ClockTimeTypeEnum;
import clock.socoolby.com.clock.model.SharePerferenceModel;
import clock.socoolby.com.clock.state.ClockInterfaceTypeEnum;
import clock.socoolby.com.clock.state.ClockThemeUITypeEnum;
@ -66,30 +65,8 @@ import clock.socoolby.com.clock.viewmodel.ThemeUIViewModel;
import clock.socoolby.com.clock.viewmodel.ViewModelFactory;
import clock.socoolby.com.clock.widget.animatorview.AnimatorView;
import clock.socoolby.com.clock.widget.animatorview.I_Animator;
import clock.socoolby.com.clock.widget.animatorview.animator.AnimatorFactory;
import clock.socoolby.com.clock.widget.animatorview.animator.BubbleAnimator;
import clock.socoolby.com.clock.widget.animatorview.animator.BubbleCollisionAnimator;
import clock.socoolby.com.clock.widget.animatorview.animator.BubbleWhirlPoolAnimator;
import clock.socoolby.com.clock.widget.animatorview.animator.CarrouselAnimator;
import clock.socoolby.com.clock.widget.animatorview.animator.DotsLineAnimator;
import clock.socoolby.com.clock.widget.animatorview.animator.FishAnimator;
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.SawtoothAnimator;
import clock.socoolby.com.clock.widget.animatorview.animator.Wave3DAnimator;
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.ClockFactory;
import clock.socoolby.com.clock.widget.animatorview.animator.textanimator.EZLedAnimator;
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.FluorescenceAnimator;
import clock.socoolby.com.clock.widget.animatorview.animator.RainAnimator;
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.StarFallAnimator;
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.WindmillAnimator;
import clock.socoolby.com.clock.widget.animatorview.animator.textanimator.EvaporateTextAnimator;
import static clock.socoolby.com.clock.state.ClockThemeUITypeEnum.FULLSCREEN;
import static clock.socoolby.com.clock.state.ClockThemeUITypeEnum.SETTING;
@ -97,6 +74,7 @@ import static clock.socoolby.com.clock.state.ClockThemeUITypeEnum.SETTING;
public class MainActivity extends AppCompatActivity implements android.view.GestureDetector.OnGestureListener, ScaleGestureDetector.OnScaleGestureListener, GestureDetector.OnDoubleTapListener {
private final static String TAG = MainActivity.class.getSimpleName();
private final static int SETTING_REQUEST_CODE = 100;
//背景动画
@ -104,7 +82,6 @@ public class MainActivity extends AppCompatActivity implements android.view.Ges
private I_Animator backGroundAnimator;
private int currectAnimatorIndex=0;
private final static int ANIMATOR_TEXTLED=80;
@ -112,7 +89,7 @@ public class MainActivity extends AppCompatActivity implements android.view.Ges
//背景图相关
private ImageView tv_background_image;
private String imagePath=null;
// 定义手势检测器实例
GestureDetector detector;
@ -126,8 +103,6 @@ public class MainActivity extends AppCompatActivity implements android.view.Ges
public WeatherResponse weatherAdape;
private ClockTimeTypeEnum showTimeType=ClockTimeTypeEnum.TIME;
private ClockStateMachine clockStateMachine;
Intent proximityServiceIntent=null;
@ -258,8 +233,6 @@ public class MainActivity extends AppCompatActivity implements android.view.Ges
//digitViewModel.getTimeFontStyle().setValue(fontManager.getCurrentFontStyle());
clockStateMachine.start();
themeUIManager=new ThemeUIManager(ClockApplication.getInstance().getEntityManager(),model);
testSetup();
@ -298,6 +271,9 @@ public class MainActivity extends AppCompatActivity implements android.view.Ges
} catch (BasicException e) {
e.printStackTrace();
}*/
fontManager.addCoustomFontStyle(new TimeFontStyle("BONX-TubeBold",110,120,130,150));
fontManager.addCoustomFontStyle(new TimeFontStyle("BONX-TubeBoldReverse",110,120,130,150));
}
@ -471,7 +447,8 @@ public class MainActivity extends AppCompatActivity implements android.view.Ges
public void onDestroy() {
//Log.i(TAG, "onDestroy....");
super.onDestroy();
clockStateMachine.onDestory();
if(clockStateMachine!=null)
clockStateMachine.onDestory();
try {
if (model.isTriggerScreen())
stopService(proximityServiceIntent);
@ -494,6 +471,7 @@ public class MainActivity extends AppCompatActivity implements android.view.Ges
wakeLock.acquire();
if(backGroundAnimator!=null)
backGroundAnimator.start();
clockStateMachine.start();
}
@Override
@ -504,6 +482,7 @@ public class MainActivity extends AppCompatActivity implements android.view.Ges
wakeLock.release();
if(backGroundAnimator!=null)
backGroundAnimator.stop();
clockStateMachine.stop();
}
public void configBackGroundImage(){

View File

@ -80,9 +80,10 @@ public class WorkClockDatabase extends DataBase {
.value("谁能许我扶桑花期", 110, 120, 130, 150)
.value("造字工房凌黑", 110, 120, 130, 150)
.value("中国龙新草体", 110, 120, 130, 150)
.value("迷你简剪纸_0",110,120,130,150);
.value("迷你简剪纸_0",110,120,130,150)
.value("BONX-TubeBold",110,120,130,150)
.value("BONX-TubeBoldReverse",110,120,130,150)
;
addData(fontStyleInitData);
}
}

View File

@ -93,9 +93,6 @@ public abstract class AbstractThemeUIFragment extends Fragment implements View.O
private Timer timer=null;
private ClockStateMachine clockStateMachine;
public AbstractThemeUIFragment(int layoutId){
this.layoutId=layoutId;
}
@ -110,7 +107,6 @@ public abstract class AbstractThemeUIFragment extends Fragment implements View.O
this.alterViewModel=ViewModelProviders.of(getActivity(), new ViewModelFactory(ClockApplication.getInstance().getModel())).get(AlterViewModel.class);
this.mainActivity = (MainActivity)getActivity();
this.model = ClockApplication.getInstance().getModel();
this.clockStateMachine=mainActivity.getClockStateMachine();
}
@Override
@ -168,7 +164,7 @@ public abstract class AbstractThemeUIFragment extends Fragment implements View.O
tv_break.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
clockStateMachine.handUpCountingDownCheck();
mainActivity.getClockStateMachine().handUpCountingDownCheck();
return true;
}
});
@ -341,8 +337,8 @@ public abstract class AbstractThemeUIFragment extends Fragment implements View.O
}else{
tv_handup.setColorFilter(R.color.colorPrimaryDark);
tv_hand_time.setVisibility(View.GONE);
if(clockStateMachine.getCurrentShowTimeType()== ClockTimeTypeEnum.COUNTING_DOWN)
clockStateMachine.setCurrentShowTimeType(ClockTimeTypeEnum.TIME);
if(mainActivity.getClockStateMachine().getCurrentShowTimeType()== ClockTimeTypeEnum.COUNTING_DOWN)
mainActivity.getClockStateMachine().setCurrentShowTimeType(ClockTimeTypeEnum.TIME);
}
}
});
@ -520,7 +516,7 @@ public abstract class AbstractThemeUIFragment extends Fragment implements View.O
globalViewModel.setSrceenLock(!globalViewModel.getSrceenLock().getValue());
break;
case R.id.tv_break:
clockStateMachine.countingCheck();
mainActivity.getClockStateMachine().countingCheck();
break;
case R.id.tv_descript:
setDiscript(SettingActivity.roundAutoQuotes());

View File

@ -13,12 +13,13 @@ import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;
import com.openbravo.data.basic.BasicException;
import java.util.Random;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
@ -46,6 +47,7 @@ public class DigitClockConfigFragment extends Fragment {
ThemeUIManager themeUIManager;
@BindView(R.id.tv_hourSystem12)
RadioButton tvHourSystem12;
@BindView(R.id.tv_hourSystem24)
@ -114,6 +116,14 @@ public class DigitClockConfigFragment extends Fragment {
RadioButton tvTextAnimTabDigitUp;
@BindView(R.id.tv_theme_config_recover)
Button tvThemeConfigRecover;
@BindView(R.id.button_round)
Button buttonRound;
@BindView(R.id.tv_SecondSubscript)
CheckBox tvSecondSubscript;
@BindView(R.id.tv_textStyle_border)
CheckBox tvTextStyleBorder;
@BindView(R.id.tv_textStyle_border_color)
Button tvTextStyleBorderColor;
public DigitClockConfigFragment(ThemeUIManager themeUIManager) {
this.themeUIManager = themeUIManager;
@ -233,6 +243,17 @@ public class DigitClockConfigFragment extends Fragment {
changeGradientColor(button8, 4);
});
buttonRound.setOnClickListener(view1 -> {
for (int i = 0; i < confColors.length; i++)
confColors[i] = roundColor();
digitViewModel.setTimeLinearGradientColorsArray(confColors);
button4.setBackgroundColor(confColors[0]);
button5.setBackgroundColor(confColors[1]);
button6.setBackgroundColor(confColors[2]);
button7.setBackgroundColor(confColors[3]);
button8.setBackgroundColor(confColors[4]);
});
tvThemeUIStyle1.setOnClickListener(v -> changeThemeUIStyle(1));
tvThemeUIStyle2.setOnClickListener(v -> changeThemeUIStyle(2));
@ -258,6 +279,33 @@ public class DigitClockConfigFragment extends Fragment {
}
});
tvSecondSubscript.setOnCheckedChangeListener((group, checkedId) -> {
digitViewModel.setSecondSubscript(tvSecondSubscript.isChecked());
});
tvTextStyleBorder.setOnCheckedChangeListener((group, checkedId) -> {
digitViewModel.setCharBackgroundBorder(tvTextStyleBorder.isChecked());
tvTextStyleBorderColor.setClickable(tvTextStyleBorder.isChecked());
});
tvTextStyleBorderColor.setOnClickListener(v->{
if (colorPickerDialog == null)
colorPickerDialog = new ColorPickerPop(getActivity());
colorPickerDialog.setOnColorChangeListenter(new ColorPickerPop.OnColorListener() {
@Override
public void onEnsure(int color) {
digitViewModel.setCharBackgroundBorderColor(color);
tvTextStyleBorderColor.setBackgroundColor(color);
}
@Override
public void onBack() {
}
});
colorPickerDialog.show(digitViewModel.getCharBackgroundBorderColor().getValue());
});
return view;
}
@ -268,8 +316,8 @@ public class DigitClockConfigFragment extends Fragment {
themeUIManager.loadDigitThemeFromDB(styleName);
reloadViewModel();
} else {
DialogUtils.show(getActivity(),"温馨提示","当前主题还未设置,是否以当前主题保存.",ok->{
if(ok)
DialogUtils.show(getActivity(), "温馨提示", "当前主题还未设置,是否以当前主题保存.", ok -> {
if (ok)
configThemeUIStyle(order);
});
Toast.makeText(getActivity(), "你可长按来保存一个主题", Toast.LENGTH_SHORT).show();
@ -314,6 +362,7 @@ public class DigitClockConfigFragment extends Fragment {
digitViewModel.loadFromModel();
loadForViewModel();
}
/**
* onDestroyView中进行解绑操作
*/
@ -393,9 +442,16 @@ public class DigitClockConfigFragment extends Fragment {
button6.setClickable(able);
button7.setClickable(able);
button8.setClickable(able);
buttonRound.setClickable(able);
});
setTextColor(globalViewModel.getForegroundColor().getValue());
tvSecondSubscript.setChecked(digitViewModel.getSecondSubscript().getValue());
tvTextStyleBorder.setChecked(digitViewModel.getCharBackgroundBorder().getValue());
tvTextStyleBorderColor.setBackgroundColor(digitViewModel.getCharBackgroundBorderColor().getValue());
tvTextStyleBorderColor.setClickable(digitViewModel.getCharBackgroundBorder().getValue());
}
private void setTextColor(int color) {
@ -404,6 +460,7 @@ public class DigitClockConfigFragment extends Fragment {
tvHourSystem24.setTextColor(color);
tvSecoundShow.setTextColor(color);
tvSecondSubscript.setTextColor(color);
textView3.setTextColor(color);
@ -428,10 +485,24 @@ public class DigitClockConfigFragment extends Fragment {
button6.setTextColor(color);
button7.setTextColor(color);
button8.setTextColor(color);
buttonRound.setTextColor(color);
tvThemeUIStyle1.setTextColor(color);
tvThemeUIStyle2.setTextColor(color);
tvThemeUIStyle3.setTextColor(color);
tvThemeUIStyle4.setTextColor(color);
tvTextStyleBorder.setTextColor(color);
tvTextStyleBorderColor.setTextColor(color);
}
static Random rand = new Random();
public static int roundColor() {
int alpha = 200;
int r = rand.nextInt(255);
int g = rand.nextInt(255);
int b = rand.nextInt(255);
return alpha << 24 | r << 16 | g << 8 | b;
}
}

View File

@ -131,6 +131,12 @@ public class DigitClockFragment extends Fragment {
tv_time.setTextColor(integer);
}
});
digitViewModel.getSecondSubscript().observe(this,isSubscript->tv_time.setSecondSubscript(isSubscript));
digitViewModel.getCharBackgroundBorder().observe(this,able->tv_time.setCharBackgroundBorder(able));
digitViewModel.getCharBackgroundBorderColor().observe(this,color->tv_time.setCharBackgroundBorderColor(color));
}
private void updateBaseLine(boolean isFullScreen){

View File

@ -136,10 +136,21 @@ public class DateModel implements Serializable {
return String.format("%02d:%02d", hour, minute);
}
public String getTimeString(boolean heartbeat,boolean isHourSystem12) {
if(isHourSystem12&&hour>12)
if(heartbeat)
return String.format("%02d:%02d %02d", hour-12, minute, second);
else
return String.format("%02d:%02d:%02d", hour-12, minute, second);
if(heartbeat)
return String.format("%02d:%02d %02d", hour, minute, second);
return String.format("%02d:%02d:%02d", hour, minute, second);
}
public String getTimeString(boolean isHourSystem12) {
if(isHourSystem12&&hour>12)
return String.format("%02d:%02d %02d", hour-12, minute, second);
return String.format("%02d:%02d %02d", hour, minute, second);
return String.format("%02d:%02d:%02d", hour-12, minute, second);
return String.format("%02d:%02d:%02d", hour, minute, second);
}
public static String getNowWithTime() {

View File

@ -1,5 +1,7 @@
package clock.socoolby.com.clock.model;
import android.graphics.Color;
import org.json.JSONException;
import org.json.JSONObject;
@ -25,6 +27,15 @@ public class DigitPerferenceModel {
protected final static String KEY_IS_DISPLAY_SECOND = "key_is_display_second";
protected boolean displaySecond = true;
protected final static String KEY_IS_DISPLAY_SECOND_SUBSCRIPT = "key_is_display_second_subscript";
protected boolean timeTextSecondSubscript = true;
protected final static String KEY_IS_CHAR_BACKGROUND_BORDER = "key_is_char_background_border";
protected boolean charBackgroundBorder = false;
protected final static String KEY_IS_CHAR_BACKGROUND_BORDER_COLOR = "key_is_char_background_border_color";
protected Integer charBackgroundBorderColor=0;
public void fromJsonString(JSONObject jsonObject) throws JSONException {
linearGradientAble=jsonObject.optBoolean(KEY_IS_LINEARGRADIENT_ABLE,false);
timeColorsArray=stringToIntegerArray(jsonObject.optString(KEY_FOREGROUND_TIME_COLORS_ARRAY,null));
@ -32,7 +43,10 @@ public class DigitPerferenceModel {
shadowType=jsonObject.optInt(KEY_TIME_TEXT_SHADOW_TYPE,0);
timeTextCharAnimatorType=jsonObject.optInt(KEY_TIME_TEXT_CHAR_ANIMATOR_TYPE,0);
fontName=jsonObject.optString(KEY_FONT_NAME,"default");
displaySecond = jsonObject.getBoolean(KEY_IS_DISPLAY_SECOND);
displaySecond = jsonObject.optBoolean(KEY_IS_DISPLAY_SECOND,false);
timeTextSecondSubscript=jsonObject.optBoolean(KEY_IS_DISPLAY_SECOND_SUBSCRIPT,true);
charBackgroundBorder=jsonObject.optBoolean(KEY_IS_CHAR_BACKGROUND_BORDER,false);
charBackgroundBorderColor=jsonObject.optInt(KEY_IS_CHAR_BACKGROUND_BORDER_COLOR, Color.BLACK);
}
@ -44,6 +58,9 @@ public class DigitPerferenceModel {
jsonObject.put(KEY_TIME_TEXT_CHAR_ANIMATOR_TYPE,timeTextCharAnimatorType);
jsonObject.put(KEY_FONT_NAME,fontName);
jsonObject.put(KEY_IS_DISPLAY_SECOND, displaySecond);
jsonObject.put(KEY_IS_DISPLAY_SECOND_SUBSCRIPT,timeTextSecondSubscript);
jsonObject.put(KEY_IS_CHAR_BACKGROUND_BORDER,charBackgroundBorder);
jsonObject.put(KEY_IS_CHAR_BACKGROUND_BORDER_COLOR,charBackgroundBorderColor);
}
public static String integerArrayToString(Integer[] fromArrays){
@ -124,4 +141,28 @@ public class DigitPerferenceModel {
public void setFontName(String fontName) {
this.fontName = fontName;
}
public boolean isTimeTextSecondSubscript() {
return timeTextSecondSubscript;
}
public void setTimeTextSecondSubscript(boolean timeTextSecondSubscript) {
this.timeTextSecondSubscript = timeTextSecondSubscript;
}
public boolean isCharBackgroundBorder() {
return charBackgroundBorder;
}
public void setCharBackgroundBorder(boolean charBackgroundBorder) {
this.charBackgroundBorder = charBackgroundBorder;
}
public Integer getCharBackgroundBorderColor() {
return charBackgroundBorderColor;
}
public void setCharBackgroundBorderColor(Integer charBackgroundBorderColor) {
this.charBackgroundBorderColor = charBackgroundBorderColor;
}
}

View File

@ -689,4 +689,32 @@ public class SharePerferenceModel implements Serializable {
this.simulatePerferenceModel = simulatePerferenceModel;
dirtySave();
}
public void setTimeTextSecondSubscript(Boolean secondSubscript) {
digitPerferenceModel.setTimeTextSecondSubscript(secondSubscript);
dirtySave();
}
public boolean isTimeTextSecondSubscript(){
return digitPerferenceModel.isTimeTextSecondSubscript();
}
public boolean isCharBackgroundBorder() {
return digitPerferenceModel.isCharBackgroundBorder();
}
public void setCharBackgroundBorder(boolean charBackgroundBorder) {
digitPerferenceModel.setCharBackgroundBorder(charBackgroundBorder);
dirtySave();
}
public Integer getCharBackgroundBorderColor() {
return digitPerferenceModel.getCharBackgroundBorderColor();
}
public void setCharBackgroundBorderColor(Integer charBackgroundBorderColor) {
digitPerferenceModel.setCharBackgroundBorderColor(charBackgroundBorderColor);
dirtySave();
}
}

View File

@ -58,12 +58,12 @@ public class ClockStateMachine implements Handler.Callback{
this.alterManager = alterManager;
this.alterViewModel=alterViewModel;
this.themeUIViewModel=themeUIViewModel;
LunarCalendarManager.init(ClockApplication.getContext());
model=ClockApplication.getInstance().getModel();
}
public void start(){
LunarCalendarManager.init(ClockApplication.getContext());
model=ClockApplication.getInstance().getModel();
//Log.d(TAG,"create timer and timerTask.................................");
timer = new Timer();
handler = new Handler(this);
@ -79,6 +79,15 @@ public class ClockStateMachine implements Handler.Callback{
timer.schedule(timerTask, 1000, 1000);
}
public void stop(){
if(timer!=null) {
timerTask.cancel();
timer.cancel();
timer=null;
}
}
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
@ -226,7 +235,8 @@ public class ClockStateMachine implements Handler.Callback{
}
public void onDestory() {
timer.cancel();
if(timer!=null)
timer.cancel();
}
//handUp

View File

@ -32,6 +32,12 @@ public class DigitViewModel extends ViewModel {
private MutableLiveData<String> timeFontName =new MutableLiveData<>();
private MutableLiveData<Boolean> secondSubscript=new MutableLiveData<>();//缩小
private MutableLiveData<Boolean> charBackgroundBorder=new MutableLiveData<>();
private MutableLiveData<Integer> charBackgroundBorderColor=new MutableLiveData<>();
SharePerferenceModel model;
public DigitViewModel(SharePerferenceModel model) {
@ -49,6 +55,9 @@ public class DigitViewModel extends ViewModel {
baseLineDown.setValue(0);
timeFontStyleSize.setValue(100);
timeFontName.setValue(model.getFontName());
secondSubscript.setValue(model.isTimeTextSecondSubscript());
charBackgroundBorder.setValue(model.isCharBackgroundBorder());
charBackgroundBorderColor.setValue(model.getCharBackgroundBorderColor());
}
public MutableLiveData<Boolean> getDisplaySecond() {
@ -143,4 +152,30 @@ public class DigitViewModel extends ViewModel {
return timeFontName;
}
public MutableLiveData<Boolean> getSecondSubscript() {
return secondSubscript;
}
public void setSecondSubscript(Boolean secondSubscript) {
this.secondSubscript.setValue(secondSubscript);
model.setTimeTextSecondSubscript(secondSubscript);
}
public MutableLiveData<Boolean> getCharBackgroundBorder() {
return charBackgroundBorder;
}
public void setCharBackgroundBorder(Boolean charBackgroundBorder) {
this.charBackgroundBorder.setValue(charBackgroundBorder);
model.setCharBackgroundBorder(charBackgroundBorder);
}
public MutableLiveData<Integer> getCharBackgroundBorderColor() {
return charBackgroundBorderColor;
}
public void setCharBackgroundBorderColor(Integer charBackgroundBorderColor) {
this.charBackgroundBorderColor.setValue(charBackgroundBorderColor);
model.setCharBackgroundBorderColor(charBackgroundBorderColor);
}
}

View File

@ -0,0 +1,6 @@
package clock.socoolby.com.clock.widget.animatorview.animator;
public class SnakeAnimator {
}

View File

@ -8,12 +8,14 @@ import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import androidx.annotation.Nullable;
import java.util.Date;
import java.util.HashMap;
import java.util.Random;
@ -25,20 +27,64 @@ import clock.socoolby.com.clock.widget.textview.charanimator.TabDigitCharAnimato
import clock.socoolby.com.clock.widget.textview.charanimator.Up2DownCharAnimator;
public class DigitTextView extends androidx.appcompat.widget.AppCompatTextView {
public static final String Tag=DigitTextView.class.getSimpleName();
public static final String Tag = DigitTextView.class.getSimpleName();
float baseLineDown=0;
float baseLineDown = 0;
private LinearGradient mLinearGradient;
private boolean isLinearGradientAble=false;
private boolean isLinearGradientAble = false;
private ShadowTypeEnum shadowType=ShadowTypeEnum.NOSETUP;//0:不设置1阴影2:浮雕
private ShadowTypeEnum shadowType = ShadowTypeEnum.NOSETUP;//0:不设置1阴影2:浮雕
private int[] linearGradientColors=new int[]{roundColor(), roundColor(), roundColor(), roundColor(), roundColor()};
private int[] linearGradientColors;
private CharSequence preString = "";
private CharSequence preString=null;
private boolean secondSubscript = false;
private boolean charBackgroundBorder = false;
private int charBackgroundBorderColor = Color.BLACK;
private int textWidth = 0;
private int textHight;
private int textfontHight;
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;
AbstractCharAnimator charAnimator;
float startX, startY;
Paint smallCharPaint = null;
Paint mTextPaint;
float fontScale;
String charStr;
float centerY;
CharSequence textToDraw;
Paint.FontMetricsInt fm;
int padding = 2;
int charWidth;
Paint mDividerPaint, mBackgroundPaint;
boolean layoutReflushAble=true;
public DigitTextView(Context context) {
super(context);
@ -55,9 +101,8 @@ public class DigitTextView extends androidx.appcompat.widget.AppCompatTextView {
init();
}
private void init(){
/*mDividerPaint = new Paint();
private void init() {
mDividerPaint = new Paint();
mDividerPaint.setAntiAlias(true);
mDividerPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mDividerPaint.setColor(Color.WHITE);
@ -65,73 +110,62 @@ public class DigitTextView extends androidx.appcompat.widget.AppCompatTextView {
mBackgroundPaint = new Paint();
mBackgroundPaint.setAntiAlias(true);
mBackgroundPaint.setColor(Color.BLACK);*/
}
public void setBaseLineDown(float baseLineDown) {
this.baseLineDown = baseLineDown;
layoutReflushAble=true;
}
float[] pos = {0.1f,0.3f,0.5f,0.7f,0.9f};
float[] pos = {0.1f, 0.3f, 0.5f, 0.7f, 0.9f};
boolean isLinearGradientPosAble=false;
boolean isLinearGradientPosAble = false;
boolean isReflectedAble=false;
boolean isReflectedAble = false;
boolean linearGradientReCreate=false;
boolean linearGradientReCreate = false;
public void setLinearGradientRandom(boolean able){
if(able){
linearGradientColors= new int[]{roundColor(), roundColor(), roundColor(), roundColor(), roundColor()};
isLinearGradientPosAble=rand.nextBoolean();
isReflectedAble=rand.nextBoolean();
}
setLinearGradientAble(able);
setShadowType(ShadowTypeEnum.valueOf(rand.nextInt(3)));
public void setLinearGradientAble(boolean able) {
isLinearGradientAble = able;
linearGradientReCreate = true;
}
public void setLinearGradientAble(boolean able){
isLinearGradientAble=able;
linearGradientReCreate=true;
public void setLinearGradient(int[] colors) {
this.linearGradientColors = colors;
linearGradientReCreate = true;
}
public void setLinearGradient(int[] colors){
this.linearGradientColors=colors;
linearGradientReCreate=true;
}
private void checkReCreate(){
private void linearGradientReflush() {
mLinearGradient = null;
if(isLinearGradientAble&&linearGradientColors!=null) {
if (isLinearGradientAble && linearGradientColors != null) {
mLinearGradient = new LinearGradient(0, 0, getWidth(), getHeight(), linearGradientColors, pos, Shader.TileMode.CLAMP);
}
getPaint().setShader(mLinearGradient);
linearGradientReCreate=false;
linearGradientReCreate = false;
}
public void setShadowType(ShadowTypeEnum shadowType){
this.shadowType=shadowType;
switch (shadowType){
public void setShadowType(ShadowTypeEnum shadowType) {
this.shadowType = shadowType;
switch (shadowType) {
case SHADOW://阴影效果
setShadowLayer(4, 10, 10, Color.BLACK);
break;
case RELIEF:
//setShadowLayer(1, 0.5f, 0.5f, Color.argb(200,204,204,204));//浮雕效果
setShadowLayer(12, 0, 1,Color.parseColor("#CC2b88f6"));//边缘模糊
setShadowLayer(12, 0, 1, Color.parseColor("#CC2b88f6"));//边缘模糊
break;
default:
setShadowLayer(0,0,0,getPaint().getColor());
setShadowLayer(0, 0, 0, getPaint().getColor());
}
}
public ShadowTypeEnum getShadowType(){
public ShadowTypeEnum getShadowType() {
return shadowType;
}
public boolean isLinearGradientAble(){
public boolean isLinearGradientAble() {
return isLinearGradientAble;
}
@ -167,154 +201,180 @@ public class DigitTextView extends androidx.appcompat.widget.AppCompatTextView {
isReflectedAble = reflectedAble;
}
private int textWidth=0;
private int textHight;
private int textfontHight;
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<>();
public boolean isSecondSubscript() {
return secondSubscript;
}
private CharAnimatorEnum currentCharAnimatorType= CharAnimatorEnum.Marquee3D_Up;
public void setSecondSubscript(boolean secondSubscript) {
this.secondSubscript = secondSubscript;
layoutReflushAble=true;
}
AbstractCharAnimator charAnimator;
@Override
public void setTextSize(float size) {
super.setTextSize(size);
layoutReflushAble=true;
}
float startX,startY;
@Override
public void setTypeface(@Nullable Typeface tf, int style) {
super.setTypeface(tf, style);
layoutReflushAble=true;
}
Paint smallCharPaint=null;
private void layoutReflush(CharSequence textToDraw){
fm = mTextPaint.getFontMetricsInt();
Paint mTextPaint;
baseCharWidth = getCharWidth("8", mTextPaint);
padding = baseCharWidth / 20;
//baseCharWidth+=padding;
float fontScale;
flagCharwidth = getCharWidth(":", mTextPaint);
textfontHight = (int) getFontHeight(mTextPaint);
textHight = -fm.descent - fm.ascent;
String charStr;
smallTextHight = textHight;
smallCharWidth = baseCharWidth;
float centerY;
textLength = textToDraw.length();
textSmallSpan = 0;
CharSequence textToDraw;
if (textLength > 4) {
textWidth = (baseCharWidth + padding) * 4 + flagCharwidth;
}
Paint.FontMetricsInt fm;
if (textLength > 7) {
if (secondSubscript) {
fontScale = getResources().getDisplayMetrics().scaledDensity;
smallCharPaint = getCustomTextPaint(mTextPaint, mTextPaint.getTextSize() / fontScale * 4 / 5);
smallCharWidth = getCharWidth("8", smallCharPaint);
fm = smallCharPaint.getFontMetricsInt();
smallTextHight = -fm.descent - fm.ascent;
} else
textSmallSpan = textSmallSpan + flagCharwidth;
textSmallSpan = textSmallSpan + smallCharWidth * 2;
}
layoutReflushAble=false;
}
private boolean layoutReflushCheck(CharSequence textToDraw){
if(layoutReflushAble||textToDraw.length()!=preString.length())
return true;
return false;
}
int padding=2;
protected void onDraw(Canvas canvas) {
mTextPaint=getPaint();
//long before=System.currentTimeMillis();
mTextPaint = getPaint();
mTextPaint.setColor(getCurrentTextColor());
textToDraw=getText();
textToDraw = getText();
fm=mTextPaint.getFontMetricsInt();
if(layoutReflushCheck(textToDraw))
layoutReflush(textToDraw);
baseCharWidth= getCharWidth("8",mTextPaint);
padding=baseCharWidth/20;
//baseCharWidth+=padding;
startX = (getWidth() - textWidth - textSmallSpan) / 2;
startY = (getHeight() + textHight) / 2;
flagCharwidth=getCharWidth(":",mTextPaint);
textfontHight=(int)getFontHeight(mTextPaint);
textHight=-fm.descent - fm.ascent;
if (linearGradientReCreate)
linearGradientReflush();
smallTextHight=0;
smallCharWidth=0;
textLength=textToDraw.length();
textSmallSpan=0;
if(textLength>4){
textWidth=(baseCharWidth+padding)*4+flagCharwidth;
}
if(textLength>7){
fontScale = getResources().getDisplayMetrics().scaledDensity;
smallCharPaint = getCustomTextPaint(mTextPaint,mTextPaint.getTextSize()/fontScale*4/5);
smallCharWidth=getCharWidth("8",smallCharPaint);
fm=smallCharPaint.getFontMetricsInt();
smallTextHight=-fm.descent - fm.ascent;
textSmallSpan=smallCharWidth*2;
}
startX=(getWidth()-textWidth-textSmallSpan)/2;
startY=(getHeight()+textHight)/2;
if(linearGradientReCreate)
checkReCreate();
for(int i=0;i<textLength;i++){
charStr =String.valueOf(textToDraw.charAt(i));
if(i<5){
if(i==2){
canvas.drawText(charStr, startX, startY+baseLineDown, mTextPaint);
startX+=flagCharwidth;
}else{
int charWidth= getCharWidth(charStr,mTextPaint);
//Log.d(Tag,"view width:"+getWidth()+"\t heitht:"+getHeight()+"\t startx:"+startX+"\t startY:"+startY+"\t baseCharWidth:"+baseCharWidth+"\t text hight:"+textHight+"\t text font hight:"+textfontHight);
//drawBackground(canvas,startX , startY + baseLineDown-textfontHight+(textfontHight-textHight)/4,baseCharWidth,textfontHight,mBackgroundPaint);
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)), charStr, 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, charStr, startX + (baseCharWidth - charWidth) / 2, startY + baseLineDown, mTextPaint);
//drawDivider(canvas, startX, startY + baseLineDown - textfontHight + (textfontHight - textHight) / 4, baseCharWidth, textfontHight, mDividerPaint);
}
}else {
drawChar(canvas, charStr, startX + (baseCharWidth - charWidth) / 2, startY + baseLineDown, mTextPaint);
//drawDivider(canvas, startX, startY + baseLineDown - textfontHight +(textfontHight - textHight) / 4, baseCharWidth, textfontHight, mDividerPaint);
}
startX=startX+baseCharWidth+padding;
for (int i = 0; i < textLength; i++) {
charStr = String.valueOf(textToDraw.charAt(i));
if (i < 5) {
if (i == 2) {
canvas.drawText(charStr, startX, startY + baseLineDown, mTextPaint);
startX += flagCharwidth;
} else {
drawCharWithAnaimatorCheck(canvas, i, charStr, startX, startY, mTextPaint);
startX = startX + baseCharWidth + padding;
}
} else if (i == 5) {
if (secondSubscript)
startX += smallCharWidth / 2;
else {
canvas.drawText(charStr, startX, startY + baseLineDown, mTextPaint);
startX += flagCharwidth;
}
}else if(i==5) {
startX+=smallCharWidth/2;
} else {
centerY=(getHeight()+smallTextHight)/2;
centerY=centerY+(startY-centerY)/2+smallCharPaint.getFontMetrics().descent;
drawChar(canvas, charStr, startX, centerY+baseLineDown, smallCharPaint);
startX+=smallCharWidth;
//Log.d(Tag,"view hight:"+getHeight()+"\t startY:"+startY+"\t text hight:"+textHight+"small text hight:"+smallTextHight);
}
if (secondSubscript) {
centerY = (getHeight() + smallTextHight) / 2;
centerY = centerY + (startY - centerY) / 2 + smallCharPaint.getFontMetrics().descent;
if (charBackgroundBorder)
drawBackground(canvas, startX, startY + baseLineDown - smallTextHight, smallCharWidth, smallTextHight, mBackgroundPaint);
drawChar(canvas, charStr, startX, centerY + baseLineDown, smallCharPaint);
} else {
drawCharWithAnaimatorCheck(canvas, i, charStr, startX, startY, mTextPaint);
startX += padding;
}
startX += smallCharWidth;
//Log.d(Tag,"view hight:"+getHeight()+"\t startY:"+startY+"\t text hight:"+textHight+"small text hight:"+smallTextHight);
}
}
preString=textToDraw;
preString = textToDraw;
//Log.d(Tag,"total draw time:"+(System.currentTimeMillis()-before));
}
Paint mDividerPaint,mBackgroundPaint;
private void drawBackground(Canvas canvas,float startX,float startY,int width,int height,Paint mBackgroundPaint) {
canvas.drawRoundRect(new RectF(startX,startY,startX+width,startY+height), 10, 10, mBackgroundPaint);
private void drawBackground(Canvas canvas, float startX, float startY, int width, int height, Paint mBackgroundPaint) {
mBackgroundPaint.setColor(charBackgroundBorderColor);
canvas.drawRoundRect(new RectF(startX, startY, startX + width, startY + height), 10, 10, mBackgroundPaint);
}
private void drawDivider(Canvas canvas,float startX,float startY,int width,int height,Paint mDividerPaint) {
canvas.drawLine(startX, startY+height/2, startX+width, startY+height/2, mDividerPaint);
private void drawDivider(Canvas canvas, float startX, float startY, int width, int height, Paint mDividerPaint) {
//canvas.drawLine(startX, startY+height/2, startX+width, startY+height/2, mDividerPaint);
}
private void drawChar(Canvas canvas,String c,float startX,float startY,Paint mTextPaint){
if(isReflectedAble)
drawCharReflected(canvas,c, startX, startY, mTextPaint);
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 drawCharWithAnaimatorCheck(Canvas canvas, int i, String charStr, float startX, float startY, Paint mTextPaint) {
charWidth = getCharWidth(charStr, mTextPaint);
//Log.d(Tag,"view width:"+getWidth()+"\t heitht:"+getHeight()+"\t startx:"+startX+"\t startY:"+startY+"\t baseCharWidth:"+baseCharWidth+"\t text hight:"+textHight+"\t text font hight:"+textfontHight);
if (charBackgroundBorder)
drawBackground(canvas, startX, startY + baseLineDown - textfontHight + (textfontHight - textHight) / 4, baseCharWidth, textfontHight, mBackgroundPaint);
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)), charStr, 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, charStr, startX + (baseCharWidth - charWidth) / 2, startY + baseLineDown, mTextPaint);
if (charBackgroundBorder)
drawDivider(canvas, startX, startY + baseLineDown - textfontHight + (textfontHight - textHight) / 4, baseCharWidth, textfontHight, mDividerPaint);
}
} else {
drawChar(canvas, charStr, startX + (baseCharWidth - charWidth) / 2, startY + baseLineDown, mTextPaint);
if (charBackgroundBorder)
drawDivider(canvas, startX, startY + baseLineDown - textfontHight + (textfontHight - textHight) / 4, baseCharWidth, textfontHight, mDividerPaint);
}
}
Paint reflectedPaint;
Matrix matrix;
LinearGradient reflectedShader;
private void drawCharReflected(Canvas canvas,String c,float startX,float startY,Paint mTextPaint){
private void drawCharReflected(Canvas canvas, String c, float startX, float startY, Paint mTextPaint) {
canvas.save();
reflectedPaint = new Paint(mTextPaint);
reflectedShader = new LinearGradient(startX,
-startY, startX,
-startY-textHight*6/5,
-startY - textHight * 6 / 5,
Color.BLACK, 0x00ffffff, Shader.TileMode.MIRROR);// 创建线性渐变LinearGradient对象
matrix = new Matrix();
matrix.preScale(1, -1); // 实现图片的反转
@ -325,36 +385,37 @@ public class DigitTextView extends androidx.appcompat.widget.AppCompatTextView {
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;
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);
charAnimator = new Marquee3DCharAnimator(preString, currentString, Marquee3DCharAnimator.U2D);
break;
case TabDigit:
charAnimator=new TabDigitCharAnimator(preString,currentString,true);
charAnimator = new TabDigitCharAnimator(preString, currentString, true);
break;
}
return charAnimator;
}
return charAnimator;
}
private static TextPaint getCustomTextPaint(Paint srcPaint,float fontSizeSp) {
private static TextPaint getCustomTextPaint(Paint srcPaint, float fontSizeSp) {
TextPaint paint = new TextPaint(srcPaint);
paint.setTextSize(fontSizeSp); //设定字体大小, sp转换为px
return paint;
}
static Random rand=new Random();
public static int roundColor(){
static Random rand = new Random();
public static int roundColor() {
int alpha = 200;
int r = rand.nextInt(255);
int g = rand.nextInt(255);
@ -362,13 +423,28 @@ public class DigitTextView extends androidx.appcompat.widget.AppCompatTextView {
return alpha << 24 | r << 16 | g << 8 | b;
}
public static int getCharWidth(String str, Paint paint){
return (int)paint.measureText(str);
public static int getCharWidth(String str, Paint paint) {
return (int) paint.measureText(str);
}
public float getFontHeight(Paint paint) {
Paint.FontMetrics fm = paint.getFontMetrics();
return ((int) Math.ceil(fm.descent - fm.top) + 2) ;
return ((int) Math.ceil(fm.descent - fm.top) + 2);
}
public boolean isCharBackgroundBorder() {
return charBackgroundBorder;
}
public void setCharBackgroundBorder(boolean charBackgroundBorder) {
this.charBackgroundBorder = charBackgroundBorder;
}
public int getCharBackgroundBorderColor() {
return charBackgroundBorderColor;
}
public void setCharBackgroundBorderColor(int charBackgroundBorderColor) {
this.charBackgroundBorderColor = charBackgroundBorderColor;
}
}

View File

@ -50,9 +50,16 @@
android:id="@+id/tv_secoundShow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:layout_weight="1"
android:text="秒显" />
<CheckBox
android:id="@+id/tv_SecondSubscript"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="下标秒" />
<Button
android:id="@+id/tv_theme_config_recover"
android:layout_width="wrap_content"
@ -74,7 +81,8 @@
android:id="@+id/tv_textStyle_group"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_weight="5"
android:gravity="center"
android:orientation="horizontal">
<TextView
@ -114,6 +122,20 @@
android:layout_weight="1"
android:text="倒影" />
<CheckBox
android:id="@+id/tv_textStyle_border"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="底框" />
<Button
android:id="@+id/tv_textStyle_border_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="底框色" />
</LinearLayout>
<LinearLayout
@ -237,8 +259,16 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="尾" />
<Button
android:id="@+id/button_round"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="随机" />
</LinearLayout>
<LinearLayout