Android中的扩展和折叠工具栏 [英] Expanding And Collapsing Toolbar In Android

查看:41
本文介绍了Android中的扩展和折叠工具栏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在折叠工具栏的帮助下实现了扩展和折叠工具栏,但是当我的工具栏折叠时我卡住了我想显示不同的工具栏.我已经看到了这么一段代码,但无法找到我的解决方案.我还看到了一位了不起的开发人员的解决方案

这是我已经实现的代码段

activity_collapsing_toolbar.xml

<android.support.design.widget.AppBarLayoutandroid: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.CollapsingToolbarLayoutandroid:id="@+id/collapsing_toolbar"android:layout_width="match_parent"android:layout_height="match_parent"app:contentScrim="?attr/colorPrimary"app:layout_scrollFlags="scroll|exitUntilCollapsed"><相对布局android:layout_width="match_parent"android:layout_height="match_parent"机器人:layout_gravity="中心"android:background="@color/base_color_theme_new"机器人:重力=center_horizo​​ntal"app:layout_collapseMode="视差"><相对布局android:id="@+id/rl_class_image"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="26dp"机器人:重力=中心"><线性布局android:id="@+id/ll_class"android:layout_width="60dp"android:layout_height="60dp"android:background="@drawable/rounded_white_circle"机器人:重力=中心"><图像视图android:id="@+id/iv_class_image"android:layout_width="60dp"android:layout_height="60dp"机器人:layout_gravity="中心"机器人:填充=8dp"android:src="@drawable/class_4"/></LinearLayout></RelativeLayout><文本视图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:textSize="17sp"/><文本视图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:text="20 个视频 | 5 个测试"android:textSize="10sp"/></RelativeLayout><android.support.v7.widget.Toolbarandroid:id="@+id/工具栏"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.NestedScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginLeft="10dp"机器人:layout_marginRight="10dp"android:background="@drawable/rounded_corners_for_list"机器人:fillViewport =真"应用程序:behavior_overlapTop="10dp"app:layout_behavior="@string/appbar_scrolling_view_behavior"><!--<include layout="@layout/activity_chapters"/>--><com.chalklit.widget.NonScrollListViewandroid: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 自动生成的方法存根super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_collapsing_toolbar);最终工具栏工具栏 = (工具栏) findViewById(R.id.toolbar);toolbar.inflateMenu(R.menu.menu_main);setSupportActionBar(工具栏);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));}

解决方案

我已经预先阅读了两个令人惊叹的头像折叠演示示例,其方法不使用自定义 CoordinatorLayoutBehavior

要查看我的示例本机代码: 演示 2

<小时>

我使用来自 AppBarLayoutOnOffsetChangedListener 而不是使用自定义的 CoordinatorLayoutBehavior.

private lateinit var appBarLayout: AppBarLayout覆盖 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 方法中,avatar 在第一个演示中改变了大小并改变了 avatar 的 X、Y 位置转换.

私人乐趣 updateViews(offset: Float) {.../* 折叠头像 img*/ivUserAvatar.apply {什么时候 {偏移>avatarAnimateStartPointY ->{val avatarCollapseAnimateOffset = (offset - avatarAnimateStartPointY) * avatarCollapseAnimationChangeWeightval avatarSize = EXPAND_AVATAR_SIZE - (EXPAND_AVATAR_SIZE - COLLAPSE_IMAGE_SIZE) * avatarCollapseAnimateOffsetthis.layoutParams.also {it.height = Math.round(avatarSize)it.width = Math.round(avatarSize)}invisibleTextViewWorkAround.setTextSize(TypedValue.COMPLEX_UNIT_PX, offset)this.translationX = ((appBarLayout.width - horizo​​ntalToolbarAvatarMargin - avatarSize)/2) * avatarCollapseAnimateOffsetthis.translationY = ((toolbar.height - verticalToolbarAvatarMargin - avatarSize )/2) * avatarCollapseAnimateOffset}否则 ->this.layoutParams.also {如果 (it.height != EXPAND_AVATAR_SIZE.toInt()) {it.height = EXPAND_AVATAR_SIZE.toInt()it.width = EXPAND_AVATAR_SIZE.toInt()this.layoutParams = 它}平移X = 0f}}}}

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

