NekoX/TMessagesProj/src/main/java/org/telegram/ui/AvatarPreviewPagerIndicator...

385 lines
15 KiB
Java

package org.telegram.ui;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.GradientDrawable;
import android.os.Build;
import android.os.SystemClock;
import android.text.TextPaint;
import android.view.View;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.ProfileGalleryView;
import java.util.Arrays;
public class AvatarPreviewPagerIndicator extends View implements ProfileGalleryView.Callback {
private final RectF indicatorRect = new RectF();
private final int statusBarHeight = 0;
private int overlayCountVisible = 1;
private final Rect topOverlayRect = new Rect();
private final Rect bottomOverlayRect = new Rect();
private final RectF rect = new RectF();
private final GradientDrawable topOverlayGradient;
private final GradientDrawable bottomOverlayGradient;
private final ValueAnimator animator;
private final float[] animatorValues = new float[]{0f, 1f};
private final Paint backgroundPaint;
private final Paint barPaint;
private final Paint selectedBarPaint;
Path path = new Path();
RectF rectF = new RectF();
private final GradientDrawable[] pressedOverlayGradient = new GradientDrawable[2];
private final boolean[] pressedOverlayVisible = new boolean[2];
private final float[] pressedOverlayAlpha = new float[2];
private boolean isOverlaysVisible;
private float currentAnimationValue;
private float alpha = 0f;
private float[] alphas = null;
private long lastTime;
private float previousSelectedProgress;
private int previousSelectedPotision = -1;
private float currentProgress;
private int selectedPosition;
private float currentLoadingAnimationProgress;
private int currentLoadingAnimationDirection = 1;
protected ProfileGalleryView profileGalleryView;
TextPaint textPaint;
private float progressToCounter;
public AvatarPreviewPagerIndicator(Context context) {
super(context);
barPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
barPaint.setColor(0x55ffffff);
selectedBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
selectedBarPaint.setColor(0xffffffff);
topOverlayGradient = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[] {0x42000000, 0});
topOverlayGradient.setShape(GradientDrawable.RECTANGLE);
bottomOverlayGradient = new GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, new int[] {0x42000000, 0});
bottomOverlayGradient.setShape(GradientDrawable.RECTANGLE);
for (int i = 0; i < 2; i++) {
final GradientDrawable.Orientation orientation = i == 0 ? GradientDrawable.Orientation.LEFT_RIGHT : GradientDrawable.Orientation.RIGHT_LEFT;
pressedOverlayGradient[i] = new GradientDrawable(orientation, new int[] {0x32000000, 0});
pressedOverlayGradient[i].setShape(GradientDrawable.RECTANGLE);
}
backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
backgroundPaint.setColor(Color.BLACK);
backgroundPaint.setAlpha(66);
animator = ValueAnimator.ofFloat(0f, 1f);
animator.setDuration(250);
animator.setInterpolator(CubicBezierInterpolator.EASE_BOTH);
animator.addUpdateListener(anim -> {
float value = AndroidUtilities.lerp(animatorValues, currentAnimationValue = anim.getAnimatedFraction());
setAlphaValue(value, true);
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (!isOverlaysVisible) {
setVisibility(GONE);
}
}
@Override
public void onAnimationStart(Animator animation) {
setVisibility(VISIBLE);
}
});
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(Color.WHITE);
textPaint.setTypeface(Typeface.SANS_SERIF);
textPaint.setTextAlign(Paint.Align.CENTER);
textPaint.setTextSize(AndroidUtilities.dpf2(15f));
}
public void saveCurrentPageProgress() {
previousSelectedProgress = currentProgress;
previousSelectedPotision = selectedPosition;
currentLoadingAnimationProgress = 0.0f;
currentLoadingAnimationDirection = 1;
}
public void setAlphaValue(float value, boolean self) {
if (Build.VERSION.SDK_INT > 18) {
int alpha = (int) (255 * value);
topOverlayGradient.setAlpha(alpha);
bottomOverlayGradient.setAlpha(alpha);
backgroundPaint.setAlpha((int) (66 * value));
barPaint.setAlpha((int) (0x55 * value));
selectedBarPaint.setAlpha(alpha);
this.alpha = value;
} else {
setAlpha(value);
}
if (!self) {
currentAnimationValue = value;
}
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
path.reset();
rectF.set(0, 0, getMeasuredHeight(), getMeasuredWidth());
path.addRoundRect(rectF, new float[]{AndroidUtilities.dp(13), AndroidUtilities.dp(13), AndroidUtilities.dp(13), AndroidUtilities.dp(13), 0, 0, 0, 0}, Path.Direction.CCW);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
final int actionBarHeight = statusBarHeight + ActionBar.getCurrentActionBarHeight();
final float k = 0.5f;
topOverlayRect.set(0, 0, w, (int) (actionBarHeight * k));
bottomOverlayRect.set(0, (int) (h - AndroidUtilities.dp(72f) * k), w, h);
topOverlayGradient.setBounds(0, topOverlayRect.bottom, w, actionBarHeight + AndroidUtilities.dp(16f));
bottomOverlayGradient.setBounds(0, h - AndroidUtilities.dp(72f) - AndroidUtilities.dp(24f), w, bottomOverlayRect.top);
pressedOverlayGradient[0].setBounds(0, 0, w / 5, h);
pressedOverlayGradient[1].setBounds(w - (w / 5), 0, w, h);
}
@Override
protected void onDraw(Canvas canvas) {
// canvas.save();
// canvas.clipPath(path);
for (int i = 0; i < 2; i++) {
if (pressedOverlayAlpha[i] > 0f) {
pressedOverlayGradient[i].setAlpha((int) (pressedOverlayAlpha[i] * 255));
pressedOverlayGradient[i].draw(canvas);
}
}
topOverlayGradient.draw(canvas);
canvas.drawRect(topOverlayRect, backgroundPaint);
//canvas.restore();
int count = profileGalleryView.getRealCount();
selectedPosition = profileGalleryView.getRealPosition();
if (alphas == null || alphas.length != count) {
alphas = new float[count];
Arrays.fill(alphas, 0.0f);
}
boolean invalidate = false;
long newTime = SystemClock.elapsedRealtime();
long dt = (newTime - lastTime);
if (dt < 0 || dt > 20) {
dt = 17;
}
lastTime = newTime;
if (count > 1 && count <= 20) {
if (overlayCountVisible == 0) {
alpha = 0.0f;
overlayCountVisible = 3;
} else if (overlayCountVisible == 1) {
alpha = 0.0f;
overlayCountVisible = 2;
}
if (overlayCountVisible == 2) {
barPaint.setAlpha((int) (0x55 * alpha));
selectedBarPaint.setAlpha((int) (0xff * alpha));
}
int width = (getMeasuredWidth() - AndroidUtilities.dp(5 * 2) - AndroidUtilities.dp(2 * (count - 1))) / count;
int y = AndroidUtilities.dp(8);
for (int a = 0; a < count; a++) {
int x = AndroidUtilities.dp(5 + a * 2) + width * a;
float progress;
int baseAlpha = 0x55;
if (a == previousSelectedPotision && Math.abs(previousSelectedProgress - 1.0f) > 0.0001f) {
progress = previousSelectedProgress;
canvas.save();
canvas.clipRect(x + width * progress, y, x + width, y + AndroidUtilities.dp(2));
rect.set(x, y, x + width, y + AndroidUtilities.dp(2));
barPaint.setAlpha((int) (0x55 * alpha));
canvas.drawRoundRect(rect, AndroidUtilities.dp(1), AndroidUtilities.dp(1), barPaint);
baseAlpha = 0x50;
canvas.restore();
invalidate = true;
} else if (a == selectedPosition) {
if (profileGalleryView.isCurrentItemVideo()) {
progress = currentProgress = profileGalleryView.getCurrentItemProgress();
if (progress <= 0 && profileGalleryView.isLoadingCurrentVideo() || currentLoadingAnimationProgress > 0.0f) {
currentLoadingAnimationProgress += currentLoadingAnimationDirection * dt / 500.0f;
if (currentLoadingAnimationProgress > 1.0f) {
currentLoadingAnimationProgress = 1.0f;
currentLoadingAnimationDirection *= -1;
} else if (currentLoadingAnimationProgress <= 0) {
currentLoadingAnimationProgress = 0.0f;
currentLoadingAnimationDirection *= -1;
}
}
rect.set(x, y, x + width, y + AndroidUtilities.dp(2));
barPaint.setAlpha((int) ((0x55 + 0x30 * currentLoadingAnimationProgress) * alpha));
canvas.drawRoundRect(rect, AndroidUtilities.dp(1), AndroidUtilities.dp(1), barPaint);
invalidate = true;
baseAlpha = 0x50;
} else {
progress = currentProgress = 1.0f;
}
} else {
progress = 1.0f;
}
rect.set(x, y, x + width * progress, y + AndroidUtilities.dp(2));
if (a != selectedPosition) {
if (overlayCountVisible == 3) {
barPaint.setAlpha((int) (AndroidUtilities.lerp(baseAlpha, 0xff, CubicBezierInterpolator.EASE_BOTH.getInterpolation(alphas[a])) * alpha));
}
} else {
alphas[a] = 0.75f;
}
canvas.drawRoundRect(rect, AndroidUtilities.dp(1), AndroidUtilities.dp(1), a == selectedPosition ? selectedBarPaint : barPaint);
}
if (overlayCountVisible == 2) {
if (alpha < 1.0f) {
alpha += dt / 180.0f;
if (alpha > 1.0f) {
alpha = 1.0f;
}
invalidate = true;
} else {
overlayCountVisible = 3;
}
} else if (overlayCountVisible == 3) {
for (int i = 0; i < alphas.length; i++) {
if (i != selectedPosition && alphas[i] > 0.0f) {
alphas[i] -= dt / 500.0f;
if (alphas[i] <= 0.0f) {
alphas[i] = 0.0f;
if (i == previousSelectedPotision) {
previousSelectedPotision = -1;
}
}
invalidate = true;
} else if (i == previousSelectedPotision) {
previousSelectedPotision = -1;
}
}
}
}
if (count > 20 || progressToCounter != 0) {
final float textWidth = textPaint.measureText(getCurrentTitle());
indicatorRect.right = getMeasuredWidth() - AndroidUtilities.dp(8f);
indicatorRect.left = indicatorRect.right - (textWidth + AndroidUtilities.dpf2(16f));
indicatorRect.top = AndroidUtilities.dp(8f);
indicatorRect.bottom = indicatorRect.top + AndroidUtilities.dp(26);
final float radius = AndroidUtilities.dpf2(12);
canvas.save();
boolean showCounter = count > 20;
if (showCounter && progressToCounter != 1f) {
progressToCounter += dt / 150f;
} else if (!showCounter && progressToCounter != 0f) {
progressToCounter -= dt / 150f;
}
if (progressToCounter >= 1f) {
progressToCounter = 1f;
} else if (progressToCounter <= 0) {
progressToCounter = 0f;
} else {
invalidate();
}
canvas.scale(progressToCounter, progressToCounter, indicatorRect.centerX(), indicatorRect.centerY());
canvas.drawRoundRect(indicatorRect, radius, radius, backgroundPaint);
canvas.drawText(getCurrentTitle(), indicatorRect.centerX(), indicatorRect.top + AndroidUtilities.dpf2(18.5f), textPaint);
canvas.restore();
}
for (int i = 0; i < 2; i++) {
if (pressedOverlayVisible[i]) {
if (pressedOverlayAlpha[i] < 1f) {
pressedOverlayAlpha[i] += dt / 180.0f;
if (pressedOverlayAlpha[i] > 1f) {
pressedOverlayAlpha[i] = 1f;
}
invalidate = true;
}
} else {
if (pressedOverlayAlpha[i] > 0f) {
pressedOverlayAlpha[i] -= dt / 180.0f;
if (pressedOverlayAlpha[i] < 0f) {
pressedOverlayAlpha[i] = 0f;
}
invalidate = true;
}
}
}
if (invalidate) {
postInvalidateOnAnimation();
}
}
int lastCurrentItem = -1;
String title;
private String getCurrentTitle() {
if (lastCurrentItem != profileGalleryView.getCurrentItem()) {
title = profileGalleryView.getAdapter().getPageTitle(profileGalleryView.getCurrentItem()).toString();
lastCurrentItem = profileGalleryView.getCurrentItem();
}
return title;
}
@Override
public void onDown(boolean left) {
pressedOverlayVisible[left ? 0 : 1] = true;
postInvalidateOnAnimation();
}
@Override
public void onRelease() {
Arrays.fill(pressedOverlayVisible, false);
postInvalidateOnAnimation();
}
@Override
public void onPhotosLoaded() {
}
@Override
public void onVideoSet() {
invalidate();
}
public void setProfileGalleryView(ProfileGalleryView profileGalleryView) {
this.profileGalleryView = profileGalleryView;
}
public ProfileGalleryView getProfileGalleryView() {
return profileGalleryView;
}
}