【问题标题】:Expanding And Collapsing Toolbar In AndroidAndroid中的扩展和折叠工具栏
【发布时间】:2017-05-07 16:17:29
【问题描述】:

我在折叠工具栏的帮助下实现了扩展和折叠工具栏,但是当我的工具栏折叠时我被卡住了,我想显示不同的工具栏。我看过这么一段代码,但找不到我的解决方案。 我还看到了一位了不起的开发人员https://github.com/saulmm/CoordinatorLayoutExample 的解决方案,但无法正确找到我的解决方案

这是我实现的一段代码

activity_collapsing_toolbar.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar_layout"
        android:layout_width="match_parent"
        android:layout_height="176dp"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">


            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                android:background="@color/base_color_theme_new"
                android:gravity="center_horizontal"
                app:layout_collapseMode="parallax">

                <RelativeLayout
                    android:id="@+id/rl_class_image"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="26dp"
                    android:gravity="center">

                    <LinearLayout
                        android:id="@+id/ll_class"
                        android:layout_width="60dp"
                        android:layout_height="60dp"
                        android:background="@drawable/rounded_white_circle"
                        android:gravity="center">

                        <ImageView
                            android:id="@+id/iv_class_image"
                            android:layout_width="60dp"
                            android:layout_height="60dp"
                            android:layout_gravity="center"
                            android:padding="8dp"
                            android:src="@drawable/class_4" />
                    </LinearLayout>
                </RelativeLayout>


                <TextView
                    android:id="@+id/tv_class_name"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_below="@id/rl_class_image"
                    android:layout_marginTop="15dp"
                    android:gravity="center"
                    android:text="MATHEMATICS"
                    android:textSize="17sp" />

                <TextView
                    android:id="@+id/tv_videos_test"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_below="@id/tv_class_name"
                    android:layout_marginTop="10dp"
                    android:gravity="center"
                    android:text="20 VIDEOS | 5 TESTS"
                    android:textSize="10sp" />


            </RelativeLayout>

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin" />

        </android.support.design.widget.CollapsingToolbarLayout>

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:background="@drawable/rounded_corners_for_list"
        android:fillViewport="true"

        app:behavior_overlapTop="10dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">


        <!--<include layout="@layout/activity_chapters" />-->
        <com.chalklit.widget.NonScrollListView
            android:id="@+id/lv_modules_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/white"
            android:divider="@null"
            android:scrollbars="none"></com.chalklit.widget.NonScrollListView>


    </android.support.v4.widget.NestedScrollView>

</android.support.design.widget.CoordinatorLayout>

CollapsingToolbarActivity.java

private CollapsingToolbarLayout collapsingToolbarLayout = null;
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);


    setContentView(R.layout.activity_collapsing_toolbar);

    final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    toolbar.inflateMenu(R.menu.menu_main);

    setSupportActionBar(toolbar);
    ActionBar actionBar = getSupportActionBar();
    actionBar.setDisplayHomeAsUpEnabled(true);

    collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
    collapsingToolbarLayout.setTitle(" ");
    collapsingToolbarLayout.setContentScrimColor(getResources().getColor(R.color.base_color_theme_new));
    collapsingToolbarLayout.setStatusBarScrimColor(getResources().getColor(R.color.base_color_theme_new));
}

【问题讨论】:

  • 你有.setTitle(" ");。我假设你想要.setTitle("Mathematics")?否则,是的,您的工具栏是空白的 - 这是您的问题吗?您链接到的示例代码也处理圆形图像...
  • #cricket_007 我无法在工具栏展开时设置标题(“数学”)我想在工具栏折叠时移动数学文本视图
  • 我很困惑问题是什么......这个方法处理标题。 github.com/saulmm/CoordinatorBehaviorExample/blob/master/app/…
  • 你只需将标题设置为 collapsingToolbarLayout.setTitle("YOUR TITLE");当你滚动时,标题会自动移动到工具栏
  • 我希望图像视图应该从右对齐到后退按钮,并且文本视图包含数学应该在工具栏折叠时与图像视图右对齐。我试图执行 CoordinatorBehaviourExample 的代码,但我无法实现我想要的输出.

标签: android android-collapsingtoolbarlayout


【解决方案1】:

我已经使用不使用自定义 CoordinatorLayoutBehavior 的方法预读了两个令人惊叹的 avatar 折叠演示示例!

查看我的示例原生代码:"Collapsing Avatar Toolbar Sample"

阅读我在 Medium 上的 "Animation Collapsing Toolbar Android" 帖子。


