今天使用自定义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中换成自己的图片即可