当前位置: 首页 > 工具软件 > TitleBar > 使用案例 >

scrollview滑动是titlebar的显示和隐藏效果

阴宏爽
2023-12-01

实现状态栏向上滑动,控制titlebar类似相关的控件隐藏和显示的 修改透明度
主要实现思路
1.主要是通过监听scrllview的滑动scrollY的高度控制titlebar的显示或隐藏以及和状态栏的透明或非透明(沉浸式状态栏效果)
大致思路步骤说明(具体还是看代码)
1初始化状态栏 :initStatusBar()方法
2.设置titlebar的高度 需要处理statusbar的高度 :onAttachedToWindow()方法
3.上滑时第一个控件高度为参照物。根据滑动的高度来确定titlebar的显示和隐藏效果
具体看initListener()方法

class BusinessStudyV2Activity : BaseActivity() {

    private var isBannerNeedAutoMove = true
    private var pageSize = 0

    private lateinit var mLayoutInflater: LayoutInflater

    private var theMaxWidth0: Int = 0
    private var theMaxWidth1: Int = 0
    private var theMaxWidth2: Int = 0

    private var isHavePublicCourse = true

    private val collegeLayoutItems: MutableList<View> = mutableListOf<View>()

    private val colAnchorNameList: MutableList<TextView> = mutableListOf<TextView>()
    private val anchorLinearList: MutableList<LinearLayout> = mutableListOf<LinearLayout>()
    private val anchorParentList: MutableList<View> = mutableListOf<View>()

