Android干货

Android 滑动悬浮置顶指南

2017-02-16  本文已影响548人  欢乐的乐
  1. Android 滑动悬浮置顶效果的新实现 (有完整的xml代码)

  2. Material Design之CoordinatorLayout+AppBarLayout实现上滑隐藏ToolBar (有比较详细的说明xml的属性的意思,同时介绍了TabLayout)

  3. android CoordinatorLayout使用 (详细的说明了CoordinatorLayout使用的例子)

  4. Android CoordinatorLayout + AppBarLayout(向上滚动隐藏指定的View) (就是看它终于明白了,如果想实现滑动悬浮置顶,必须要有CoordinatorLayout + AppBarLayout)

  5. android 控件 NestedScrollView (解释了为什么一定要用NestedScrollView)

我自己的xml代码,加上一些理解后的注释

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:fitsSystemWindows="true">

    <!-- 第一部分:CoordinatorLayout -->
    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ffffff">

        <!-- 第二部分:缩放控件-->
        <android.support.design.widget.AppBarLayout
            android:id="@+id/appBarLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <RelativeLayout
                android:id="@+id/collapsing_tool_bar_test_ctl"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_scrollFlags="scroll">
                <!-- layout_scrollFlags="scroll"  所有想滚动出屏幕的view都需要设置这个flag, 没有设置这个flag的view将被固定在屏幕顶部。-->
                
                <RelativeLayout
                    android:id="@+id/userScroreRe"
                    android:layout_width="match_parent"
                    android:layout_height="240dp"
                    android:background="#f00">

                </RelativeLayout>
            </RelativeLayout>

            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
                <!-- 没有设置的则会停留在顶部 -->

                <RadioGroup
                    android:id="@+id/radioGroup"
                    android:layout_width="fill_parent"
                    android:layout_height="50dip"
                    android:gravity="center"
                    android:orientation="horizontal" />
            </LinearLayout>
        </android.support.design.widget.AppBarLayout>

        <!-- 第三部分:Your Scroll View-->
        <!-- 一开始不明白为什么一定要使用NestedScrollView为什么不用你管ScrollView -->
        <!-- 简单的说,它是专门用于和CoordinatorLayout搭配的达成滑动 -->
        <android.support.v4.widget.NestedScrollView
            android:id="@+id/myMainScrollView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:overScrollMode="always"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">
            <!-- app:layout_behavior="@string/appbar_scrolling_view_behavior"这一句,这句话跟CollapsingToolbarLayout中app:layout_scrollFlags="scroll|exitUntilCollapsed"对应,系统一旦发现NestedScrollView中有那句话,就会检查其他控件,然后如果有上面这句对应的话,那么滑动效果就是可以实现的。-->

            <LinearLayout
                android:id="@+id/mainLinearLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <TextView
                    android:layout_width="50dp"
                    android:layout_height="match_parent"
                    android:layout_gravity="center"
                    android:text="测试gem测试测试测试测试测试测试测试测试测试测测试测试测试测试测试测试测试测试测试测测试测试测试测试测试测试测试测试测试测测试测试测试测试测试测试测试测试测试测测试测试测试测试测试测试测试测试测试测测试测试测试测试测试测试测试测试测试测测试测试测试测试测试测试测试测试测试测测试测试测试测试测试测试测试测试测试测试测试测试"
                    />

                <!--<FrameLayout-->
                <!--android:id="@+id/myFrameContainer"-->
                <!--android:layout_width="match_parent"-->
                <!--android:layout_height="fill_parent"></FrameLayout>-->

            </LinearLayout>

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

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

需要注意的有几点:
1.CollapsingToolbarLayout必须设置app:layout_scrollFlags=”scroll”,他才可以滑动。
2.NestedScrollView必须设置app:layout_behavior这个属性,他们才会联动。
3.NestedScrollView里面如果嵌套listview等可滑动的布局时要重写listview的onmeasures方法(网上一大堆)。


新项目中仿支付宝的浮动效果
计算距离添加淡入淡出效果
滑动卡顿就当recyclerView滑动到第一个的时候打开appBarLayout