演示1 演示2


我没有使用自定义CoordinatorLayoutBehavior,而是使用来自AppBarLayoutOnOffsetChangedListener

private lateinit var appBarLayout: AppBarLayout

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_demo_1)
        ...
        appBarLayout = findViewById(R.id.app_bar_layout)

        /**/
        appBarLayout.addOnOffsetChangedListener(
                AppBarLayout.OnOffsetChangedListener { appBarLayout, i ->
                   ...
                    /**/
                    updateViews(Math.abs(i / appBarLayout.totalScrollRange.toFloat()))
                })
    }

演示1


updateViews方法中头像改变大小,并在第一个演示中改变头像的X、Y位置平移。

private fun updateViews(offset: Float) {

        ...

        /* Collapse avatar img*/
        ivUserAvatar.apply {
            when {
                offset > avatarAnimateStartPointY -> {
                    val avatarCollapseAnimateOffset = (offset - avatarAnimateStartPointY) * avatarCollapseAnimationChangeWeight
                    val avatarSize = EXPAND_AVATAR_SIZE - (EXPAND_AVATAR_SIZE - COLLAPSE_IMAGE_SIZE) * avatarCollapseAnimateOffset
                    this.layoutParams.also {
                        it.height = Math.round(avatarSize)
                        it.width = Math.round(avatarSize)
                    }
                    invisibleTextViewWorkAround.setTextSize(TypedValue.COMPLEX_UNIT_PX, offset)

                    this.translationX = ((appBarLayout.width - horizontalToolbarAvatarMargin - avatarSize) / 2) * avatarCollapseAnimateOffset
                    this.translationY = ((toolbar.height  - verticalToolbarAvatarMargin - avatarSize ) / 2) * avatarCollapseAnimateOffset
                }
                else -> this.layoutParams.also {
                    if (it.height != EXPAND_AVATAR_SIZE.toInt()) {
                        it.height = EXPAND_AVATAR_SIZE.toInt()
                        it.width = EXPAND_AVATAR_SIZE.toInt()
                        this.layoutParams = it
                    }
                    translationX = 0f
                }
            }
        }
    }

查找avatarAnimateStartPointYavatarCollapseAnimationChangeWeight(用于将一般偏移转换为头像动画偏移):

private var avatarAnimateStartPointY: Float = 0F
 private var avatarCollapseAnimationChangeWeight: Float = 0F
 private var isCalculated = false
 private var verticalToolbarAvatarMargin =0F
...
if (isCalculated.not()) {
    avatarAnimateStartPointY = 
                 Math.abs((appBarLayout.height - (EXPAND_AVATAR_SIZE + horizontalToolbarAvatarMargin)) / appBarLayout.totalScrollRange)

    avatarCollapseAnimationChangeWeight = 1 / (1 - avatarAnimateStartPointY)

    verticalToolbarAvatarMargin = (toolbar.height - COLLAPSE_IMAGE_SIZE) * 2
    isCalculated = true
 }

演示 2


头像改变他的大小,然后动画向右移动,顶部工具栏文本变为显示并向左移动。

您需要跟踪状态:TO_EXPANDED_STATE 变化、TO_COLLAPSED_STATE 变化、WAIT_FOR_SWITCH

 /*Collapsed/expended sizes for views*/
            val result: Pair<Int, Int> = when {
                percentOffset < ABROAD -> {
                    Pair(TO_EXPANDED_STATE, cashCollapseState?.second ?: WAIT_FOR_SWITCH)
                }
                else -> {
                    Pair(TO_COLLAPSED_STATE, cashCollapseState?.second ?: WAIT_FOR_SWITCH)
                }
            }

