CollapsingToolbarLayout subtítulo

¿Puedo configurar el título de un CollapsingToolbarLayout través del método setTitle ?

¿Hay también una forma de configurar un subtítulo?

Si desea que los subtítulos vayan a la Toolbar de Toolbar cuando el AppBar está completamente contraído, debe crear su CoordinatorLayout.Behaviour personalizado. De esta manera: Guía de Github

Pero si solo desea un texto más pequeño detrás del título cuando se amplíe AppBar , puede probar este diseño:

              

Tenga en cuenta que aquí configuro la altura de AppBar como 300dp y la app:expandedTitleMarginBottom es 160dp por lo que el título no se 160dp y entrará en conflicto con el subtítulo de salida. En este ejemplo, debe establecer CollapsingToolbarTitle dinámicamente en el tiempo de ejecución con collapsingToolbarTitle.setTitle("My Title"); método.

El resultado será algo como esto:

enter image description here

Intenta algo como esto , funciona para mí. He creado ViewBehavior personalizado.

 @Override public boolean layoutDependsOn(CoordinatorLayout parent, HeaderView child, View dependency) { return dependency instanceof AppBarLayout; } @Override public boolean onDependentViewChanged(CoordinatorLayout parent, HeaderView child, View dependency) { shouldInitProperties(child, dependency); int maxScroll = ((AppBarLayout) dependency).getTotalScrollRange(); float percentage = Math.abs(dependency.getY()) / (float) maxScroll; float childPosition = dependency.getHeight() + dependency.getY() - child.getHeight() - (getToolbarHeight() - child.getHeight()) * percentage / 2; childPosition = childPosition - mStartMarginBottom * (1f - percentage); CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams(); lp.leftMargin = (int) (percentage * mEndMargintLeft) + mStartMarginLeft; lp.rightMargin = mMarginRight; child.setLayoutParams(lp); child.setY(childPosition); ... return true; } 

y este mi diseño

            ...     

Diseño de ViewHeader:

        

El soporte de subtítulos en un CollapsingToolbarLayout es una característica que también anhelo, así que creé una biblioteca collapsingtoolbarlayout-subtitle :

enter image description here

Úselo como lo haría en cualquier CollapsingToolbarLayout , simplemente agregue el atributo de subtítulos en él:

          

Aquí está la versión modificada de la implementación de Harco ( esto ) dada anteriormente que también cambiará el tamaño del título a medida que expandimos y colapsamos el diseño.