fragment_fish.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"
    android:background="@color/white">

    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:id="@+id/abl_bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <android.support.design.widget.CollapsingToolbarLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/top_layout_height"
                    android:background="@color/blue"
                    android:layout_marginTop="@dimen/tool_bar_height"
                    app:layout_collapseMode="parallax"
                    app:layout_collapseParallaxMultiplier="0.7">

                    <LinearLayout
                        android:id="@+id/rl_no_special"
                        android:layout_width="match_parent"
                        android:layout_height="@dimen/top_layout_height"
                        android:orientation="horizontal">

                        <RelativeLayout
                            android:id="@+id/rl_top_fish_info"
                            android:layout_width="0dp"
                            android:layout_weight="1"
                            android:layout_height="match_parent">

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


                                <ImageView
                                    android:id="@+id/iv_top_fish_info"
                                    android:layout_width="@dimen/top_layout_icon_width"
                                    android:layout_height="@dimen/top_layout_icon_width"
                                    android:background="@drawable/top_icon_big_fish"
                                    android:layout_gravity="center_horizontal"
                                    android:clickable="true" />

                                <TextView
                                    android:id="@+id/tv_top_fish_info"
                                    android:layout_width="wrap_content"
                                    android:layout_height="wrap_content"
                                    android:text="鱼塘信息"
                                    android:textColor="@color/white"
                                    android:textSize="@dimen/text_size_middle"
                                    android:layout_gravity="center_horizontal"
                                    android:layout_marginTop="8dp"/>


                            </LinearLayout>

                        </RelativeLayout>

                        <RelativeLayout
                            android:id="@+id/rl_top_device_info"
                            android:layout_width="0dp"
                            android:layout_weight="1"
                            android:layout_height="match_parent">

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


                                <ImageView
                                    android:id="@+id/iv_top_device_info"
                                    android:layout_width="@dimen/top_layout_icon_width"
                                    android:layout_height="@dimen/top_layout_icon_width"
                                    android:background="@drawable/top_icon_device"
                                    android:layout_gravity="center_horizontal"
                                    android:clickable="true"/>

                                <TextView
                                    android:id="@+id/tv_top_device_info"
                                    android:layout_width="wrap_content"
                                    android:layout_height="wrap_content"
                                    android:text="设备信息"
                                    android:textColor="@color/white"
                                    android:textSize="@dimen/text_size_middle"
                                    android:layout_gravity="center_horizontal"
                                    android:layout_marginTop="8dp"/>

                            </LinearLayout>

                        </RelativeLayout>

                        <RelativeLayout
                            android:id="@+id/rl_top_data_list"
                            android:layout_width="0dp"
                            android:layout_weight="1"
                            android:layout_height="match_parent">

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


                                <ImageView
                                    android:id="@+id/iv_top_data_info"
                                    android:layout_width="@dimen/top_layout_icon_width"
                                    android:layout_height="@dimen/top_layout_icon_width"
                                    android:background="@drawable/top_icon_data"
                                    android:layout_gravity="center_horizontal"
                                    android:clickable="true"/>

                                <TextView
                                    android:id="@+id/tv_top_data_info"
                                    android:layout_width="wrap_content"
                                    android:layout_height="wrap_content"
                                    android:text="数据列表"
                                    android:textColor="@color/white"
                                    android:textSize="@dimen/text_size_middle"
                                    android:layout_gravity="center_horizontal"
                                    android:layout_marginTop="8dp"/>


                            </LinearLayout>

                        </RelativeLayout>

                    </LinearLayout>

                    <View
                        android:id="@+id/v_pay_mask"
                        android:layout_width="match_parent"
                        android:layout_height="@dimen/top_layout_height"
                        android:background="@color/transparent" />


                </RelativeLayout>



                <android.support.v7.widget.Toolbar
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/tool_bar_height"
                    app:layout_collapseMode="pin"
                    app:contentInsetLeft="0dp"
                    app:contentInsetStart="0dp">

                    <include
                        android:id="@+id/tl_expand"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        layout="@layout/ele_title_bar"/>

                    <include
                        android:id="@+id/tl_collapse"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        layout="@layout/ele_title_bar_collapse"
                        android:visibility="gone"/>


                </android.support.v7.widget.Toolbar>



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


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



        <com.github.jdsjlzx.recyclerview.LRecyclerView
            android:id="@+id/lv_fish_pond_info"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:overScrollMode="never"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">


        </com.github.jdsjlzx.recyclerview.LRecyclerView>

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



</RelativeLayout>
ele_title_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="@dimen/tool_bar_height"
    android:background="@color/blue">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/tool_bar_title_margin_left"
        android:layout_centerVertical="true"
        android:text="标题"
        android:textColor="@color/white"
        android:textSize="@dimen/text_size_big"/>

    <View
        android:id="@+id/v_expand_mask"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/transparent"/>

</RelativeLayout>
ele_title_bar_collapse.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="@dimen/tool_bar_height"
    android:background="@color/blue">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/iv_top_bar_fish"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:background="@drawable/top_icon_big_fish"
            android:layout_marginLeft="@dimen/tool_bar_title_margin_left"
            android:layout_gravity="center_vertical" />

        <ImageView
            android:id="@+id/iv_top_bar_device"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:background="@drawable/top_icon_device"
            android:layout_marginLeft="@dimen/tool_bar_title_margin_left"
            android:layout_gravity="center_vertical" />

        <ImageView
            android:id="@+id/iv_top_bar_data"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:background="@drawable/top_icon_data"
            android:layout_marginLeft="@dimen/tool_bar_title_margin_left"
            android:layout_gravity="center_vertical" />


    </LinearLayout>

    <View
        android:id="@+id/v_collapse_mask"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/transparent"/>



