Skip to content

Commit e07cd98

Browse files
committed
Fixed lyrics loading lag, thanks to piyush
1 parent 17a1c5e commit e07cd98

3 files changed

Lines changed: 71 additions & 53 deletions

File tree

app/src/main/java/com/xapps/media/xmusic/widget/LyricItemDelegate.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public class LyricItemDelegate {
2626
private int rawBgHeight = 0;
2727
private int rawRomajiHeight = 0;
2828

29+
private int preppedWidth = -1;
2930
private boolean isPrepped = false;
3031
public boolean isActive = false;
3132
private float activeProgress = 0f;
@@ -96,7 +97,6 @@ public void precomputeLayouts(int textWidth) {
9697
}
9798

9899
public void measureStaticBounds(int availableWidth, int parentPaddingLeft, int parentPaddingRight) {
99-
isPrepped = false;
100100
int contentWidth = availableWidth - parentPaddingLeft - parentPaddingRight;
101101

102102
paddingLeft = (int) (contentWidth * 0.05f);
@@ -109,6 +109,11 @@ public void measureStaticBounds(int availableWidth, int parentPaddingLeft, int p
109109

110110
int textWidth = contentWidth - paddingLeft - paddingRight;
111111

112+
if (textWidth != preppedWidth) {
113+
isPrepped = false;
114+
preppedWidth = textWidth;
115+
}
116+
112117
if (dotsView != null) {
113118
dotsView.setTimes(item.mainLine.time, item.mainLine.endTime);
114119
dotsView.measure(

app/src/main/java/com/xapps/media/xmusic/widget/XLyricsContainerView.java

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -165,37 +165,33 @@ public void setLyrics(List<LyricLine> newLyrics) {
165165
tempItems.add(item);
166166
}
167167

168-
mainHandler.post(() -> {
169-
List<LyricItemDelegate> tempDelegates = new ArrayList<>();
170-
for (LyricItem item : tempItems) {
171-
LyricItemDelegate delegate = new LyricItemDelegate(getContext(), item);
172-
if (currentColor != 0) delegate.setLyricColor(currentColor);
173-
if (currentFontConfig != null) delegate.setFontConfig(currentFontConfig);
174-
delegate.setEnableSparkles(enableSparkles);
175-
tempDelegates.add(delegate);
168+
List<LyricItemDelegate> tempDelegates = new ArrayList<>();
169+
int contentWidth = finalAvailableWidth - parentPaddingLeft - parentPaddingRight;
170+
171+
for (LyricItem item : tempItems) {
172+
LyricItemDelegate delegate = new LyricItemDelegate(getContext(), item);
173+
if (currentColor != 0) delegate.setLyricColor(currentColor);
174+
if (currentFontConfig != null) delegate.setFontConfig(currentFontConfig);
175+
delegate.setEnableSparkles(enableSparkles);
176+
177+
int pLeft = (int) (contentWidth * 0.05f);
178+
int pRight = (int) (contentWidth * 0.2f);
179+
if (delegate.getItem().mainLine != null && delegate.getItem().mainLine.vocalType != 1 && !delegate.getItem().mainLine.isWaitingDots && !delegate.getItem().mainLine.isBackground) {
180+
pLeft = (int) (contentWidth * 0.2f);
181+
pRight = (int) (contentWidth * 0.05f);
176182
}
183+
int textWidth = contentWidth - pLeft - pRight;
184+
delegate.precomputeLayouts(textWidth);
185+
186+
tempDelegates.add(delegate);
187+
}
177188

178-
bgExecutor.execute(() -> {
179-
int contentWidth = finalAvailableWidth - parentPaddingLeft - parentPaddingRight;
180-
for (LyricItemDelegate delegate : tempDelegates) {
181-
int pLeft = (int) (contentWidth * 0.05f);
182-
int pRight = (int) (contentWidth * 0.2f);
183-
if (delegate.getItem().mainLine != null && delegate.getItem().mainLine.vocalType != 1 && !delegate.getItem().mainLine.isWaitingDots && !delegate.getItem().mainLine.isBackground) {
184-
pLeft = (int) (contentWidth * 0.2f);
185-
pRight = (int) (contentWidth * 0.05f);
186-
}
187-
int textWidth = contentWidth - pLeft - pRight;
188-
delegate.precomputeLayouts(textWidth);
189-
}
190-
191-
mainHandler.post(() -> {
192-
lineDelegates.clear();
193-
lineDelegates.addAll(tempDelegates);
194-
scrollTo(0, 0);
195-
requestLayout();
196-
invalidate();
197-
});
198-
});
189+
mainHandler.post(() -> {
190+
lineDelegates.clear();
191+
lineDelegates.addAll(tempDelegates);
192+
scrollTo(0, 0);
193+
requestLayout();
194+
invalidate();
199195
});
200196
});
201197
}

app/src/main/java/com/xapps/media/xmusic/widget/XLyricsLineView.java

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,15 @@
2727

2828
public class XLyricsLineView extends View {
2929

30+
private static Typeface sharedTypeface;
31+
private static final AccelerateDecelerateInterpolator sharedInterpolator = new AccelerateDecelerateInterpolator();
32+
private static final Random sharedRandom = new Random();
33+
private static LinearGradient sharedBrushShader;
34+
private static int lastActiveColor = -1;
35+
private static int lastFutureColor = -1;
36+
3037
public final TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
3138
private final Paint sparklePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
32-
private final AccelerateDecelerateInterpolator interpolator = new AccelerateDecelerateInterpolator();
33-
private final Random random = new Random();
3439

3540
protected StaticLayout staticLayout;
3641
private LyricLine lyricLine;
@@ -125,8 +130,11 @@ public XLyricsLineView(Context context, AttributeSet attrs) {
125130
}
126131

127132
private void init() {
128-
Typeface customFont = ResourcesCompat.getFont(getContext(), R.font.gsans_flex_full);
129-
textPaint.setTypeface(Typeface.create(customFont, Typeface.BOLD));
133+
if (sharedTypeface == null) {
134+
Typeface customFont = ResourcesCompat.getFont(getContext(), R.font.gsans_flex_full);
135+
sharedTypeface = Typeface.create(customFont, Typeface.BOLD);
136+
}
137+
textPaint.setTypeface(sharedTypeface);
130138
textPaint.setFontFeatureSettings("'liga' 0, 'clig' 0");
131139
setClipToOutline(false);
132140
setClickable(false);
@@ -185,7 +193,11 @@ public int getDesiredHeight() {
185193
}
186194

187195
public int getDesiredHeight(String text, int width) {
188-
if (width <= 0) return 0;
196+
if (width <= 0 || text == null || text.isEmpty()) return 0;
197+
LayoutCache cache = this.layoutCache;
198+
if (cache != null && text.equals(cache.text) && width == cache.width && this.alignment == cache.alignment) {
199+
return cache.staticLayout.getHeight() + (int)(getExtraPadding() * 2);
200+
}
189201
StaticLayout temp = StaticLayout.Builder.obtain(text, 0, text.length(), textPaint, width)
190202
.setAlignment(alignment)
191203
.setIncludePad(true)
@@ -527,10 +539,15 @@ public void setText(String text, int width) {
527539
}
528540

529541
private void updateShader() {
530-
brushShader = new LinearGradient(0, 0, GRADIENT_WIDTH, 0,
531-
new int[]{activeColor, activeColor, futureColor, futureColor},
532-
new float[]{0f, 0.1f, 0.9f, 1f},
533-
Shader.TileMode.CLAMP);
542+
if (sharedBrushShader == null || activeColor != lastActiveColor || futureColor != lastFutureColor) {
543+
lastActiveColor = activeColor;
544+
lastFutureColor = futureColor;
545+
sharedBrushShader = new LinearGradient(0, 0, GRADIENT_WIDTH, 0,
546+
new int[]{activeColor, activeColor, futureColor, futureColor},
547+
new float[]{0f, 0.1f, 0.9f, 1f},
548+
Shader.TileMode.CLAMP);
549+
}
550+
brushShader = sharedBrushShader;
534551
}
535552

536553
private float getGlobalXForOffset(int offset) {
@@ -592,15 +609,15 @@ public void updateProgress(int progressMs, boolean snap) {
592609
float gap = syl.startTime - lastEndTime;
593610
if (gap > 0) {
594611
float ratio = (float) (progressMs - lastEndTime) / gap;
595-
globalX = lastLineEndGlobal + (sylGlobalStart - lastLineEndGlobal) * interpolator.getInterpolation(ratio);
612+
globalX = lastLineEndGlobal + (sylGlobalStart - lastLineEndGlobal) * sharedInterpolator.getInterpolation(ratio);
596613
} else {
597614
globalX = lastLineEndGlobal;
598615
}
599616
found = true;
600617
break;
601618
} else if (progressMs >= syl.startTime && progressMs <= syl.endTime) {
602619
float ratio = (float) (progressMs - syl.startTime) / Math.max(1, syl.endTime - syl.startTime);
603-
globalX = sylGlobalStart + ((sylGlobalEnd - sylGlobalStart) * interpolator.getInterpolation(ratio));
620+
globalX = sylGlobalStart + ((sylGlobalEnd - sylGlobalStart) * sharedInterpolator.getInterpolation(ratio));
604621
found = true;
605622
break;
606623
}
@@ -641,19 +658,19 @@ public void updateProgress(int progressMs, boolean snap) {
641658
private void spawnSparkle(float headX, float topY, float bottomY) {
642659
if (sparkles.size() > 45) return;
643660
Sparkle s = new Sparkle();
644-
s.baseX = headX - (random.nextFloat() * spToPx(4f));
661+
s.baseX = headX - (sharedRandom.nextFloat() * spToPx(4f));
645662
float h = bottomY - topY;
646-
s.baseY = topY + (h * 0.125f) + (random.nextFloat() * (h * 0.75f));
647-
s.vx = (random.nextFloat() - 0.5f) * spToPx(8f);
648-
s.vy = -(random.nextFloat() * spToPx(10f) + spToPx(4f));
649-
s.maxLife = 0.4f + random.nextFloat() * 0.6f;
663+
s.baseY = topY + (h * 0.125f) + (sharedRandom.nextFloat() * (h * 0.75f));
664+
s.vx = (sharedRandom.nextFloat() - 0.5f) * spToPx(8f);
665+
s.vy = -(sharedRandom.nextFloat() * spToPx(10f) + spToPx(4f));
666+
s.maxLife = 0.4f + sharedRandom.nextFloat() * 0.6f;
650667
s.life = s.maxLife;
651-
s.maxAlpha = 0.6f + random.nextFloat() * 0.4f;
668+
s.maxAlpha = 0.6f + sharedRandom.nextFloat() * 0.4f;
652669
s.alpha = s.maxAlpha;
653-
s.size = spToPx(0.8f + random.nextFloat() * 1.4f);
654-
s.phase = random.nextFloat() * (float) Math.PI * 2f;
655-
s.amplitude = spToPx(1.5f + random.nextFloat() * 1.5f);
656-
s.frequency = 6f + random.nextFloat() * 8f;
670+
s.size = spToPx(0.8f + sharedRandom.nextFloat() * 1.4f);
671+
s.phase = sharedRandom.nextFloat() * (float) Math.PI * 2f;
672+
s.amplitude = spToPx(1.5f + sharedRandom.nextFloat() * 1.5f);
673+
s.frequency = 6f + sharedRandom.nextFloat() * 8f;
657674
sparkles.add(s);
658675
}
659676

@@ -824,8 +841,8 @@ protected void onDraw(Canvas canvas) {
824841
float lineBottom = staticLayout.getLineBottom(currentLineIdx);
825842

826843
if (clampedLocalX > 0 && clampedLocalX < lineWidth) {
827-
if (random.nextFloat() < 0.7f) {
828-
int spawnCount = random.nextInt(2) + 1;
844+
if (sharedRandom.nextFloat() < 0.7f) {
845+
int spawnCount = sharedRandom.nextInt(2) + 1;
829846
for(int k=0; k<spawnCount; k++) {
830847
spawnSparkle(headX, lineTop + getExtraPadding(), lineBottom + getExtraPadding());
831848
}

0 commit comments

Comments
 (0)