android - collapsible - layout collapsemode parallax
Android CollapsingToolbarLayout con vista personalizada (3)
Estoy siguiendo el proyecto de ejemplo de Cheesesquare para comprender la nueva biblioteca de materiales de diseño.
Me pregunto si hay una manera de usar una vista personalizada (como Telegram) con ImageView, título y subtítulo en lugar del título simple proporcionado por el widget CollapsingToolbarLayout.
Gracias.
Desde el propio widget no parece haber una forma de habilitar esto directamente, como si fuera posible agregar vistas personalizadas a la barra de herramientas.
Sin embargo, lo que podría intentar hacer es abrir la fuente de CollapsingToolbarLayout.class
y ver cómo se usa CollapsingTextHelper.class
para establecer el título. Puedes intentar crear tu propio widget extendiéndolo desde CollapsingToolbarLayout
.
Estos enlaces pueden ayudarlo a crear componentes / vistas personalizados, si no los ha creado antes: Vistas personalizadas , Componentes personalizados
No he intentado esto todavía, pero en realidad es algo que estaba pensando en tratar de lograr una solución similar a la que estás buscando. Pasos que seguí, hasta ahora:
- Cree atributos personalizados para la configuración de subtítulos en
attrs.xml
- Cree su propio
MyCollapsingToolbarLayout
extendiendo el original. - Asegúrese de llamar a
super
en los constructores, por lo que el componente original se mantendrá intacto. - Cree un
subtitleTextHelper
agregando un nuevoCollapsingTextHelper
a su componente. - Sobrescriba
onDraw
para dibujar su subtítulo. - Actualice el diseño que contiene su
CollapingsToolbarLayout
con sus atributos de subtítulos (estilo predeterminado y tal vez, tal vez un texto de subtítulo fijo). - Aplique los cambios en la
Activity
contiene suCollapsingToolbar
. (ConviertaCollapsingToolbarlayout
aMyCollapingsToolbarLayout
, establezca subtítulos, configuraciones personalizadas adicionales, etc.). - Cruzar los dedos, probar.
Voy a echarle un vistazo ahora.
Tuve el mismo problema y pasé muchas horas tratando de encontrar una solución. Mi solución fue agregar las vistas colapsadas (ImageView y TextView) dentro de CollapsingToolbarLayout
y luego manejar la transición en el código. De esta manera es más flexible y simple que extenderse desde CollapsingToolbarLayout.
Primero deberá agregar sus Vistas dentro de CollapsingToolbarLayout
con las propiedades de paralaje:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop:"80dp"
android:src="@drawable/icon"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.8"/> //set vertical transition here
Luego configure la escala de las Vistas con la ayuda de un OnOffsetchangeListner
:
private static final float SCALE_MINIMUM=0.5f;
appBarLayout.setOnWorkingOffsetChange(new ControllableAppBarLayout.OnWorkingOffsetChange() {
@Override
public void onOffsetChange(int offSet, float collapseDistance) {
imageView.setScaleX(1 + (collapseDistance * SCALE_MINIMUM));
imageView.setScaleY(1 + (collapseDistance * SCALE_MINIMUM));
textView.setScaleX(1 + (collapseDistance * SCALE_MINIMUM));
textView.setScaleY(1 + (collapseDistance * SCALE_MINIMUM));
// You can also setTransitionY/X, setAlpha, setColor etc.
}
});
De alguna manera, el offsetChangedListener
predeterminado no funcionó correctamente para mí (probablemente debería intentarlo primero con el oyente predeterminado), así que usé el ControllableAppBarLayout
de https://gist.github.com/blipinsk/3f8fb37209de6d3eea99 y agregue lo siguiente:
private OnWorkingOffsetChange onWorkingOffsetChange;
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
if (!isInEditMode()) {
onWorkingOffsetChange.onOffsetChange(i, (float) i / appBarLayout.getTotalScrollRange());
}
}
public void setOnWorkingOffsetChange(OnWorkingOffsetChange listener) {
this.onWorkingOffsetChange = listener;
}
public interface OnWorkingOffsetChange {
void onOffsetChange(int offSet, float collapseDistance);
}
El único problema es que necesitaría establecer app:contentScrim="#00000000"
(transparente) para su CollapsingToolbarLayout
, por lo que sus vistas aún estarán visibles cuando la barra de herramientas esté contraída. Si realmente necesita el efecto de fondo de colapso, estoy seguro de que podría "falsificar" esto configurando el alfa de un ImageView de fondo en el OffsetChangeListener
;)
Vamos a editar un poco la respuesta de Christopher para mostrar cómo puede hacer que su vista personalizada no desaparezca al colapsar:
Primero deberá agregar sus Vistas dentro de CollapsingToolbarLayout
con las propiedades de paralaje:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop:"80dp"
android:src="@drawable/icon"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.8"/> //set vertical transition here
En su lugar, agregue la vista personalizada programáticamente y no desaparecerá al colapsar. Por ejemplo, aquí hay una vista que contiene un título y un subtítulo:
final FrameLayout frameLayout = new FrameLayout(mActivity);
FrameLayout.LayoutParams frameLayoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT);
frameLayout.setLayoutParams(frameLayoutParams);
// Create new LinearLayout
final LinearLayout linearLayout = new LinearLayout(mActivity);
frameLayoutParams =new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, dpToPixels(78));
frameLayoutParams.gravity = Gravity.BOTTOM;
linearLayout.setLayoutParams(frameLayoutParams);
linearLayout.setOrientation(LinearLayout.VERTICAL);
// Add textviews
final TextView textView1 = new TextView(mActivity);
LinearLayout.LayoutParams linearLayoutParams =new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
frameLayoutParams.gravity = Gravity.BOTTOM;
textView1.setLayoutParams(linearLayoutParams);
textView1.setText("Title");
textView1.setTextColor(ContextCompat.getColor(mActivity, R.color.colorWhite));
textView1.setTextSize(TypedValue.COMPLEX_UNIT_SP, 40);
linearLayout.addView(textView1);
final TextView textView2 = new TextView(mActivity);
linearLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
textView2.setLayoutParams(linearLayoutParams);
textView2.setText("Subtitle");
textView2.setTextColor(ContextCompat.getColor(mActivity, R.color.colorWhite));
textView2.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
linearLayout.addView(textView2);
frameLayout.addView(linearLayout);
collapsingToolbar.addView(frameLayout);
final float SCALE_MIN=0.4f;
AppBarLayout appBarLayout = (AppBarLayout) mActivity.findViewById(R.id.appBarLayout);
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int offSet) {
float collapsedRatio = (float) offSet / appBarLayout.getTotalScrollRange();
linearLayout.setScaleX(1 + (collapsedRatio * SCALE_MIN));
linearLayout.setScaleY(1 + (collapsedRatio * SCALE_MIN));
FrameLayout.LayoutParams frameLayoutParams =new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, dpToPixels(78));
frameLayoutParams.gravity = Gravity.BOTTOM;
frameLayoutParams.setMargins(Math.round(dpToPixels(48) * (1+collapsedRatio)), 0, 0, Math.round(dpToPixels(15) * collapsedRatio));
linearLayout.setLayoutParams(frameLayoutParams);
// You can also setTransitionY/X, setAlpha, setColor etc.
}
});
/////
float lastCollapsedRatio = -2;
////
private int dpToPixels(int padding_in_dp){
final float scale = getResources().getDisplayMetrics().density;
int padding_in_px = (int) (padding_in_dp * scale + 0.5f);
return padding_in_px;
}