Android/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/EleTimer.java

167 lines
5.1 KiB
Java
Raw Normal View History

2023-11-09 08:37:59 +08:00
package com.xixun.xixunplayer;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.view.Choreographer;
import android.view.View;
import android.widget.ImageView;
import java.util.ArrayList;
import java.util.HashMap;
import gnph.util.Dates;
import gnph.util.JSList;
import gnph.util.JSMap;
import gnph.util.NumFmts;
public class EleTimer extends View implements Choreographer.FrameCallback {
HashMap<String, Bitmap> imgMap = new HashMap<>();
ArrayList<Bitmap> imgs = new ArrayList<>();
Bitmap text, day, hour, min, sec;
int spaceWidth, len;
Paint paint = new Paint();
long targetTime;
boolean isDown;
boolean isMultiline;
boolean hasDay;
boolean hasHour;
boolean hasMin;
boolean hasSec;
public EleTimer(String prefix, JSMap json, Context context) {
super(context);
var imgEntrys = json.jsmap("imgs").entrySet();
for(var imgEntry : imgEntrys) imgMap.put(imgEntry.getKey(), BitmapFactory.decodeFile(prefix+imgEntry.getValue()));
text = imgMap.get("text");
day = imgMap.get("day");
hour = imgMap.get("hour");
min = imgMap.get("min");
sec = imgMap.get("sec");
spaceWidth = (int) Math.round(json.dbl("spaceWidth"));
isDown = json.bool("isDown");
targetTime = Dates.milli(json.stnn("targetTime")) / 1000;
hasDay = json.bool("hasDay");
hasHour = json.bool("hasHour");
hasMin = json.bool("hasMin");
hasSec = json.bool("hasSec");
isMultiline = json.bool("isMultiline");
paint.setTextAlign(Paint.Align.CENTER);
try {
setBackgroundColor(Color.parseColor(json.stnn("backColor")));
} catch (Exception ignored) {}
}
void cal() {
var cur = System.currentTimeMillis() / 1000;
var secs = isDown ? targetTime - cur : cur - targetTime;
if(secs < 0) secs = 0;
len = 0;
imgs.clear();
if(text!=null && ! isMultiline) {
imgs.add(text);
imgs.add(null);
len += text.getWidth();
len += spaceWidth;
}
if(hasDay) {
var str = Long.toString(secs/86400);
for(int cc=0; cc<str.length(); cc++) {
var img = imgMap.get(str.substring(cc, cc+1));
imgs.add(img);
len += img.getWidth();
}
imgs.add(null);
imgs.add(day);
imgs.add(null);
len += day.getWidth();
len += spaceWidth * 2;
secs %= 86400;
}
if(hasHour) {
var str = NumFmts.zz().format(secs/3600);
for(int cc=0; cc<str.length(); cc++) {
var img = imgMap.get(str.substring(cc, cc+1));
imgs.add(img);
len += img.getWidth();
}
imgs.add(hour);
imgs.add(null);
len += hour.getWidth();
len += spaceWidth;
secs %= 3600;
}
if(hasMin) {
var str = NumFmts.zz().format(secs/60);
for(int cc=0; cc<str.length(); cc++) {
var img = imgMap.get(str.substring(cc, cc+1));
imgs.add(img);
len += img.getWidth();
}
imgs.add(min);
imgs.add(null);
len += min.getWidth();
len += spaceWidth;
secs %= 60;
}
if(hasSec) {
var str = NumFmts.zz().format(secs);
for(int cc=0; cc<str.length(); cc++) {
var img = imgMap.get(str.substring(cc, cc+1));
imgs.add(img);
len += img.getWidth();
}
imgs.add(sec);
imgs.add(null);
len += sec.getWidth();
len += spaceWidth;
}
imgs.remove(imgs.size()-1);
len -= spaceWidth;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(lastSec==0) {
cal();
choreographer.postFrameCallback(this);
}
int x = (getWidth()-len) / 2, y;
if(text!=null && isMultiline) {
y = getHeight() / 2;
canvas.drawBitmap(text, (getWidth()-text.getWidth()) / 2, y-text.getHeight(), null);
} else y = (getHeight() - imgs.get(0).getHeight()) / 2;
for(var img : imgs) {
if(img==null) x += spaceWidth;
else {
canvas.drawBitmap(img, x, y, null);
x += img.getWidth();
}
}
}
Choreographer choreographer = Choreographer.getInstance();
long lastSec = 0;
@Override
public void doFrame(long frameTimeNanos) {
if(! isShown()) {
lastSec = 0;
return;
}
var sec = frameTimeNanos / 1000000000;
if(sec != lastSec) {
lastSec = sec;
cal();
invalidate();
}
choreographer.postFrameCallback(this);
}
}