</RelativeLayout>
FishFragment.kt
package com.example.administrator.tempdemo.fragment

import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.os.Bundle
import android.support.design.widget.AppBarLayout
import android.support.v4.content.ContextCompat
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import com.example.administrator.tempdemo.BaseFragment
import com.example.administrator.tempdemo.R
import com.example.administrator.tempdemo.adapter.FishPondInfoAdapter
import com.example.administrator.tempdemo.model.FishPondInfo
import com.example.administrator.tempdemo.presenter.FishPresenter
import com.example.administrator.tempdemo.view.FishView
import com.github.jdsjlzx.ItemDecoration.DividerDecoration
import com.github.jdsjlzx.recyclerview.LRecyclerViewAdapter
import com.github.jdsjlzx.recyclerview.ProgressStyle
import kotlinx.android.synthetic.main.ele_title_bar.*
import kotlinx.android.synthetic.main.ele_title_bar_collapse.*
import kotlinx.android.synthetic.main.fragment_fish.*
import org.jetbrains.anko.onClick
import org.jetbrains.anko.onTouch
import org.jetbrains.anko.support.v4.find
import org.jetbrains.anko.support.v4.toast

/**
 * Created by Administrator on 2017/6/28.
 */
class FishFragment: BaseFragment(), FishView, AppBarLayout.OnOffsetChangedListener {


    lateinit var fishPresenter: FishPresenter
    lateinit var fishListener: FishListener
    lateinit var fishPondInfoList: MutableList<FishPondInfo>

    lateinit var mFishPondInfoAdapter: FishPondInfoAdapter
    lateinit var mLRecyclerViewAdapter: LRecyclerViewAdapter
    lateinit var layoutManager: LinearLayoutManager

    var mMaskColor: Int = 0

    interface FishListener{

    }

    companion object{
        fun newInstance(): FishFragment{
            return FishFragment()
        }
    }

