最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android吸頂效果并有著ViewPager左右切換功能

 更新時(shí)間:2024年11月21日 14:20:33   作者:NotesChapter  
文章介紹了如何在Android應(yīng)用中實(shí)現(xiàn)類似美團(tuán)的吸頂效果,并使用ViewPager進(jìn)行左右切換,主要通過(guò)自定義NestedScrollView控件來(lái)解決滑動(dòng)沖突,并使用post方法監(jiān)聽(tīng)布局高度動(dòng)態(tài)調(diào)整NestedScrollView的最大滑動(dòng)距離,感興趣的朋友跟隨小編一起看看吧

老規(guī)矩,先上圖,看看是不是你想要的
美團(tuán):

來(lái)一個(gè)圖形分析
接下來(lái)我要寫(xiě)一個(gè)簡(jiǎn)單示例,先分析一下布局,見(jiàn)下圖,最外層是NestedScrollView,之后嵌套一個(gè)LinearLayout頭部,中間TabLayout選擇器,底部一個(gè)ViewPager ViewPager高度需要?jiǎng)討B(tài)控制,看自己的需求了,如果是美團(tuán)那種效果,就是 ViewPager高度 = NestedScrollView高度 - TabLayout高度

話不多說(shuō),代碼實(shí)現(xiàn)
接下來(lái)我寫(xiě)一個(gè)例子,如果按照普通控件的嵌套方式來(lái)實(shí)現(xiàn),那么肯定存在滑動(dòng)沖突,會(huì)出現(xiàn)RecyclerView先進(jìn)行滑動(dòng)其次才是ScrollView滑動(dòng),那么就需要先重寫(xiě)NestedScrollView控件,用于控制最大的滑動(dòng)距離,當(dāng)達(dá)到最大滑動(dòng)距離,再分發(fā)給RecyclerView滑動(dòng)!

NestedScrollView重寫(xiě)
需要繼承自NestedScrollView并重寫(xiě)onStartNestedScroll和onNestedPreScroll方法,如下

import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.core.view.NestedScrollingParent2
import androidx.core.widget.NestedScrollView
/**
 * @author: shuhuai
 * @desc:
 * @date: 2024/11/20
 * @version:
 * @remark
 */
class CoordinatorScrollview : NestedScrollView, NestedScrollingParent2 {
    private var maxScrollY = 0
    constructor(context: Context?) : super(context!!)
    constructor(context: Context?, attrs: AttributeSet?) : super(
        context!!,
        attrs
    )
    constructor(
        context: Context?,
        attrs: AttributeSet?,
        defStyleAttr: Int
    ) : super(context!!, attrs, defStyleAttr)
    override fun onStartNestedScroll(
        child: View,
        target: View,
        axes: Int,
        type: Int
    ): Boolean {
        return true
    }
    /**
     * 設(shè)置最大滑動(dòng)距離
     *
     * @param maxScrollY 最大滑動(dòng)距離
     */
    fun setMaxScrollY(maxScrollY: Int) {
        this.maxScrollY = maxScrollY
    }
    /**
     * @param target   觸發(fā)嵌套滑動(dòng)的View
     * @param dx       表示 View 本次 x 方向的滾動(dòng)的總距離
     * @param dy       表示 View 本次 y 方向的滾動(dòng)的總距離
     * @param consumed 表示父布局消費(fèi)的水平和垂直距離
     * @param type     觸發(fā)滑動(dòng)事件的類型
     */
    override fun onNestedPreScroll(
        target: View,
        dx: Int,
        dy: Int,
        consumed: IntArray,
        type: Int
    ) {
        if (dy > 0 && scrollY < maxScrollY) {
            scrollBy(0, dy)
            consumed[1] = dy
        }
    }
}

布局文件
我按照美團(tuán)的布局大體寫(xiě)出這樣的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    tools:context=".MainActivity">
    <!--titleBar-->
    <LinearLayout
        android:id="@+id/titleBar"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:paddingLeft="18dp"
        android:paddingRight="18dp">
        <EditText
            android:layout_width="0dp"
            android:layout_height="35dp"
            android:layout_marginEnd="12dp"
            android:layout_marginRight="12dp"
            android:layout_weight="1"
            android:background="@drawable/edit_style"
            android:paddingLeft="12dp"
            android:paddingRight="12dp" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="35dp"
            android:background="@drawable/button_style"
            android:gravity="center"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            android:text="搜索"
            android:textColor="#333333"
            android:textStyle="bold" />
    </LinearLayout>
    <!--coordinatorScrollView-->
    <com.cyn.mt.CoordinatorScrollview
        android:id="@+id/coordinatorScrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <!--相當(dāng)于分析圖中頭部的LinearLayout,模擬動(dòng)態(tài)添加的情況-->
            <LinearLayout
                android:id="@+id/titleLinerLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical" />
            <!--相當(dāng)于分析圖中紅色標(biāo)記處TabLayout-->
            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
            <!--相當(dāng)于分析圖中綠色標(biāo)記處ViewPager,代碼中動(dòng)態(tài)設(shè)置高度-->
            <androidx.viewpager.widget.ViewPager
                android:id="@+id/viewPager"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </com.cyn.mt.CoordinatorScrollview>