private var avatarAnimateStartPointY: Float = 0F私有 var avatarCollapseAnimationChangeWeight: Float = 0F私有变量 isCalculated = falseprivate var verticalToolbarAvatarMargin =0F...如果(isCalculated.not()){avatarAnimateStartPointY =Math.abs((appBarLayout.height - (EXPAND_AVATAR_SIZE + horizo​​ntalToolbarAvatarMargin))/appBarLayout.totalScrollRange)avatarCollapseAnimationChangeWeight = 1/(1 - avatarAnimateStartPointY)VerticalToolbarAvatarMargin = (toolbar.height - COLLAPSE_IMAGE_SIZE) * 2isCalculated = true}

演示 2

<小时>

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

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

/*折叠/展开的视图尺寸*/val 结果:Pair<Int, Int>= 当{百分比偏移<国外 ->{对(TO_EXPANDED_STATE,cashCollapseState?.second ?:WAIT_FOR_SWITCH)}否则 ->{对(TO_COLLAPSED_STATE,cashCollapseState?.second ?:WAIT_FOR_SWITCH)}}

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

 result.apply {无功翻译Y = 0fvar headContainerHeight = 0fval 翻译X:浮动var currentImageSize = 0什么时候 {cashCollapseState != null &&cashCollapseState != this ->{当(第一次){TO_EXPANDED_STATE ->{translationY = toolbar.height.toFloat()headContainerHeight = appBarLayout.totalScrollRange.toFloat()currentImageSize = EXPAND_AVATAR_SIZE.toInt()/**/titleToolbarText.visibility = View.VISIBLEtitleToolbarTextSingle.visibility = View.INVISIBLEbackground.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)/2headContainerHeight = toolbar.height.toFloat()translationX = appBarLayout.width/2f - COLLAPSE_IMAGE_SIZE/2 - margin * 2/**/ValueAnimator.ofFloat(ivAvatar.translationX, translationX).apply {添加更新监听器 {if (cashCollapseState!!.first == TO_COLLAPSED_STATE) {ivAvatar.translationX = it.animatedValue 作为 Float}}interpolator = AnticipateOvershootInterpolator()开始延迟 = 69持续时间 = 350开始()}...}}ivAvatar.apply {layoutParams.height = currentImageSizelayoutParams.width = currentImageSize}collapsingAvatarContainer.apply {layoutParams.height = headContainerHeight.toInt()this.translationY = translationY请求布局()}/**/cashCollapseState = Pair(第一,切换)}

<小时>

要查看我的示例本机代码:折叠头像工具栏示例"

I am implementing expanding and collapsing toolbar with the help of collapsing toolbar but I am stuck when my toolbar is collapsed I want to show different toolbar. I have seen so piece of code but cannot be able to find my solution. I have also seen the solution of one of the amazing developer https://github.com/saulmm/CoordinatorLayoutExample but cannot be able to find out my solution properly

This is my piece of code which i have implemented

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

解决方案

I have preperead two amaizing avatar collapsing demo samples with approach that doesn’t use a custom CoordinatorLayoutBehavior!

To view my samples native code: "Collapsing Avatar Toolbar Sample"

To read my "Animation Collapsing Toolbar Android" post on Medium.


demo 1 demo 2


Instead of use use a custom CoordinatorLayoutBehavior i use an OnOffsetChangedListener which comes from AppBarLayout.

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

Demo 1


in updateViews method avatar changes the size and changes avatar’s X, Y position translation in first demo.

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

to find avatarAnimateStartPointY and avatarCollapseAnimationChangeWeight (for convert general offset to avatar animate offset):

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
 }

Demo 2


avatar change his size and than animate move to right at one moment with top toolbar text became to show and moving to left.

You need to track states: TO_EXPANDED_STATE changing, TO_COLLAPSED_STATE changing, 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)
                }
            }

Create animation for avatar on state switch change:

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


To view my samples native code: "Collapsing Avatar Toolbar Sample"

这篇关于Android中的扩展和折叠工具栏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