package com.james.status.views;
import android.animation.Animator;
import android.animation.ArgbEvaluator;
import android.animation.LayoutTransition;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.WallpaperInfo;
import android.app.WallpaperManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.support.annotation.ColorInt;
import android.support.annotation.Nullable;
import android.support.v7.graphics.Palette;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.james.status.R;
import com.james.status.data.icon.IconData;
import com.james.status.utils.ColorUtils;
import com.james.status.utils.ImageUtils;
import com.james.status.utils.PreferenceUtils;
import com.james.status.utils.StaticUtils;
import java.util.ArrayList;
import java.util.List;
public class StatusView extends FrameLayout {
private LinearLayout status, leftLayout, rightLayout, centerLayout;
private float x, y;
private int burnInOffsetX, burnInOffsetY;
@ColorInt
private Integer color, iconColor = Color.WHITE;
private boolean isSystemShowing, isFullscreen, isAnimations, isIconAnimations, isTintedIcons, isContrastIcons, isRegistered;
private List<IconData> icons;
private WallpaperManager wallpaperManager;
private Handler handler;
private Runnable burnInRunnable = new Runnable() {
@Override
public void run() {
if (status != null && status.getParent() != null) {
ViewGroup.LayoutParams layoutParams = status.getLayoutParams();
switch (burnInOffsetX) {
case 0:
status.setX(x - 1);
burnInOffsetX++;
break;
case 2:
case 3:
case 4:
status.setX(x + 1);
burnInOffsetX++;
break;
case 6:
status.setX(x - 1);
burnInOffsetX++;
break;
case 7:
status.setX(x - 1);
burnInOffsetX = 0;
break;
default:
status.setX(x);
burnInOffsetX++;
}
switch (burnInOffsetY) {
case 0:
case 1:
case 2:
status.setY(y + 1);
burnInOffsetY++;
break;
case 4:
case 5:
case 6:
status.setY(y - 1);
burnInOffsetY++;
break;
case 7:
status.setY(y);
burnInOffsetY = 0;
break;
default:
status.setY(y);
burnInOffsetY++;
}
status.setLayoutParams(layoutParams);
}
handler.postDelayed(this, 2000);
}
};
public StatusView(Context context) {
this(context, null);
}
public StatusView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public StatusView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
handler = new Handler();
}
@TargetApi(21)
public StatusView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
handler = new Handler();
}
public void setUp() {
if (status != null && status.getParent() != null) removeView(status);
View v = LayoutInflater.from(getContext()).inflate(R.layout.layout_status, this, false);
status = (LinearLayout) v.findViewById(R.id.status);
status.getLayoutParams().height = StaticUtils.getStatusBarHeight(getContext());
leftLayout = (LinearLayout) v.findViewById(R.id.notificationIcons);
rightLayout = (LinearLayout) v.findViewById(R.id.statusIcons);
centerLayout = (LinearLayout) v.findViewById(R.id.statusCenterIcons);
Boolean isAnimations = PreferenceUtils.getBooleanPreference(getContext(), PreferenceUtils.PreferenceIdentifier.STATUS_BACKGROUND_ANIMATIONS);
this.isAnimations = isAnimations != null ? isAnimations : true;
Boolean isIconAnimations = PreferenceUtils.getBooleanPreference(getContext(), PreferenceUtils.PreferenceIdentifier.STATUS_ICON_ANIMATIONS);
this.isIconAnimations = isIconAnimations != null ? isIconAnimations : true;
if (this.isIconAnimations) {
leftLayout.setLayoutTransition(new LayoutTransition());
rightLayout.setLayoutTransition(new LayoutTransition());
centerLayout.setLayoutTransition(new LayoutTransition());
} else {
leftLayout.setLayoutTransition(null);
rightLayout.setLayoutTransition(null);
centerLayout.setLayoutTransition(null);
}
Boolean isTintedIcons = PreferenceUtils.getBooleanPreference(getContext(), PreferenceUtils.PreferenceIdentifier.STATUS_TINTED_ICONS);
this.isTintedIcons = isTintedIcons != null ? isTintedIcons : false;
Boolean isContrastIcons = PreferenceUtils.getBooleanPreference(getContext(), PreferenceUtils.PreferenceIdentifier.STATUS_DARK_ICONS);
this.isContrastIcons = isContrastIcons != null ? isContrastIcons : true;
addView(v);
status.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
x = status.getX();
y = status.getY();
Boolean isBurnInProtection = PreferenceUtils.getBooleanPreference(getContext(), PreferenceUtils.PreferenceIdentifier.STATUS_BURNIN_PROTECTION);
if (isBurnInProtection != null && isBurnInProtection)
handler.post(burnInRunnable);
status.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
Boolean isStatusColorAuto = PreferenceUtils.getBooleanPreference(getContext(), PreferenceUtils.PreferenceIdentifier.STATUS_COLOR_AUTO);
if (isStatusColorAuto != null && !isStatusColorAuto) {
Integer statusBarColor = PreferenceUtils.getIntegerPreference(getContext(), PreferenceUtils.PreferenceIdentifier.STATUS_COLOR);
if (statusBarColor != null) setColor(statusBarColor);
} else if (color != null) setColor(color);
else setColor(Color.BLACK);
Integer defaultIconColor = PreferenceUtils.getIntegerPreference(getContext(), PreferenceUtils.PreferenceIdentifier.STATUS_ICON_COLOR);
if (defaultIconColor != null) iconColor = defaultIconColor;
if (wallpaperManager == null) wallpaperManager = WallpaperManager.getInstance(getContext());
}
public void setIcons(List<IconData> icons) {
for (int i = (leftLayout.getChildCount() - 1); i >= 0; i--) {
View child = leftLayout.getChildAt(i);
Object tag = child.getTag();
if (tag != null && tag instanceof IconData) {
((IconData) tag).unregister();
leftLayout.removeViewAt(i);
}
}
for (int i = (centerLayout.getChildCount() - 1); i >= 0; i--) {
View child = centerLayout.getChildAt(i);
Object tag = child.getTag();
if (tag != null && tag instanceof IconData) {
((IconData) tag).unregister();
centerLayout.removeViewAt(i);
}
}
for (int i = (rightLayout.getChildCount() - 1); i >= 0; i--) {
View child = rightLayout.getChildAt(i);
Object tag = child.getTag();
if (tag != null && tag instanceof IconData) {
((IconData) tag).unregister();
rightLayout.removeViewAt(i);
}
}
this.icons = icons;
for (final IconData iconData : icons) {
if (!iconData.isVisible()) continue;
final View item = iconData.getIconView();
iconData.setDrawableListener(new IconData.DrawableListener() {
@Override
public void onUpdate(@Nullable Drawable drawable) {
CustomImageView iconView = (CustomImageView) item.findViewById(R.id.icon);
if (drawable != null && iconView != null)
iconView.setImageDrawable(drawable, iconColor);
else if (iconView == null || !iconView.getParent().equals(item))
setIconTint(item, iconColor);
}
});
switch (iconData.getGravity()) {
case IconData.LEFT_GRAVITY:
leftLayout.addView(item, 0);
break;
case IconData.CENTER_GRAVITY:
centerLayout.addView(item, 0);
break;
case IconData.RIGHT_GRAVITY:
rightLayout.addView(item, 0);
break;
}
}
}
public List<IconData> getIcons() {
if (icons == null) icons = new ArrayList<>();
return icons;
}
public void register() {
if (icons != null && !isRegistered()) {
for (IconData icon : icons) {
icon.register();
}
isRegistered = true;
}
}
public void unregister() {
if (icons != null && isRegistered()) {
for (IconData icon : icons) {
icon.unregister();
}
isRegistered = false;
}
}
public boolean isRegistered() {
return isRegistered;
}
public void setSystemShowing(boolean isSystemShowing) {
if ((this.isFullscreen != isSystemShowing || this.isSystemShowing != isSystemShowing) && isSystemShowing)
setStatusBarVisibility(false);
this.isSystemShowing = isSystemShowing;
}
public boolean isSystemShowing() {
return isSystemShowing;
}
public void setFullscreen(boolean isFullscreen) {
if (((getVisibility() == View.GONE) != isFullscreen) && !isSystemShowing) {
setStatusBarVisibility(!isFullscreen);
}
this.isFullscreen = isFullscreen;
}
public boolean isFullscreen() {
return isFullscreen;
}
private void setStatusBarVisibility(final boolean visible) {
if (isAnimations) {
ValueAnimator animator = ValueAnimator.ofFloat(getY(), visible ? 0 : -StaticUtils.getStatusBarHeight(getContext()));
animator.setDuration(150);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
float y = (float) valueAnimator.getAnimatedValue();
setY(y);
}
});
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
if (visible) setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animator) {
if (!visible) setVisibility(View.GONE);
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
animator.start();
} else {
if (visible) setVisibility(View.VISIBLE);
else setVisibility(View.GONE);
}
}
public void setColor(@ColorInt int color) {
if (this.color == null) this.color = Color.BLACK;
color = Color.argb(255, Color.red(color), Color.green(color), Color.blue(color));
if (!isTintedIcons) {
if (isAnimations) {
ValueAnimator animator = ValueAnimator.ofObject(new ArgbEvaluator(), this.color, color);
animator.setDuration(150);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int color = (int) animation.getAnimatedValue();
if (status != null)
status.setBackgroundColor(Color.argb(255, Color.red(color), Color.green(color), Color.blue(color)));
}
});
animator.start();
} else
status.setBackgroundColor(Color.argb(255, Color.red(color), Color.green(color), Color.blue(color)));
setDarkMode(!ColorUtils.isColorDark(color));
} else if (status != null) {
int backgroundColor = getDefaultColor();
if (color == backgroundColor) {
if (color == Color.BLACK) color = getDefaultIconColor();
else if (color == Color.WHITE) color = Color.BLACK;
}
status.setBackgroundColor(backgroundColor);
if (isContrastIcons)
color = ColorUtils.isColorDark(backgroundColor) ? ColorUtils.lightColor(color) : ColorUtils.darkColor(color);
if (isIconAnimations) {
ValueAnimator animator = ValueAnimator.ofObject(new ArgbEvaluator(), this.color, color);
animator.setDuration(150);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int color = (int) animation.getAnimatedValue();
if (status != null)
setIconTint(status, Color.argb(255, Color.red(color), Color.green(color), Color.blue(color)));
}
});
animator.start();
} else
setIconTint(status, Color.argb(255, Color.red(color), Color.green(color), Color.blue(color)));
iconColor = color;
}
this.color = color;
}
@ColorInt
public int getColor() {
return color;
}
@ColorInt
private int getDefaultColor() {
Integer color = PreferenceUtils.getIntegerPreference(getContext(), PreferenceUtils.PreferenceIdentifier.STATUS_COLOR);
if (color == null) color = Color.BLACK;
return color;
}
@ColorInt
private int getDefaultIconColor() {
Integer color = PreferenceUtils.getIntegerPreference(getContext(), PreferenceUtils.PreferenceIdentifier.STATUS_ICON_COLOR);
if (color == null) color = Color.WHITE;
return color;
}
public void setTransparent() {
if (status != null && wallpaperManager != null) {
Drawable backgroundDrawable;
WallpaperInfo wallpaperInfo = wallpaperManager.getWallpaperInfo();
if (wallpaperInfo != null)
backgroundDrawable = wallpaperInfo.loadThumbnail(getContext().getPackageManager());
else {
try {
backgroundDrawable = wallpaperManager.getDrawable();
} catch (SecurityException e) {
setColor(getDefaultColor());
return;
}
}
Bitmap background = ImageUtils.cropBitmapToBar(getContext(), ImageUtils.drawableToBitmap(backgroundDrawable));
if (background != null) {
int color = ColorUtils.getAverageColor(background);
Boolean transparent = PreferenceUtils.getBooleanPreference(getContext(), PreferenceUtils.PreferenceIdentifier.STATUS_HOME_TRANSPARENT);
if (transparent == null || transparent) {
status.setBackground(new BitmapDrawable(getResources(), background));
setDarkMode(!ColorUtils.isColorDark(color));
StatusView.this.color = color;
} else setColor(color);
} else setColor(getDefaultColor());
}
}
public void setDarkMode(boolean isDarkMode) {
if (isContrastIcons) {
int color = isDarkMode ? Color.BLACK : getDefaultIconColor();
if (isIconAnimations) {
ValueAnimator animator = ValueAnimator.ofObject(new ArgbEvaluator(), iconColor, color);
animator.setDuration(150);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int color = (int) animation.getAnimatedValue();
if (status != null)
setIconTint(status, Color.argb(255, Color.red(color), Color.green(color), Color.blue(color)));
}
});
animator.start();
} else
setIconTint(status, Color.argb(255, Color.red(color), Color.green(color), Color.blue(color)));
iconColor = color;
}
}
private void setIconTint(View view, @ColorInt int color) {
for (IconData icon : getIcons()) {
icon.setColor(color);
}
if (view instanceof LinearLayout) {
for (int i = 0; i < ((LinearLayout) view).getChildCount(); i++) {
setIconTint(((LinearLayout) view).getChildAt(i), color);
}
} else if (view instanceof TextView) {
if (view.getTag() == null)
((TextView) view).setTextColor(color);
} else if (view instanceof CustomImageView) {
CustomImageView imageView = (CustomImageView) view;
if (imageView.getDrawable() != null)
imageView.setColorFilter(color);
}
}
public void setLockscreen(boolean lockscreen) {
Boolean expand = PreferenceUtils.getBooleanPreference(getContext(), PreferenceUtils.PreferenceIdentifier.STATUS_LOCKSCREEN_EXPAND);
if (expand != null && expand)
status.getLayoutParams().height = StaticUtils.getStatusBarHeight(getContext()) * (lockscreen ? 3 : 1);
if (lockscreen) {
Palette.from(ImageUtils.drawableToBitmap(WallpaperManager.getInstance(getContext()).getFastDrawable())).generate(new Palette.PaletteAsyncListener() {
@Override
public void onGenerated(Palette palette) {
setColor(palette.getDarkVibrantColor(ColorUtils.darkColor(palette.getVibrantColor(Color.BLACK))));
}
});
}
}
}