    override fun onAttach(activity: Activity?) {
        super.onAttach(activity)
        if(activity is FishListener){
            fishListener = activity
        }
    }

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        var view = inflater!!.inflate(R.layout.fragment_fish, null)
        fishPresenter = FishPresenter(this)
        return view
    }

    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView()
        initListener()
        if(savedInstanceState == null){
            this.fishPresenter.loadDataList()
        }
    }

    override fun renderFishPondInfoList(fishPondInfoList: MutableList<FishPondInfo>) {
        if(fishPondInfoList != null){
            mFishPondInfoAdapter.fishPondInfoList = fishPondInfoList
            mLRecyclerViewAdapter.notifyDataSetChanged()
            lv_fish_pond_info.refreshComplete(fishPondInfoList.size)
        }
    }

    fun initView(){
        mFishPondInfoAdapter = FishPondInfoAdapter(context)
        mLRecyclerViewAdapter = LRecyclerViewAdapter(mFishPondInfoAdapter)
        tv_title.text = getString(R.string.main_fish)
        lv_fish_pond_info.adapter = mLRecyclerViewAdapter
        var divider = DividerDecoration.Builder(context)
                .setHeight(R.dimen.fish_pond_info_divider)
                .setColorResource(R.color.white)
                .build()
        lv_fish_pond_info.addItemDecoration(divider)
        layoutManager = LinearLayoutManager(context)
        lv_fish_pond_info.layoutManager = layoutManager
        //RecyclerView添加Header
        var header = LayoutInflater.from(context).inflate(R.layout.item_fish_now_text_view, activity.findViewById(android.R.id.content) as ViewGroup, false)
        mLRecyclerViewAdapter.addHeaderView(header)
        //下拉刷新样式
        lv_fish_pond_info.setRefreshProgressStyle(ProgressStyle.LineSpinFadeLoader);
        lv_fish_pond_info.setArrowImageView(R.drawable.ic_pulltorefresh_arrow);
        //禁止上拉加载
        lv_fish_pond_info.setLoadMoreEnabled(false)

        mMaskColor = ContextCompat.getColor(context, R.color.blue)
        abl_bar.addOnOffsetChangedListener(this)
    }

    fun initListener(){
        rl_top_fish_info.onTouch { _, event ->
            when(event!!.action){
                MotionEvent.ACTION_DOWN -> {
                    iv_top_fish_info.background = ContextCompat.getDrawable(activity, R.drawable.top_icon_big_fish_pressed)
                    tv_top_fish_info.setTextColor(ContextCompat.getColor(activity, R.color.blue_pressed))
                }
                MotionEvent.ACTION_UP -> {
                    iv_top_fish_info.background = ContextCompat.getDrawable(activity, R.drawable.top_icon_big_fish)
                    tv_top_fish_info.setTextColor(ContextCompat.getColor(activity, R.color.white))
                }
                MotionEvent.ACTION_CANCEL -> {
                    iv_top_fish_info.background = ContextCompat.getDrawable(activity, R.drawable.top_icon_big_fish)
                    tv_top_fish_info.setTextColor(ContextCompat.getColor(activity, R.color.white))
                }
            }
            false
        }
        rl_top_device_info.onTouch { _, event ->
            when(event!!.action){
                MotionEvent.ACTION_DOWN -> {
                    iv_top_device_info.background = ContextCompat.getDrawable(activity, R.drawable.top_icon_device_pressed)
                    tv_top_device_info.setTextColor(ContextCompat.getColor(activity, R.color.blue_pressed))
                }
                MotionEvent.ACTION_UP -> {
                    iv_top_device_info.background = ContextCompat.getDrawable(activity, R.drawable.top_icon_device)
                    tv_top_device_info.setTextColor(ContextCompat.getColor(activity, R.color.white))
                }
                MotionEvent.ACTION_CANCEL -> {
                    iv_top_device_info.background = ContextCompat.getDrawable(activity, R.drawable.top_icon_device)
                    tv_top_device_info.setTextColor(ContextCompat.getColor(activity, R.color.white))
                }
            }
            false
        }
        rl_top_data_list.onTouch { _, event ->
            when(event!!.action){
                MotionEvent.ACTION_DOWN -> {
                    iv_top_data_info.background = ContextCompat.getDrawable(activity, R.drawable.top_icon_data_pressed)
                    tv_top_data_info.setTextColor(ContextCompat.getColor(activity, R.color.blue_pressed))
                }
                MotionEvent.ACTION_UP -> {
                    iv_top_data_info.background = ContextCompat.getDrawable(activity, R.drawable.top_icon_data)
                    tv_top_data_info.setTextColor(ContextCompat.getColor(activity, R.color.white))
                }
                MotionEvent.ACTION_CANCEL -> {
                    iv_top_data_info.background = ContextCompat.getDrawable(activity, R.drawable.top_icon_data)
                    tv_top_data_info.setTextColor(ContextCompat.getColor(activity, R.color.white))
                }
            }
            false
        }
        rl_top_fish_info.onClick {
            toast("fish")
        }
        rl_top_device_info.onClick {
            toast("device")
        }
        rl_top_data_list.onClick {
            toast("data")
        }
        //下拉刷新监听
        lv_fish_pond_info.setOnRefreshListener {
            loadDataList()
        }
        //RecyclerView滑动监听
        lv_fish_pond_info.addOnScrollListener(object: RecyclerView.OnScrollListener(){
            override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    var firstVisiblePosition = layoutManager.findFirstCompletelyVisibleItemPosition();
                    if (firstVisiblePosition == 0) {
                        abl_bar.setExpanded(true, true);
                    }
                }
            }
        })
    }

    fun loadDataList(){
        this.fishPresenter.loadDataList()
    }

    override fun showLoading() {
    }

    override fun hideLoading() {
    }

    override fun context(): Context {
        return context.applicationContext
    }

    override fun onOffsetChanged(appBarLayout: AppBarLayout?, verticalOffset: Int) {
        var offset = Math.abs(verticalOffset)
        var total = appBarLayout!!.totalScrollRange
        var alphaIn = offset
        var alphaOut = 0
        if((200 - offset) > 0){
            alphaOut = 200 - offset
        }
        var maskColorIn = Color.argb(alphaIn, Color.red(mMaskColor), Color.green(mMaskColor), Color.blue(mMaskColor))
        var maskColorInDouble = Color.argb(alphaIn*2, Color.red(mMaskColor), Color.green(mMaskColor), Color.blue(mMaskColor))
        var maskColorOut = Color.argb(alphaOut*2, Color.red(mMaskColor), Color.green(mMaskColor), Color.blue(mMaskColor))
        if(offset <= total/2){
            tl_expand.visibility = View.VISIBLE
            tl_collapse.visibility = View.GONE
            v_expand_mask.setBackgroundColor(maskColorInDouble)
        }else{
            tl_expand.visibility = View.GONE
            tl_collapse.visibility = View.VISIBLE
            v_collapse_mask.setBackgroundColor(maskColorOut)
        }
        v_pay_mask.setBackgroundColor(maskColorIn)
    }
}
完美

好好学习,天天向上。<( ̄oo, ̄)/


Potato_zero.jpg
上一篇 下一篇

猜你喜欢

热点阅读