在状态切换时为头像创建动画:

   result.apply {
        var translationY = 0f
        var headContainerHeight = 0f
        val translationX: Float
        var currentImageSize = 0
        when {
            cashCollapseState != null && cashCollapseState != this -> {
                when (first) {
                    TO_EXPANDED_STATE -> {
                        translationY = toolbar.height.toFloat()
                        headContainerHeight = appBarLayout.totalScrollRange.toFloat()
                        currentImageSize = EXPAND_AVATAR_SIZE.toInt()
                        /**/
                        titleToolbarText.visibility = View.VISIBLE
                        titleToolbarTextSingle.visibility = View.INVISIBLE
                        background.setBackgroundColor(ContextCompat.getColor(this@Demo2Activity, R.color.color_transparent))
                        /**/
                        ivAvatar.translationX = 0f
                    }

                    TO_COLLAPSED_STATE -> {
                        background.setBackgroundColor(ContextCompat.getColor(this@Demo2Activity, R.color.colorPrimary))
                        currentImageSize = COLLAPSE_IMAGE_SIZE.toInt()
                        translationY = appBarLayout.totalScrollRange.toFloat() - (toolbar.height - COLLAPSE_IMAGE_SIZE) / 2
                        headContainerHeight = toolbar.height.toFloat()
                        translationX = appBarLayout.width / 2f - COLLAPSE_IMAGE_SIZE / 2 - margin * 2
                        /**/
                        ValueAnimator.ofFloat(ivAvatar.translationX, translationX).apply {
                            addUpdateListener {
                                if (cashCollapseState!!.first == TO_COLLAPSED_STATE) {
                                    ivAvatar.translationX = it.animatedValue as Float
                                }
                            }
                            interpolator = AnticipateOvershootInterpolator()
                            startDelay = 69
                            duration = 350
                            start()
                        }
                       ...
                    }
                }

                ivAvatar.apply {
                    layoutParams.height = currentImageSize
                    layoutParams.width = currentImageSize
                }
                collapsingAvatarContainer.apply {
                    layoutParams.height = headContainerHeight.toInt()
                    this.translationY = translationY
                    requestLayout()
                }
                /**/
                cashCollapseState = Pair(first, SWITCHED)
            }

查看我的示例原生代码:"Collapsing Avatar Toolbar Sample"

【讨论】:

  • 非常好的答案,我真的很喜欢完整 github 示例的答案,因为对于材料设计问题,您可能会错过一个标志并尝试一整天
【解决方案2】:

这是另一种不使用自定义 CoordinatorLayoutBehavior 的方法。

它使用来自AppBarLayoutOnOffsetChangedListener

这是一个sn-p:

class OnOffsetChangedListener implements AppBarLayout.OnOffsetChangedListener {

        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {

            final int scrollRange = appBarLayout.getTotalScrollRange();
            float offsetFactor = (float) (-verticalOffset) / (float) scrollRange;
            ...

这将向您展示如何找到总滚动范围,然后找到总滚动范围与当前滚动位置之间的比率。这就是您需要弄清楚如何缩放和定位工具栏视图的方法。

对于自定义布局(就像我做的那样),您可以覆盖 onAttachedToWindow 并在那里添加监听器:

        // Add an OnOffsetChangedListener if possible
        final ViewParent parent = getParent();
        if (parent instanceof AppBarLayout) {
            if (mOnOffsetChangedListener == null) {
                mOnOffsetChangedListener = new OnOffsetChangedListener();
            }
            ((AppBarLayout) parent).addOnOffsetChangedListener(mOnOffsetChangedListener);
        }

我发现这种方法比创建自定义行为要简单一些。

我在 GitHub 上创建了一个示例项目。该应用程序如下所示:

您可以在https://github.com/klarson2/Collapsing-Image查看整个项目

【讨论】:

  • 太棒了...可以在 youtube 上制作教程视频吗??
【解决方案3】:

你应该添加第 33 行

<?xml version="1.0" encoding="utf-8"?>

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbar_layout"
        android:layout_width="match_parent"
        android:layout_height="192dp"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|snap|exitUntilCollapsed"
            app:title="Collapsing"
            app:toolbarId="@+id/toolbar">
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:src="@drawable/nana"
            app:layout_collapseMode="parallax" />

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin" />

    </com.google.android.material.appbar.CollapsingToolbarLayout>

</com.google.android.material.appbar.AppBarLayout>

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/ax" />

</androidx.core.widget.NestedScrollView>

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:id="@+id/floating_action_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:baselineAlignBottom="false"
    android:clickable="true"
    android:src="@drawable/possetive"
    app:fabSize="normal"
    app:layout_anchor="@id/appbar_layout"
    app:layout_anchorGravity="bottom|right"
    app:rippleColor="#E4D6D6" />


</androidx.coordinatorlayout.widget.CoordinatorLayout>

【讨论】:

    【解决方案4】:

    要实现这一点,我们必须使用 CoordinatorLayout.Behavior 创建自定义行为

    考虑两个核心元素:子元素和依赖关系:

    子元素是增强行为的视图,依赖谁将作为与子元素交互的触发器。在您的要求中,子项是 ImageView,依赖项是 Toolbar,这样,如果 Toolbar 移动,ImageView 也会移动。

    请查看以下链接以获取客户行为工具栏演示

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-28
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      相关资源
      最近更新 更多