ViewBehavior.java

 public class ViewBehavior extends CoordinatorLayout.Behavior { private static final float MAX_SCALE = 0.5f; private Context mContext; private int mStartMarginLeft; private int mEndMargintLeft; private int mMarginRight; private int mStartMarginBottom; private boolean isHide; public ViewBehavior(Context context, AttributeSet attrs) { mContext = context; } @Override public boolean layoutDependsOn(CoordinatorLayout parent, HeaderView child, View dependency) { return dependency instanceof AppBarLayout; } @Override public boolean onDependentViewChanged(CoordinatorLayout parent, HeaderView child, View dependency) { shouldInitProperties(child, dependency); int maxScroll = ((AppBarLayout) dependency).getTotalScrollRange(); float percentage = Math.abs(dependency.getY()) / (float) maxScroll; // Set scale for the title float size = ((1 - percentage) * MAX_SCALE) + 1; child.setScaleXTitle(size); child.setScaleYTitle(size); // Set position for the header view float childPosition = dependency.getHeight() + dependency.getY() - child.getHeight() - (getToolbarHeight() - child.getHeight()) * percentage / 2; childPosition = childPosition - mStartMarginBottom * (1f - percentage); CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams(); lp.leftMargin = (int) (percentage * mEndMargintLeft) + mStartMarginLeft; lp.rightMargin = mMarginRight; child.setLayoutParams(lp); child.setY(childPosition); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { if (isHide && percentage < 1) { child.setVisibility(View.VISIBLE); isHide = false; } else if (!isHide && percentage == 1) { child.setVisibility(View.GONE); isHide = true; } } return true; } private void shouldInitProperties(HeaderView child, View dependency) { if (mStartMarginLeft == 0) mStartMarginLeft = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_start_margin_left); if (mEndMargintLeft == 0) mEndMargintLeft = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_end_margin_left); if (mStartMarginBottom == 0) mStartMarginBottom = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_start_margin_bottom); if (mMarginRight == 0) mMarginRight = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_end_margin_right); } public int getToolbarHeight() { int result = 0; TypedValue tv = new TypedValue(); if (mContext.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) { result = TypedValue.complexToDimensionPixelSize(tv.data, mContext.getResources().getDisplayMetrics()); } return result; } } 

HeaderView.java

 public class HeaderView extends LinearLayout { @Bind(R.id.header_view_title) TextView title; @Bind(R.id.header_view_sub_title) TextView subTitle; public HeaderView(Context context) { super(context); } public HeaderView(Context context, AttributeSet attrs) { super(context, attrs); } public HeaderView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public HeaderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override protected void onFinishInflate() { super.onFinishInflate(); ButterKnife.bind(this); } public void bindTo(String title) { bindTo(title, ""); } public void bindTo(String title, String subTitle) { hideOrSetText(this.title, title); hideOrSetText(this.subTitle, subTitle); } private void hideOrSetText(TextView tv, String text) { if (text == null || text.equals("")) tv.setVisibility(GONE); else tv.setText(text); } public void setScaleXTitle(float scaleXTitle) { title.setScaleX(scaleXTitle); title.setPivotX(0); } public void setScaleYTitle(float scaleYTitle) { title.setScaleY(scaleYTitle); title.setPivotY(30); } } 

También tuve el mismo problema. Al final, hice un LinearLayout que contiene el título y el subtítulo, y luego establecí el extendedTitleTextAppearance para que sea transparente, ocultando efectivamente el título de la barra de herramientas cuando se expande el diseño. Al usar este enfoque, la barra de herramientas colapsa sobre LinearLayout y al final solo muestra el título en estado colapsado.

El xml completo está aquí:

                

Asegúrese de que su estilo también amplíe TextAppearance o la aplicación se bloqueará si su biblioteca de soporte de diseño es v22.2.0:

  

Este error parece estar solucionado en v22.2.1 ( https://code.google.com/p/android/issues/detail?id=178674 ):

Aquí está la versión modificada de la implementación de Harco ( esto ) con título y subtítulo establecidos en el centro cuando se gastan.

activity_main.xml

                   

dimens.xml

   16dp 16dp 56dp 14dp 14dp  

header_view.xml

        

HeaderView.java

 public class HeaderView extends RelativeLayout { @Bind(R.id.header_view_title) TextView title; @Bind(R.id.header_view_sub_title) TextView subTitle; Context context; public HeaderView(Context context) { super(context); this.context = context; } public HeaderView(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; } public HeaderView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context = context; } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public HeaderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); this.context = context; } @Override protected void onFinishInflate() { super.onFinishInflate(); ButterKnife.bind(this); } public void bindTo(String title) { bindTo(title, ""); } public void bindTo(String title, String subTitle) { hideOrSetText(this.title, title); hideOrSetText(this.subTitle, subTitle); } private void hideOrSetText(TextView tv, String text) { if (text == null || text.equals("")) tv.setVisibility(GONE); else tv.setText(text); } public void setScaleXTitle(float scaleXTitle) { title.setScaleX(scaleXTitle); title.setPivotX(0); } public void setScaleYTitle(float scaleYTitle) { title.setScaleY(scaleYTitle); title.setPivotY(30); } public TextView getTitle() { return title; } public TextView getSubTitle() { return subTitle; } } 

