实现SlidingMenu菜单切换效果

        今天使用自定义ViewGroup实现了一个菜单与主界面切换的效果。

        其实就是继承HorizontalScrollView实现一个自己的SlidingMenuContainer。在其中简单覆写几个View的onMeasure()、onLayout()、onTouchEvent()、onScrollChanged()方法即可。在onScrollChanged()方法中,你自己灵活发挥,肯定还能玩出更多地花样。

工程结构非常简单

 下面贴上核心代码

package com.openld.seniorui.testslidingmenu

import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.ViewGroup
import android.widget.HorizontalScrollView
import android.widget.LinearLayout

/**
 * author: lllddd
 * created on: 2022/6/28 22:01
 * description:自定义菜单布局
 */
class SlidingMenuContainer @JvmOverloads constructor(
    context: Context?,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : HorizontalScrollView(context, attrs, defStyleAttr) {
    private var mScreenWidth: Int

    private var mIsOnce = false

    private lateinit var mMain: ViewGroup

    private lateinit var mMenu: ViewGroup

    private var mMenuWidth: Int = 0

    private val mMenuPaddingRight = 0

    init {
        mScreenWidth = context!!.resources.displayMetrics.widthPixels
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        if (!mIsOnce) {
            val wrapper = getChildAt(0) as LinearLayout

            mMenu = wrapper.getChildAt(0) as LinearLayout
            mMain = wrapper.getChildAt(1) as LinearLayout

            mMenuWidth = mScreenWidth - mMenuPaddingRight

            mMenu.layoutParams.width = mMenuWidth
            mMain.layoutParams.width = mScreenWidth
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        super.onLayout(changed, l, t, r, b)

        if (changed) {
            this.smoothScrollTo(mMenuWidth, 0)
            mIsOnce = true
        }
    }

    private var downX: Float = 0F

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(ev: MotionEvent?): Boolean {
        when (ev?.action) {
            MotionEvent.ACTION_DOWN -> {// 按下
                downX = ev.x
            }
            MotionEvent.ACTION_UP -> {// 抬起
                val offsetX = ev.x - downX
                if (offsetX >= mScreenWidth / 3 && downX <= mScreenWidth / 6) {
                    this.smoothScrollTo(0, 0)
                } else {
                    this.smoothScrollTo(mMenuWidth, 0)
                }
                return true
            }
        }
        return super.onTouchEvent(ev)
    }

    override fun onScrollChanged(l: Int, t: Int, oldl: Int, oldt: Int) {
        super.onScrollChanged(l, t, oldl, oldt)

        // 滚动因子,利用这个因子去做各种变幻的动画效果
        val factor = (1.0F * l / mMenuWidth).toFloat()

//        mMain.scaleX = 0.6F + 0.4F * factor
//        mMain.scaleY = 0.6F + 0.4F * factor
        mMain.alpha = factor

        mMenu.scaleX = 1.0F - 0.4F * factor
        mMenu.scaleY = 1.0F - 0.4F * factor
        mMenu.rotation = -30F * factor
    }
}

package com.openld.seniorui.testslidingmenu

import android.os.Bundle
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.openld.seniorui.R

class TestSlidingMenuActivity : AppCompatActivity() {
    private lateinit var mSlidingMenuContainer: SlidingMenuContainer

    private lateinit var mMenu: LinearLayout

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test_sliding_menu)

        initWidgets()
    }

    private fun initWidgets() {
        mSlidingMenuContainer = findViewById(R.id.sld_menu_container)

        mMenu = findViewById(R.id.menu)

        mMenu.findViewById<TextView>(R.id.txt1).setOnClickListener {
            Toast.makeText(this, "点击了巴旦木", Toast.LENGTH_SHORT).show()
        }

        mMenu.findViewById<TextView>(R.id.txt2).setOnClickListener {
            Toast.makeText(this, "点击了碧根果", Toast.LENGTH_SHORT).show()
        }

        mMenu.findViewById<TextView>(R.id.txt3).setOnClickListener {
            Toast.makeText(this, "点击了饼干", Toast.LENGTH_SHORT).show()
        }

        mMenu.findViewById<TextView>(R.id.txt4).setOnClickListener {
            Toast.makeText(this, "点击了布丁", Toast.LENGTH_SHORT).show()
        }

        mMenu.findViewById<TextView>(R.id.txt5).setOnClickListener {
            Toast.makeText(this, "点击了蚕豆", Toast.LENGTH_SHORT).show()
//        }
        }
    }
}