</LinearLayout>

Fragment
加入,在Fragment中放入RecyclerView,提供給ViewPager使用,這里代碼就不貼了,可以直接下源碼!源碼在文章末尾!

主要代碼(重點(diǎn)來(lái)了)
coordinatorScrollView最大滑動(dòng)距離即是titleLinerLayout的高度,所以實(shí)現(xiàn)titleLinerLayout的post方法,來(lái)監(jiān)聽(tīng)titleLinerLayout的高度,由于這一塊布局常常是通過(guò)網(wǎng)絡(luò)請(qǐng)求后加載,所以,網(wǎng)絡(luò)請(qǐng)求完畢后要再次實(shí)現(xiàn)post設(shè)置coordinatorScrollView最大滑動(dòng)距離,如第80行代碼和第90行代碼,在這里,我并不推薦使用多次回調(diào)監(jiān)聽(tīng)的方法!使用post只用調(diào)用一次,如果使用多次監(jiān)聽(tīng)View變化的方法,應(yīng)該在最后一次網(wǎng)絡(luò)請(qǐng)求完畢后將此監(jiān)聽(tīng)事件remove掉!

class MainActivity : AppCompatActivity() {
    //屏幕寬
    var screenWidth = 0
    //屏幕高
    var screenHeight = 0
    //tabLayout的文本和圖片
    private val tabTextData = arrayOf("常用藥品", "夜間送藥", "隱形眼鏡", "成人用品", "醫(yī)療器械", "全部商家")
    private val tabIconData = arrayOf(
        R.mipmap.tab_icon,
        R.mipmap.tab_icon,
        R.mipmap.tab_icon,
        R.mipmap.tab_icon,
        R.mipmap.tab_icon,
        R.mipmap.tab_icon
    )
    private var fragmentData = mutableListOf<Fragment>()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initView()
        initData()
    }
    private fun initView() {
        //獲取屏幕寬高
        val resources: Resources = this.resources
        val dm: DisplayMetrics = resources.displayMetrics
        screenWidth = dm.widthPixels
        screenHeight = dm.heightPixels
        //狀態(tài)欄沉浸
        StatusBarUtil.immersive(this)
        //titleBar填充
        StatusBarUtil.setPaddingSmart(this, titleBar)
        //狀態(tài)欄字體顏色設(shè)置為黑色
        StatusBarUtil.darkMode(this)
        //動(dòng)態(tài)設(shè)置ViewPager高度
        coordinatorScrollView.post {
            val layoutParams = viewPager.layoutParams
            layoutParams.width = screenWidth
            layoutParams.height = coordinatorScrollView.height - tabLayout.height
            viewPager.layoutParams = layoutParams
        }
    }
    private fun initData() {
        //我模擬在頭部動(dòng)態(tài)添加三個(gè)布局,就用圖片代替了,要設(shè)置的圖片高度都是我提前算好的,根據(jù)屏幕的比例來(lái)計(jì)算的
        val titleView1 = getTitleView(screenWidth * 0.42F, R.mipmap.title1)
        val titleView2 = getTitleView(screenWidth * 0.262F, R.mipmap.title2)
        titleLinerLayout.addView(titleView1)
        titleLinerLayout.addView(titleView2)
        //設(shè)置最大滑動(dòng)距離
        titleLinerLayout.post {
            coordinatorScrollView.setMaxScrollY(titleLinerLayout.height)
        }
        //用于請(qǐng)求網(wǎng)絡(luò)后動(dòng)態(tài)添加子布局
        Handler().postDelayed({
            val titleView3 = getTitleView(screenWidth * 0.589F, R.mipmap.title3)
            titleLinerLayout.addView(titleView3)
            //再次設(shè)置最大滑動(dòng)距離
            titleLinerLayout.post {
                coordinatorScrollView.setMaxScrollY(titleLinerLayout.height)
            }
        }, 200)
        //添加TabLayout
        for (i in tabTextData.indices) {
            tabLayout.addTab(tabLayout.newTab())
            tabLayout.getTabAt(i)!!.setText(tabTextData[i]).setIcon(tabIconData[i])
            //添加Fragment
            fragmentData.add(TestFragment.newInstance(tabTextData[i]))
        }
        //Fragment ViewPager
        viewPager.adapter = ViewPagerAdapter(supportFragmentManager, fragmentData)
        //TabLayout關(guān)聯(lián)ViewPager
        tabLayout.setupWithViewPager(viewPager)
        //設(shè)置TabLayout數(shù)據(jù)
        for (i in tabTextData.indices) {
            tabLayout.getTabAt(i)!!.setText(tabTextData[i]).setIcon(tabIconData[i])
        }
    }
    /**
     * 獲取一個(gè)title布局
     * 我這里就用三張圖片模擬的
     *
     * @height 要設(shè)置的圖片高度
     */
    private fun getTitleView(height: Float, res: Int): View {
        val inflate = from(this).inflate(R.layout.title_layout, null, false)
        val layoutParams = inflate.titleImage.layoutParams
        layoutParams.width = screenWidth
        layoutParams.height = height.toInt()
        inflate.titleImage.setImageResource(res)
        return inflate
    }
}

