android - studio - como cambiar el color de whatsapp sin root
¿Cómo puedo animar el cambio de color de la barra de estado y la barra de herramientas(como la nueva aplicación Calendario)? (4)
La nueva aplicación Google Calendar tiene una animación que me gustaría hacer en mi aplicación. Cuando creas un nuevo evento, puedes elegir un color para el evento. Cuando lo haces, la barra de estado y la barra de herramientas cambian a ese color con un efecto circular que los cubre a ambos.
Aquí hay un ejemplo de lo que me gustaría hacer:
Puedo cambiar el color de la barra de estado y la barra de herramientas, pero ¿cómo puedo aplicar el efecto de animación circular (o similar) a ambos a medida que se cambia el color?
Después de una gran cantidad de investigación,
He encontrado una respuesta que te gustaría.
Esta animación se llama animación revelada introducida en la API Android 21.0 - lollipop. Desafortunadamente, no es compatible con versiones anteriores.
He encontrado una biblioteca que muestra la misma animación de revelación pero no exactamente una copia de respaldo, pero el efecto que desea se puede lograr API 14 en adelante con esta biblioteca
https://github.com/markushi/android-ui
Gracias,
Si está interesado en utilizar esta animación solo con lollipop, simplemente busque en google "Implementación de Android Animale Color Animation".
No sé cómo lograron el efecto dominó, pero puede tener una transición de color uniforme de ambas barras simultáneamente con el siguiente código.
private void tintSystemBars() {
// Initial colors of each system bar.
final int statusBarColor = getResources().getColor(R.color.status_bar_color);
final int toolbarColor = getResources().getColor(R.color.toolbar_color);
// Desired final colors of each bar.
final int statusBarToColor = getResources().getColor(R.color.status_bar_to_color);
final int toolbarToColor = getResources().getColor(R.color.toolbar_to_color);
ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// Use animation position to blend colors.
float position = animation.getAnimatedFraction();
// Apply blended color to the status bar.
int blended = blendColors(statusBarColor, statusBarToColor, position);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow.setStatusBarColor(blended);
}
// Apply blended color to the ActionBar.
blended = blendColors(toolbarColor, toolbarToColor, position);
ColorDrawable background = new ColorDrawable(blended);
getSupportActionBar().setBackgroundDrawable(background);
}
});
anim.setDuration(500).start();
}
private int blendColors(int from, int to, float ratio) {
final float inverseRatio = 1f - ratio;
final float r = Color.red(to) * ratio + Color.red(from) * inverseRatio;
final float g = Color.green(to) * ratio + Color.green(from) * inverseRatio;
final float b = Color.blue(to) * ratio + Color.blue(from) * inverseRatio;
return Color.rgb((int) r, (int) g, (int) b);
}
No sé si esta es la forma exacta en que lo hace la aplicación Calendario, pero está lo suficientemente cerca de mí.
Advertencias
- El método utiliza el método
ViewAnimationUtils.createCircularReveal
introducido en Lollipop. - Requiere conocer la altura de la barra de estado y la barra de acciones de la barra de herramientas. Todavía puede usar
?attr/actionBarSize
para su barra de acciones y obtener ambos de forma dinámica, pero para simplificar aquí he asumido56dp
para la altura de la barra de24dp
y24dp
para la altura de la barra de estado.
Idea general
La idea general es establecer la barra de acciones y la barra de estado en transparente. Esto moverá la barra de acciones hacia arriba debajo de la barra de estado, por lo que tendrá que ajustar el tamaño y el relleno de la barra de acciones para compensar. A continuación, utiliza una vista detrás de él y ViewAnimationUtils.createCircularReveal
para revelar el nuevo color de fondo. Necesita una vista más detrás de eso para mostrar el color de fondo anterior, ya que la vista del medio revela el nuevo.
La animación
La animación requiere:
- La barra de acciones de la barra de herramientas transparente que cubre el espacio de la barra de acciones normal y la barra de estado. La altura codificada, en este caso, es 56dp (barra de acciones) + 24dp (barra de estado) = 80dp. También debe establecer el relleno superior en 24dp para mantener el contenido de la barra de acciones debajo de la barra de estado.
- Una vista del medio (la llamaré reveladora ) que tiene el mismo tamaño (80dp de altura) pero justo detrás de la barra de acciones. Esta será la vista en la que actúa
ViewAnimationUtils.createCircularReveal
. - Una vista inferior (la llamaré la vista de fondo de la revelación ) que es del mismo tamaño que la vista de revelar pero detrás de ella. Esta vista está allí para mostrar el color de fondo anterior, mientras que la vista de revelar revela el nuevo color en la parte superior.
Código
Estas son las piezas clave de código que utilicé. Vea el proyecto de ejemplo en https://github.com/shaun-blake-experiments/example-toolbar-animation .
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<View
android:id="@+id/revealBackground"
android:layout_width="match_parent"
android:layout_height="80dp"
android:paddingTop="24dp"
android:background="@color/primary"
android:elevation="4dp">
</View>
<View
android:id="@+id/reveal"
android:layout_width="match_parent"
android:layout_height="80dp"
android:paddingTop="24dp"
android:background="@color/primary"
android:elevation="4dp">
</View>
<Toolbar
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="80dp"
android:paddingTop="24dp"
android:background="@android:color/transparent"
android:elevation="4dp"
android:theme="@style/TranslucentActionBar">
</Toolbar>
<ToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Invert Toolbar Colors"
android:textOn="Invert Toolbar Colors On"
android:textOff="Invert Toolbar Colors Off"
android:id="@+id/toggleButton"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
styles.xml
<resources>
<style name="AppTheme" parent="@android:style/Theme.Material.Light.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
<style name="TranslucentActionBar" parent="@android:style/Widget.Material.ActionBar">
<item name="android:textColorPrimary">@color/primary_text_dark_background</item>
</style>
</resources>
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="primary">#2196F3</color>
<color name="primary_dark">#1976D2</color>
<color name="primary_light">#BBDEFB</color>
<color name="accent">#009688</color>
<color name="primary_text">#DD000000</color>
<color name="primary_text_dark_background">#FFFFFF</color>
<color name="secondary_text">#89000000</color>
<color name="icons">#FFFFFF</color>
<color name="divider">#30000000</color>
</resources>
MainActivity.java
package com.example.android.toolbaranimation;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.widget.ToggleButton;
import android.widget.Toolbar;
public class MainActivity extends Activity {
private View mRevealView;
private View mRevealBackgroundView;
private Toolbar mToolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.appbar);
mToolbar.setTitle(getString(R.string.app_name));
mRevealView = findViewById(R.id.reveal);
mRevealBackgroundView = findViewById(R.id.revealBackground);
ToggleButton toggleButton = (ToggleButton) findViewById(R.id.toggleButton);
toggleButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean on = ((ToggleButton) v).isChecked();
if (on) {
animateAppAndStatusBar(R.color.primary, R.color.accent);
} else {
animateAppAndStatusBar(R.color.accent, R.color.primary);
}
}
});
setActionBar(mToolbar);
}
private void animateAppAndStatusBar(int fromColor, final int toColor) {
Animator animator = ViewAnimationUtils.createCircularReveal(
mRevealView,
mToolbar.getWidth() / 2,
mToolbar.getHeight() / 2, 0,
mToolbar.getWidth() / 2);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mRevealView.setBackgroundColor(getResources().getColor(toColor));
}
});
mRevealBackgroundView.setBackgroundColor(getResources().getColor(fromColor));
animator.setStartDelay(200);
animator.setDuration(125);
animator.start();
mRevealView.setVisibility(View.VISIBLE);
}
}
Notas
- Tenga cuidado con la propiedad
android:elevation
en la barra de herramientas, revele y revele vistas de fondo. Si la elevación es menor en la barra de herramientas, las otras cubrirán los botones y el texto.
Prueba esto, funciona muy bien para mí y tiene el mismo efecto que la aplicación Google Calendar.
private void reveal(CollapsingToolbarLayout toolbarLayout, int colorPrimary, int colorPrimaryDark){
// get the center for the clipping circle
int cx = toolbarLayout.getWidth() / 2;
int cy = toolbarLayout.getHeight() / 2;
// get the final radius for the clipping circle
float finalRadius = (float) Math.hypot(cx, cy);
// create the animator for this view (the start radius is zero)
Animator anim =
ViewAnimationUtils.createCircularReveal(toolbarLayout, cx, cy, 0, finalRadius);
// make the view visible and start the animation
toolbarLayout.setBackgroundColor(colorPrimary);
anim.start();
Window window = getWindow();
window.setStatusBarColor(colorPrimaryDark);
toolbarLayout.setContentScrimColor(colorPrimary);
}