Android CollapsingToolbarLayout与自定义视图

我遵循Cheesesquare示例项目来了解新的devise材料库。

我想知道是否有一种方法来使用自定义视图(如电报)与ImageView,标题和副标题,而不是CollapsingToolbarLayout小部件提供的简单标题。

谢谢。

Solutions Collecting From Web of "Android CollapsingToolbarLayout与自定义视图"

我有同样的问题,花了很多时间试图find一个解决scheme。 我的解决scheme是在CollapsingToolbarLayout Views(ImageView和TextView),然后处理代码中的转换。 这样比从CollapsingToolbarLayout扩展更加灵活和简单。

首先,您需要使用视差属性在CollapsingToolbarLayout添加视图:

  <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 

然后在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. } }); 

不知怎的,默认的offsetChangedListener不能正常工作(你可能还是应该先用默认的侦听器来试试),所以我使用了https://gist.github.com/blipinsk/3f8fb37209de6d3eea99中&#x7684;ControllableAppBarLayout ,并添加了以下内容:

 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); } 

唯一的问题是,您需要为CollapsingToolbarLayout设置app:contentScrim="#00000000" (透明),所以当工具栏被折叠时,您的视图仍然可见。 如果你真的需要折叠背景效果,我相信你可以通过在OffsetChangeListener设置背景ImageView的alpha来“伪造”这个OffsetChangeListener 。 ;)

从小部件本身来看,似乎没有办法直接启用它,就像可以将自定义视图添加到工具栏一样。

然而,你可以尝试做什么,打开CollapsingToolbarLayout.class的来源,并检查如何使用CollapsingTextHelper.class标题集。 您可以尝试通过从CollapsingToolbarLayout扩展来制作自己的小部件。

这些链接可以帮助您创build自定义组件/视图,如果您之前没有创build它们: 自定义视图 , 自定义组件

我还没有尝试过,但实际上我正在考虑尝试实现类似的解决scheme。 到目前为止,我会遵循的步骤:

  1. attrs.xml为字幕设置创build自定义属性
  2. 通过扩展原来的MyCollapsingToolbarLayout创build自己的MyCollapsingToolbarLayout
  3. 确保在构造函数中调用super ,以便原始组件保持不变。
  4. 创build一个subtitleTextHelper通过添加一个新的CollapsingTextHelper到你的组件。
  5. 重写onDraw来实际绘制你的字幕。
  6. 用你的字幕属性更新包含你的CollapingsToolbarLayout的布局(默认样式等,也许是一个固定的字幕文本)。
  7. 在包含CollapsingToolbarActivity中应用更改。 (将CollapsingToolbarlayout转换为MyCollapingsToolbarLayout ,设置字幕,额外的自定义设置等)。
  8. 交叉手指,testing。

现在去看看。

稍微编辑克里斯托弗的答案,以显示如何让您的自定义视图崩溃时不会消失:

首先,您需要使用视差属性在CollapsingToolbarLayout添加视图:

  <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 

而是以编程方式添加自定义视图,并且在折叠时不会消失。 例如,这是一个包含标题和副标题的视图:

  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; }