    private lateinit var requestOptions: RequestOptions

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initStatusBar()
        setContentView(R.layout.activity_buiness_study_v2)
//        setStatusBarColor(R.color.transparent)
        initViews()
        initListener()
        initData(false)
    }

    private fun initStatusBar() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0及以上
            val decorView = window.decorView
            val option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            decorView.systemUiVisibility = option
            window.statusBarColor = Color.TRANSPARENT
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {//4.4到5.0
            val localLayoutParams = window.attributes
            localLayoutParams.flags = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS or localLayoutParams.flags
        }
    }

    private fun initViews() {
        mLayoutInflater = LayoutInflater.from(this)
        //ll_content.orientation = VERTICAL
        refreshLayoutSR.isRefreshing = true

        requestOptions = RequestOptions()
                .centerCrop()
                .optionalCenterCrop()
                .diskCacheStrategy(DiskCacheStrategy.DATA)
    }
    //设置title的位置流出statusBar 的高度
    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        val statusBarHeight = MeasureUtil.getStatusBarHeight(this)
        val margin12dp = MeasureUtil.dip2px(this, 12f)
        business_title.setPadding(0, statusBarHeight, 0, 0)
        ll_cancel.setPadding(0, statusBarHeight + margin12dp, 0, 0)
    }

    private fun initListener() {
        tv_cancel.setOnClickListener { finish() }
        cancelTv.setOnClickListener { finish() }
        refreshLayoutSR.setOnRefreshListener {
            isBannerNeedAutoMove = false
            initData(true)
        }

        //val bannerLocation =  IntArray(2)
        val bannerHeight = resources.getDimension(R.dimen.height_busin_banner)//px
        val businessTitleHeight = MeasureUtil.getMeasuredViewH(business_title) + MeasureUtil.getStatusBarHeight(this)//titlebar的高度+状态栏高度
        val theHeight = bannerHeight - businessTitleHeight//banner高度减去悬浮在上面的tiitlebar和状态栏的高度。businesstitle的高度会遮挡banner所以要减去
        Log.e("TAG","bannerHeight:businessTitleHeight:theHeight = $bannerHeight:$businessTitleHeight:$theHeight")

        colSv.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY ->
            Log.e("TAG","$scrollY:$scrollX")
            if (scrollY >= theHeight) {//滑动的高度>banner实际的显示高度
                business_title.alpha = 1f
                setStatusBarColor(R.color.white)
                business_title.visibility = View.VISIBLE
                tv_cancel.visibility = View.GONE
            } else {
                if (scrollY == 0) {
                    business_title.visibility = View.INVISIBLE
                    tv_cancel.visibility = View.VISIBLE
                } else {
                    business_title.visibility = View.VISIBLE
                    tv_cancel.visibility = View.GONE
                }
                business_title.alpha = scrollY / theHeight  //滑动的高度占 banner实际高度百分比
                setStatusBarColor(R.color.transparent)
            }
        })

        tvMorePublic?.setOnClickListener {
            startActivity<PublicCourseV2Activity>()
        }
    }

    private fun calAnchorLLWidthAndDis() {
        for (count in anchorLinearList.indices) {
            val ll = anchorLinearList[count]
            val llWidth = MeasureUtil.getMeasuredViewW(ll)
            when (count % 3) {
                0 -> {
                    if (llWidth >= theMaxWidth0) {
                        theMaxWidth0 = llWidth
                    }
                }
                1 -> {
                    if (llWidth >= theMaxWidth1) {
                        theMaxWidth1 = llWidth
                    }
                }
                2 -> {
                    if (llWidth >= theMaxWidth2) {
                        theMaxWidth2 = llWidth
                    }
                }
            }
        }

        for (count2 in anchorLinearList.indices) {
            val linearLayout = anchorLinearList[count2]
            val mLayoutParams = LinearLayout.LayoutParams(0,
                    LinearLayout.LayoutParams.WRAP_CONTENT)
            when (count2 % 3) {
                0 -> {
                    mLayoutParams.width = theMaxWidth0
                    linearLayout.layoutParams = mLayoutParams
                }
                1 -> {
                    mLayoutParams.width = theMaxWidth1
                    linearLayout.layoutParams = mLayoutParams
                }
                2 -> {
                    mLayoutParams.width = theMaxWidth2
                    linearLayout.layoutParams = mLayoutParams
                }
            }
        }

        for (view in anchorParentList)
            collegeAnchorFxl.addView(view)
    }

    private fun initCollegeAnchor(school: BusinessStudyBean.School) {
        // 通过代码向FlexboxLayout添加View
        val llAnchorItemLayout = mLayoutInflater.inflate(R.layout.item_college_anchor, null)
        val cLayoutParams = LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT)

        cLayoutParams.width = Math.ceil(((MeasureUtil.getScreenWidth(this)).toDouble() / 3
                - MeasureUtil.dip2px(this, 2f))).toInt()
        llAnchorItemLayout.layoutParams = cLayoutParams

        val llAnchor = llAnchorItemLayout.findViewById<LinearLayout>(R.id.llAnchor)

        val colAnchorName = llAnchorItemLayout.findViewById<TextView>(R.id.colAnchorName)
        colAnchorName.text = school.name
        val colAnchorIcon = llAnchorItemLayout.findViewById<ImageView>(R.id.colAnchorIcon)
        Glide.with(this@BusinessStudyV2Activity)
                .load(school.icon)
                .apply(requestOptions)
                .into(colAnchorIcon)

        colAnchorNameList.add(colAnchorName)
        anchorLinearList.add(llAnchor)

        anchorParentList.add(llAnchorItemLayout)
    }

    private val location = IntArray(2)

    private fun setAnchorClick() {
        val offset2 = MeasureUtil.dip2px(this, resources.getDimension(R.dimen.height_college_div) * 1f)
        val offset = MeasureUtil.getMeasuredViewH(business_title)

        for (count in anchorParentList.indices) {

            val theAnchorTv = colAnchorNameList[count]
            val theParent = anchorParentList[count]

            if (theAnchorTv.text == "公开课") {
                theParent.setOnClickListener { startActivity<PublicCourseV2Activity>() }
                continue
            } else {
                theParent.setOnClickListener {
                    //val item = collegeLayoutItems[count]
//                        item.getLocationOnScreen(location)
//                        colSv.smoothScrollBy(0, location[1] - offset + offset2)
                    if (count < collegesRV?.layoutManager!!.itemCount) {
                        val item = collegesRV?.layoutManager?.findViewByPosition(count)//collegeLayoutItems[count]
                        item?.getLocationOnScreen(location)
                        colSv.smoothScrollBy(0, location[1] - offset + offset2)
                    }
                }
            }
        }
    }

    inner class GlideImageLoader : ImageLoader() {
        override fun displayImage(context: Context, path: Any, imageView: ImageView) {
            Glide.with(context)
                    .load(path)
                    .into(imageView)
        }
    }

    private val bannerImages: MutableList<String> = arrayListOf()
    private val bannerTitles: MutableList<String> = arrayListOf()

    private fun initBanner(banners: List<BusinessStudyBean.Banner>) {
        if (banners.isEmpty()) return
        pageSize = banners.size

        bannerImages.clear()
        bannerTitles.clear()

        for (bannerBean in banners.iterator()) {
            bannerImages.add(bannerBean.path)
            bannerTitles.add(bannerBean.title)
        }

        banner?.setImageLoader(GlideImageLoader())
        //设置图片集合
        banner?.setImages(bannerImages)
        //设置banner动画效果
        //banner?.setBannerAnimation(Transformer.Default)
        //设置标题集合(当banner样式有显示title时)
        banner?.setBannerTitles(bannerTitles)
        //设置自动轮播,默认为true
        //banner?.isAutoPlay(true)
        //设置轮播时间
        //banner?.setDelayTime(5000)
        //设置指示器位置(当banner模式中有指示器时)
        banner?.setIndicatorGravity(BannerConfig.CENTER)
        //banner设置方法全部调用完毕时最后调用
        banner?.start()

        banner?.setOnBannerListener {
            val bean = banners[it]
            when (bean.jump_type) {
                "1" -> {
                    startActivity<CourseListV3Activity>("id" to bean?.course_id.toString(), "fromAudio" to false, "class_id" to 0)
                }
                "2" -> {
                    if (bean.ext== RefuelBagID.toString()){
                        startActivity<RefuelBagDetailsActivity>("plan_id" to bean.ext)
                    }else if(bean.ext== VentureID.toString()){
                        startActivity<VentureCampActivity>("plan_id" to bean.ext)
                    } else{
                        startActivity<CourseSignUpDetailsActivity>("plan_id" to bean.ext)
                    }
                }
                else -> {
                }
            }
        }
    }

    private fun initPublicCourse(datas: List<BusinessStudyBean.Course.Data>) {
        val linearLayoutManager = androidx.recyclerview.widget.LinearLayoutManager(this)
        linearLayoutManager.orientation = androidx.recyclerview.widget.LinearLayoutManager.HORIZONTAL
        publicCollegeRV?.layoutManager = linearLayoutManager
        publicCollegeRV?.adapter = PublicCourseAdapter(this, datas) {
            startActivity<CourseListV3Activity>("id" to it.course_id.toString(), "fromAudio" to false, "class_id" to 0)
        }
    }

    private fun initData(isRefresh: Boolean) {
        refreshLayoutSR?.isRefreshing = true

        httpRequest(apiStores.getBusinessStudy(), { it ->
            if (isRefresh) {
                collegeAnchorFxl.removeAllViews()
                collegeLayoutItems.clear()
                colAnchorNameList.clear()
                anchorLinearList.clear()
                anchorParentList.clear()
            }

            llContent.visibility = View.VISIBLE

            initBanner(it?.banners!!)

            it.schools = it.schools.sortedBy { it.sort }

            for (school in it.schools) {

                initCollegeAnchor(school)

                isHavePublicCourse = school.name == "公开课"
            }

            calAnchorLLWidthAndDis()//此计算须在学院名锚点显示之前

            //下面是开始显示各个学院的标题及其课程列表
//            val clPublicTitle = LayoutInflater.from(this).inflate(R.layout.item_college_title, null)
//
//            clPublicTitle.findViewById<TextView>(R.id.tvMorePublic).setOnClickListener {
//                startActivity<BusinessPublicCourseActivity>()
//            }

            if (isHavePublicCourse) {
                publicCTitle?.visibility = View.VISIBLE
                publicCollegeRV?.visibility = View.VISIBLE
                initPublicCourse(it.course.data)
            } else {
                publicCTitle?.visibility = View.GONE
                publicCollegeRV?.visibility = View.GONE
            }

            it.planBeans = it.planBeans.sortedBy { it.sort }

//            for (indices in it.planBeans.indices) {
//                val bean = it.planBeans[indices]
//            }

            initSpecialCollege(it.planBeans)

//            collegeLayoutItems.add(clPublicTitle)//clPublicTitle必须加在list最后,以使其顺序与anchorList一一对应

            setAnchorClick()
            llLogo.visibility = View.VISIBLE

        }, {
            refreshLayoutSR.isRefreshing = false
        }, {
            refreshLayoutSR.isRefreshing = false
        })
    }

    private fun initSpecialCollege(plans: List<BusinessStudyBean.Plan>) {
        if (collegesRV?.adapter == null) {
            collegesRV?.adapter = CollegesAdapter(this, plans)
        } else {
            collegesRV?.adapter?.notifyDataSetChanged()
        }

//        if (collegesRV?.adapter == null) {
//            collegesRV.adapter = CollegeCourseAdapter(this, planBean.plans) {
//                if (it is BusinessStudyBean.Plan.Plans) {
//                    startActivity<CourseSignUpDetailsActivity>("plan_id" to it.id)
//                }
//            }
//        } else {
//            collegesRV.adapter?.notifyDataSetChanged()
//        }
    }
}