最終效果

到此這篇關(guān)于Android吸頂效果,并有著ViewPager左右切換的文章就介紹到這了,更多相關(guān)android ViewPager左右切換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android11文件管理權(quán)限申請(qǐng)?jiān)敿?xì)介紹

    Android11文件管理權(quán)限申請(qǐng)?jiān)敿?xì)介紹

    大家好,本篇文章主要講的是Android11文件管理權(quán)限申請(qǐng)?jiān)敿?xì)介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • Android ListView 單條刷新方法實(shí)踐及原理解析

    Android ListView 單條刷新方法實(shí)踐及原理解析

    這篇文章主要介紹了Android ListView 單條刷新方法實(shí)踐及原理解析的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • Android Listview上下拉動(dòng)刷新tab滑動(dòng)切換功能

    Android Listview上下拉動(dòng)刷新tab滑動(dòng)切換功能

    這篇文章主要介紹了Android Listview上下拉動(dòng)刷新tab滑動(dòng)切換功能的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-04-04
  • 淺談Android invalidate 分析

    淺談Android invalidate 分析

    本篇文章主要介紹了淺談Android invalidate 分析,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • Android實(shí)現(xiàn)單項(xiàng)、多項(xiàng)選擇操作

    Android實(shí)現(xiàn)單項(xiàng)、多項(xiàng)選擇操作

    這篇文章主要介紹了Android實(shí)現(xiàn)單項(xiàng)、多項(xiàng)選擇操作的相關(guān)資料,單項(xiàng)選擇、多項(xiàng)選擇操作在項(xiàng)目開(kāi)發(fā)中經(jīng)常應(yīng)用,感興趣的小伙伴們可以參考一下
    2016-04-04
  • Android WorkManager淺談

    Android WorkManager淺談

    這篇文章主要介紹了Android WorkManager淺談,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • android長(zhǎng)截屏原理及實(shí)現(xiàn)代碼

    android長(zhǎng)截屏原理及實(shí)現(xiàn)代碼

    本篇文章主要介紹了android長(zhǎng)截屏原理及實(shí)現(xiàn)代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • Android ProgressBar進(jìn)度條使用詳解

    Android ProgressBar進(jìn)度條使用詳解

    ProgressBar進(jìn)度條,分為旋轉(zhuǎn)進(jìn)度條和水平進(jìn)度條,進(jìn)度條的樣式根據(jù)需要自定義,這篇文章主要介紹了Android ProgressBar進(jìn)度條使用方法,感興趣的小伙伴們可以參考一下
    2016-02-02
  • RecyclerView中使用CheckBox出現(xiàn)勾選混亂的解決方法

    RecyclerView中使用CheckBox出現(xiàn)勾選混亂的解決方法

    這篇文章主要為大家詳細(xì)介紹了RecyclerView中使用CheckBox出現(xiàn)勾選混亂的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Android仿IOS10圓盤(pán)時(shí)間選擇器

    Android仿IOS10圓盤(pán)時(shí)間選擇器

    這篇文章主要為大家詳細(xì)介紹了Android仿IOS10圓盤(pán)時(shí)間選擇器,自定義圓盤(pán)時(shí)間選擇器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-07-07

最新評(píng)論

军事| 洪洞县| 观塘区| 辽中县| 莲花县| 新宁县| 建始县| 乌兰察布市| 兴业县| 西充县| 河南省| 芮城县| 张掖市| 信宜市| 顺昌县| 江西省| 太白县| 理塘县| 米泉市| 临安市| 蒲江县| 泾阳县| 元朗区| 巴彦淖尔市| 安乡县| 千阳县| 新竹县| 临泉县| 休宁县| 桐庐县| 文登市| 凤庆县| 石阡县| 渑池县| 甘洛县| 三穗县| 乐昌市| 玉溪市| 海宁市| 黄骅市| 贡觉县|