y ViewBehavior.java

 public class ViewBehavior extends CoordinatorLayout.Behavior { private static final float MAX_SCALE = 0.5f; private Context mContext; private int mStartMarginLeftTitle; private int mStartMarginLeftSubTitle; private int mEndMargintLeft; private int mMarginRight; private int mStartMarginBottom; private boolean isHide; public ViewBehavior(Context context, AttributeSet attrs) { mContext = context; } @Override public boolean layoutDependsOn(CoordinatorLayout parent, HeaderView child, View dependency) { return dependency instanceof AppBarLayout; } @Override public boolean onDependentViewChanged(CoordinatorLayout parent, HeaderView child, View dependency) { shouldInitProperties(child, dependency); int maxScroll = ((AppBarLayout) dependency).getTotalScrollRange(); float percentage = Math.abs(dependency.getY()) / (float) maxScroll; // Set scale for the title float size = ((1 - percentage) * MAX_SCALE) + 1; child.setScaleXTitle(size); child.setScaleYTitle(size); // Set position for the header view float childPosition = dependency.getHeight() + dependency.getY() - child.getHeight() - (getToolbarHeight() - child.getHeight()) * percentage / 2; childPosition = childPosition - mStartMarginBottom * (1f - percentage); child.setY(childPosition); // Set Margin for title RelativeLayout.LayoutParams lpTitle = (RelativeLayout.LayoutParams) child.getTitle().getLayoutParams(); lpTitle.leftMargin = (int) ((mStartMarginLeftTitle) - (percentage * (mStartMarginLeftTitle - mEndMargintLeft))); if (lpTitle.leftMargin < 20) { lpTitle.leftMargin = 20; } lpTitle.rightMargin = mMarginRight; child.getTitle().setLayoutParams(lpTitle); // Set Margin for subtitle RelativeLayout.LayoutParams lpSubTitle = (RelativeLayout.LayoutParams) child.getSubTitle().getLayoutParams(); lpSubTitle.leftMargin = (int) ((mStartMarginLeftSubTitle) - (percentage * (mStartMarginLeftSubTitle - mEndMargintLeft))); if (lpSubTitle.leftMargin < 20) { lpSubTitle.leftMargin = 20; } lpSubTitle.rightMargin = mMarginRight; child.getSubTitle().setLayoutParams(lpSubTitle); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { if (isHide && percentage < 1) { child.setVisibility(View.VISIBLE); isHide = false; } else if (!isHide && percentage == 1) { child.setVisibility(View.GONE); isHide = true; } } return true; } private void shouldInitProperties(HeaderView child, View dependency) { if (mStartMarginLeftTitle == 0) mStartMarginLeftTitle = getStartMarginLeftTitle(child); if (mStartMarginLeftSubTitle == 0) mStartMarginLeftSubTitle = getStartMarginLeftSubTitle(child); if (mEndMargintLeft == 0) mEndMargintLeft = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_end_margin_left); if (mStartMarginBottom == 0) mStartMarginBottom = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_start_margin_bottom); if (mMarginRight == 0) mMarginRight = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_end_margin_right); } public int getStartMarginLeftTitle(HeaderView headerView) { TextView title = headerView.getTitle(); DisplayMetrics displaymetrics = new DisplayMetrics(); WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); windowManager.getDefaultDisplay().getMetrics(displaymetrics); int width = displaymetrics.widthPixels; int stringWidth = getStingWidth(title); int marginLeft = (int) ((width / 2) - ((stringWidth + (stringWidth * MAX_SCALE)) / 2)); return marginLeft; } public int getStartMarginLeftSubTitle(HeaderView headerView) { TextView subTitle = headerView.getSubTitle(); DisplayMetrics displaymetrics = new DisplayMetrics(); WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); windowManager.getDefaultDisplay().getMetrics(displaymetrics); int width = displaymetrics.widthPixels; int stringWidth = getStingWidth(subTitle); int marginLeft = ((width / 2) - (stringWidth / 2)); return marginLeft; } public int getStingWidth(TextView textView) { Rect bounds = new Rect(); Paint textPaint = textView.getPaint(); textPaint.getTextBounds(textView.getText().toString(), 0, textView.getText().toString().length(), bounds); return bounds.width(); } public int getToolbarHeight() { int result = 0; TypedValue tv = new TypedValue(); if (mContext.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) { result = TypedValue.complexToDimensionPixelSize(tv.data, mContext.getResources().getDisplayMetrics()); } return result; } }