弹出menu初步
This commit is contained in:
parent
636375fe15
commit
7459af2f0a
|
|
@ -3,7 +3,9 @@ package com.remax.visualnovel.ui.Chat
|
|||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.Toast
|
||||
import com.dylanc.viewbinding.nonreflection.inflate
|
||||
import com.remax.visualnovel.R
|
||||
import com.remax.visualnovel.databinding.ChatInputpanelBinding
|
||||
|
||||
|
||||
|
|
@ -16,7 +18,24 @@ class InputPanel @JvmOverloads constructor(context: Context, attrs: AttributeSet
|
|||
init {
|
||||
binding = inflate(ChatInputpanelBinding::inflate)
|
||||
binding?.run {
|
||||
|
||||
chatPopMenu.setMenuList(mutableListOf(
|
||||
PopMenuIconView.MenuItem(R.mipmap.ic_launcher) {
|
||||
Toast.makeText(context, "首页", Toast.LENGTH_SHORT).show()
|
||||
},
|
||||
PopMenuIconView.MenuItem(R.mipmap.ic_launcher) {
|
||||
Toast.makeText(context, "设置", Toast.LENGTH_SHORT).show()
|
||||
},
|
||||
PopMenuIconView.MenuItem(R.mipmap.ic_launcher) {
|
||||
Toast.makeText(context, "分享", Toast.LENGTH_SHORT).show()
|
||||
},
|
||||
PopMenuIconView.MenuItem(R.mipmap.ic_launcher) {
|
||||
Toast.makeText(context, "收藏", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
package com.remax.visualnovel.ui.Chat
|
||||
|
||||
|
||||
import android.animation.AnimatorSet
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import com.dylanc.viewbinding.nonreflection.inflate
|
||||
import android.view.View
|
||||
import android.view.animation.DecelerateInterpolator
|
||||
import android.view.animation.OvershootInterpolator
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import com.remax.visualnovel.R
|
||||
import com.remax.visualnovel.databinding.LayoutPopIconMenuViewBinding
|
||||
import com.remax.visualnovel.utils.spannablex.utils.dp
|
||||
|
||||
|
||||
class PopMenuIconView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : FrameLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
data class MenuItem(
|
||||
val iconResId: Int,
|
||||
val onClick: (View) -> Unit
|
||||
)
|
||||
|
||||
private val mMenuItemList = mutableListOf<MenuItem>()
|
||||
private var isMenuShowing = true
|
||||
private var itemSpacing = 0
|
||||
private var itemSize = 0
|
||||
|
||||
|
||||
|
||||
private var mBinding: LayoutPopIconMenuViewBinding? = null
|
||||
init {
|
||||
itemSize = 30.dp
|
||||
itemSpacing = 20.dp
|
||||
mBinding = inflate(LayoutPopIconMenuViewBinding::inflate)
|
||||
mBinding?.run {
|
||||
ivTrigger.setImageResource(R.mipmap.chat_up)
|
||||
ivTrigger.setOnClickListener { toggleMenu() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun setMenuList(menuList : List<MenuItem>) {
|
||||
mMenuItemList.clear()
|
||||
mMenuItemList.addAll(menuList)
|
||||
updateMenuItems()
|
||||
}
|
||||
|
||||
|
||||
private fun updateMenuItems() {
|
||||
mBinding!!.llMenuContainer.removeAllViews()
|
||||
|
||||
mMenuItemList.forEachIndexed { index, menuItem ->
|
||||
ImageView(context).apply {
|
||||
setImageResource(menuItem.iconResId)
|
||||
|
||||
layoutParams = LinearLayout.LayoutParams(itemSize, itemSize).apply {
|
||||
if (index < mMenuItemList.size - 1) {
|
||||
bottomMargin = itemSpacing
|
||||
}
|
||||
}
|
||||
|
||||
setOnClickListener {
|
||||
menuItem.onClick(this)
|
||||
dismissMenu()
|
||||
}
|
||||
|
||||
mBinding!!.llMenuContainer.addView(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun toggleMenu() {
|
||||
if (isMenuShowing) dismissMenu() else showMenu()
|
||||
}
|
||||
|
||||
private fun showMenu() {
|
||||
if (isMenuShowing) return
|
||||
isMenuShowing = true
|
||||
|
||||
mBinding?.run {
|
||||
llMenuContainer.visibility = VISIBLE
|
||||
ivTrigger.setImageResource(R.mipmap.chat_down)
|
||||
|
||||
val maxWidthSpec = MeasureSpec.makeMeasureSpec(Int.MAX_VALUE/2, MeasureSpec.AT_MOST)
|
||||
val heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
|
||||
llMenuContainer.measure(maxWidthSpec, heightSpec)
|
||||
val measureHeight = llMenuContainer.measuredHeight
|
||||
|
||||
val valueYAnim = ValueAnimator.ofInt(0, measureHeight).apply {
|
||||
addUpdateListener {
|
||||
val layoutParam = llMenuContainer.layoutParams
|
||||
layoutParam.height = it.animatedValue as Int
|
||||
llMenuContainer.layoutParams = layoutParam
|
||||
}
|
||||
}
|
||||
|
||||
AnimatorSet().apply {
|
||||
duration = 300
|
||||
interpolator = OvershootInterpolator(2f)
|
||||
playTogether(valueYAnim)
|
||||
start()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun dismissMenu() {
|
||||
if (!isMenuShowing) return
|
||||
isMenuShowing = false
|
||||
mBinding!!.ivTrigger.setImageResource(R.mipmap.chat_up)
|
||||
|
||||
mBinding?.run {
|
||||
val valueYAnim = ValueAnimator.ofInt(llMenuContainer.measuredHeight, 0).apply {
|
||||
addUpdateListener {
|
||||
var layoutParam = llMenuContainer.layoutParams
|
||||
layoutParam.height = it.animatedValue as Int
|
||||
llMenuContainer.layoutParams = layoutParam
|
||||
}
|
||||
start()
|
||||
}
|
||||
|
||||
AnimatorSet().apply {
|
||||
duration = 300
|
||||
interpolator = DecelerateInterpolator()
|
||||
playTogether(valueYAnim)
|
||||
start()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package com.remax.visualnovel.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.PopupWindow
|
||||
import androidx.core.widget.PopupWindowCompat
|
||||
|
||||
|
||||
object PopupUtils {
|
||||
fun showPopup(context: Context, anchorView: View, layoutRes: Int) {
|
||||
val contentView = LayoutInflater.from(context).inflate(layoutRes, null)
|
||||
val popupWindow = PopupWindow(
|
||||
contentView,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
isFocusable = true
|
||||
isOutsideTouchable = true
|
||||
elevation = 10f
|
||||
}
|
||||
|
||||
PopupWindowCompat.setOverlapAnchor(popupWindow, true)
|
||||
PopupWindowCompat.showAsDropDown(popupWindow, anchorView, 0, 0, Gravity.START)
|
||||
}
|
||||
|
||||
fun createPopup(context: Context, layoutRes: Int) : PopupWindow {
|
||||
val contentView = LayoutInflater.from(context).inflate(layoutRes, null)
|
||||
val popupWindow = PopupWindow(
|
||||
contentView,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
isFocusable = true
|
||||
isOutsideTouchable = true
|
||||
elevation = 10f
|
||||
}
|
||||
|
||||
PopupWindowCompat.setOverlapAnchor(popupWindow, true)
|
||||
return popupWindow
|
||||
}
|
||||
|
||||
fun createPopup(context: Context, contentView: View) : PopupWindow {
|
||||
val popupWindow = PopupWindow(
|
||||
contentView,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
isFocusable = true
|
||||
isOutsideTouchable = true
|
||||
elevation = 10f
|
||||
}
|
||||
|
||||
PopupWindowCompat.setOverlapAnchor(popupWindow, true)
|
||||
return popupWindow
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -6,6 +6,14 @@
|
|||
android:layout_height="match_parent"
|
||||
android:background="@mipmap/bg_level_1_page"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_actor_bg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@mipmap/splash_bg"
|
||||
/>
|
||||
|
||||
<com.remax.visualnovel.widget.uitoken.view.UITokenTextView
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
android:padding="@dimen/dp_20" >
|
||||
|
||||
|
||||
<com.remax.visualnovel.widget.uitoken.view.UITokenImageView
|
||||
<!--<com.remax.visualnovel.widget.uitoken.view.UITokenImageView
|
||||
android:id="@+id/chat_expand"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
@ -18,15 +18,21 @@
|
|||
android:padding="@dimen/dp_12"
|
||||
app:radiusToken="@string/radius_pill"
|
||||
app:backgroundColorToken="@string/color_surface_element_normal"
|
||||
/>
|
||||
/>-->
|
||||
|
||||
<com.remax.visualnovel.ui.Chat.PopMenuIconView
|
||||
android:id="@+id/chat_pop_menu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
/>
|
||||
|
||||
<com.remax.visualnovel.widget.uitoken.view.UITokenConstraintLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toEndOf="@id/chat_expand"
|
||||
app:layout_constraintStart_toEndOf="@id/chat_pop_menu"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginStart="@dimen/dp_10"
|
||||
app:radiusToken="@string/radius_40"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_horizontal"
|
||||
app:radiusToken="@string/radius_pill"
|
||||
app:backgroundColorToken="@string/color_surface_element_normal"
|
||||
android:padding="@dimen/dp_14"
|
||||
>
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_menu_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:layout_marginBottom="@dimen/dp_20">
|
||||
</LinearLayout>
|
||||
|
||||
<com.remax.visualnovel.widget.uitoken.view.UITokenImageView
|
||||
android:id="@+id/iv_trigger"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@mipmap/chat_up"
|
||||
/>
|
||||
</com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout>
|
||||
Loading…
Reference in New Issue