页面布局activity_test_sliding_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<com.openld.seniorui.testslidingmenu.SlidingMenuContainer 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:id="@+id/sld_menu_container"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:background="@drawable/fruit_image9"
    android:scrollbars="none"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    tools:context=".testslidingmenu.TestSlidingMenuActivity">

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

        <include
            android:id="@+id/menu"
            layout="@layout/sliding_menu" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/white"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:text="这是主界面"
                android:textColor="@color/red"
                android:textSize="48sp"
                android:textStyle="bold"
                tools:ignore="HardcodedText" />
        </LinearLayout>
    </LinearLayout>
</com.openld.seniorui.testslidingmenu.SlidingMenuContainer>

子布局sliding_menu.xml

<?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">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/txt1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawablePadding="30dp"
            android:gravity="center"
            android:text="巴旦木"
            android:textColor="@color/black"
            android:textSize="24sp"
            android:textStyle="bold"
            app:drawableLeftCompat="@drawable/ic_badanmu"
            app:layout_constraintBottom_toTopOf="@id/txt2"
            app:layout_constraintHorizontal_bias="0.2"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_chainStyle="spread"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/txt2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawablePadding="30dp"
            android:gravity="center"
            android:text="碧根果"
            android:textColor="@color/black"
            android:textSize="24sp"
            android:textStyle="bold"
            app:drawableLeftCompat="@drawable/ic_bigenguo"
            app:layout_constraintBottom_toTopOf="@id/txt3"
            app:layout_constraintHorizontal_bias="0.2"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/txt1"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/txt3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawablePadding="30dp"
            android:gravity="center"
            android:text="饼干"
            android:textColor="@color/black"
            android:textSize="24sp"
            android:textStyle="bold"
            app:drawableLeftCompat="@drawable/ic_binggan"
            app:layout_constraintBottom_toTopOf="@id/txt4"
            app:layout_constraintHorizontal_bias="0.2"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/txt2"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/txt4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawablePadding="30dp"
            android:gravity="center"
            android:text="布丁"
            android:textColor="@color/black"
            android:textSize="24sp"
            android:textStyle="bold"
            app:drawableLeftCompat="@drawable/ic_buding"
            app:layout_constraintBottom_toTopOf="@id/txt5"
            app:layout_constraintHorizontal_bias="0.2"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/txt3"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/txt5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawablePadding="30dp"
            android:gravity="center"
            android:text="蚕豆"
            android:textColor="@color/black"
            android:textSize="24sp"
            android:textStyle="bold"
            app:drawableLeftCompat="@drawable/ic_candou"
            app:layout_constraintBottom_toTopOf="@+id/txt6"
            app:layout_constraintHorizontal_bias="0.2"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/txt4"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/txt6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawablePadding="30dp"
            android:gravity="center"
            android:text="蛋糕"
            android:textColor="@color/black"
            android:textSize="24sp"
            android:textStyle="bold"
            app:drawableLeftCompat="@drawable/ic_dangao"
            app:layout_constraintBottom_toTopOf="@+id/txt7"
            app:layout_constraintHorizontal_bias="0.2"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/txt5"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/txt7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawablePadding="30dp"
            android:gravity="center"
            android:text="开心果"
            android:textColor="@color/black"
            android:textSize="24sp"
            android:textStyle="bold"
            app:drawableLeftCompat="@drawable/ic_kaixinguo"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintHorizontal_bias="0.2"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/txt6"
            tools:ignore="HardcodedText" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>

相关用到的图片就不贴了,有兴趣在xml中换成自己的图片即可

完整项目戳这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值