这里是xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/refreshLayoutSR"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/color_F6F6F6"
        android:fitsSystemWindows="false">

        <androidx.core.widget.NestedScrollView
            android:id="@+id/colSv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:overScrollMode="never">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <!--<RelativeLayout-->
                <!--android:layout_width="wrap_content"-->
                <!--android:layout_height="@dimen/height_busin_banner"-->
                <!--android:clipChildren="false">-->

                <!--<android.support.v4.view.ViewPager-->
                <!--android:id="@+id/bBannerVP"-->
                <!--android:layout_width="match_parent"-->
                <!--android:layout_height="match_parent"-->
                <!--android:clipChildren="false" />-->

                <com.youth.banner.Banner
                    android:id="@+id/banner"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/height_busin_banner"
                    android:clipChildren="false"
                    app:banner_default_image="@drawable/icon_defult"
                    app:delay_time="5000"
                    app:image_scale_type="center_crop"
                    app:indicator_drawable_selected="@drawable/shape_indicator_select_banner"
                    app:indicator_drawable_unselected="@drawable/shape_indicator_unselect_banner"
                    app:indicator_height="2dp"
                    app:indicator_margin="5dp"
                    app:indicator_width="30dp" />

                <com.google.android.flexbox.FlexboxLayout
                    android:id="@+id/collegeAnchorFxl"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@color/white"
                    app:dividerDrawableHorizontal="@drawable/shape_divider_flex_hori"
                    app:dividerDrawableVertical="@drawable/shape_divider_flex_vert"
                    app:flexDirection="row"
                    app:flexWrap="wrap"
                    app:showDividerHorizontal="middle"
                    app:showDividerVertical="middle"
                    >

                </com.google.android.flexbox.FlexboxLayout>

                <LinearLayout
                    android:id="@+id/llContent"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@color/white"
                    android:orientation="vertical"
                    android:visibility="gone">

                    <include
                        android:id="@+id/publicCTitle"
                        layout="@layout/item_college_title"
                        android:visibility="gone" />

                    <androidx.recyclerview.widget.RecyclerView
                        android:id="@+id/publicCollegeRV"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:clipToPadding="false"
                        android:nestedScrollingEnabled="true"
                        android:paddingStart="6dp"
                        android:paddingTop="22dp"
                        android:paddingEnd="6dp"
                        android:paddingBottom="22dp"
                        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

                    <androidx.recyclerview.widget.RecyclerView
                        android:id="@+id/collegesRV"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:nestedScrollingEnabled="true"
                        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

                    <!--<LinearLayout-->
                        <!--android:id="@+id/llLogo"-->
                        <!--android:layout_width="match_parent"-->
                        <!--android:layout_height="wrap_content"-->
                        <!--android:layout_gravity="center"-->
                        <!--android:background="@color/white"-->
                        <!--android:gravity="center"-->
                        <!--android:visibility="gone">-->

                        <!--<TextView-->
                            <!--android:layout_width="wrap_content"-->
                            <!--android:layout_height="wrap_content"-->
                            <!--android:drawableStart="@drawable/ic_chh_logo"-->
                            <!--android:gravity="center"-->
                            <!--android:paddingTop="10dp"-->
                            <!--android:paddingBottom="34dp"-->
                            <!--android:text="    |    创造未来,见所未见"-->
                            <!--android:textColor="@color/color_9C9C9C"-->
                            <!--android:textSize="12dp" />-->
                        <ImageView
                            android:id="@+id/llLogo"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="center_horizontal"
                            android:src="@drawable/icon_chh_college"
                            android:layout_marginTop="10dp"
                            android:layout_marginBottom="34dp"
                            />

                    <!--</LinearLayout>-->

                </LinearLayout>

            </LinearLayout>

        </androidx.core.widget.NestedScrollView>

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

    <LinearLayout
        android:id="@+id/business_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:background="@color/white"
        android:clickable="true"
        android:fitsSystemWindows="false"
        android:focusable="true"
        android:orientation="vertical"
        android:paddingTop="0dp"
        android:visibility="gone">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/business_title_se"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingTop="12dp"
            android:paddingBottom="12dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="@string/string_business_study"
                android:textColor="@color/black"
                android:textSize="18dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/cancelTv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:drawableStart="@drawable/toolbar_back"
                android:gravity="center"
                android:paddingStart="20dp"
                android:paddingEnd="20dp"
                android:textColor="#333333"
                android:textSize="16dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

        </androidx.constraintlayout.widget.ConstraintLayout>

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="@color/background_gray1" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/ll_cancel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:animateLayoutChanges="true"
        android:paddingTop="12dp"
        android:paddingBottom="12dp">

        <TextView
            android:id="@+id/tv_cancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="12dp"
            android:layout_marginTop="0dp"
            android:background="@drawable/ic_busi_back"
            android:visibility="visible" />

    </LinearLayout>

</RelativeLayout>
 类似资料: