关联用户滑动
This commit is contained in:
@@ -16,6 +16,7 @@ data class LinkedUser(
|
|||||||
|
|
||||||
class LinkedUserAdapter(
|
class LinkedUserAdapter(
|
||||||
private val deleteText: String,
|
private val deleteText: String,
|
||||||
|
private val isUnlinkMode: Boolean,
|
||||||
private val onItemClick: (LinkedUser, Int) -> Unit,
|
private val onItemClick: (LinkedUser, Int) -> Unit,
|
||||||
private val onDeleteClick: (LinkedUser, Int) -> Unit
|
private val onDeleteClick: (LinkedUser, Int) -> Unit
|
||||||
) : RecyclerView.Adapter<LinkedUserAdapter.LinkedUserViewHolder>() {
|
) : RecyclerView.Adapter<LinkedUserAdapter.LinkedUserViewHolder>() {
|
||||||
@@ -35,6 +36,12 @@ class LinkedUserAdapter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun closeSwipe(position: Int) {
|
||||||
|
if (position in items.indices) {
|
||||||
|
notifyItemChanged(position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LinkedUserViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LinkedUserViewHolder {
|
||||||
val binding = ItemLinkedUserBinding.inflate(
|
val binding = ItemLinkedUserBinding.inflate(
|
||||||
LayoutInflater.from(parent.context),
|
LayoutInflater.from(parent.context),
|
||||||
@@ -56,18 +63,38 @@ class LinkedUserAdapter(
|
|||||||
) : RecyclerView.ViewHolder(binding.root) {
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
fun bind(item: LinkedUser, position: Int) {
|
fun bind(item: LinkedUser, position: Int) {
|
||||||
binding.tvPhone.text ="手机号码:${item.phone}"
|
binding.tvPhone.text = "手机号码:${item.phone}"
|
||||||
binding.tvIdCard.text ="身份证号:${item.idCard}"
|
binding.tvIdCard.text = "身份证号:${item.idCard}"
|
||||||
binding.llContent.translationX = 0f
|
binding.llContent.translationX = 0f
|
||||||
binding.tvUserName.text = item.name
|
binding.tvUserName.text = item.name
|
||||||
binding.tvTime.text = item.time
|
binding.tvTime.text = item.time
|
||||||
//设置删除按钮的文字
|
|
||||||
binding.tvDeleteAction.text = deleteText
|
// MODE_SETTINGS → 显示"解除关联";MODE_PERSONAL → 显示"删除"
|
||||||
binding.llContent.setOnClickListener {
|
if (isUnlinkMode) {
|
||||||
onItemClick(item, position)
|
binding.tvUnlinkAction.visibility = View.VISIBLE
|
||||||
|
binding.tvDeleteAction.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
binding.tvUnlinkAction.visibility = View.GONE
|
||||||
|
binding.tvDeleteAction.visibility = View.VISIBLE
|
||||||
|
binding.tvDeleteAction.text = deleteText
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.llDelete.setOnClickListener {
|
binding.llContent.setOnClickListener {
|
||||||
|
if (binding.llContent.translationX < 0f) {
|
||||||
|
binding.llContent.animate()
|
||||||
|
.translationX(0f)
|
||||||
|
.setDuration(200)
|
||||||
|
.start()
|
||||||
|
} else {
|
||||||
|
onItemClick(item, position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.tvDeleteAction.setOnClickListener {
|
||||||
|
onDeleteClick(item, position)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.tvUnlinkAction.setOnClickListener {
|
||||||
onDeleteClick(item, position)
|
onDeleteClick(item, position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.example.defenseapplication.liveVideo
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.TypedValue
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
@@ -73,8 +73,10 @@ class LinkedUserActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private fun initView() {
|
private fun initView() {
|
||||||
val deleteText = if (mode == MODE_SETTINGS) getString(R.string.unlink) else getString(R.string.delete)
|
val deleteText = if (mode == MODE_SETTINGS) getString(R.string.unlink) else getString(R.string.delete)
|
||||||
|
val isUnlinkMode = mode == MODE_SETTINGS
|
||||||
adapter = LinkedUserAdapter(
|
adapter = LinkedUserAdapter(
|
||||||
deleteText = deleteText,
|
deleteText = deleteText,
|
||||||
|
isUnlinkMode = isUnlinkMode,
|
||||||
onItemClick = { user, position ->
|
onItemClick = { user, position ->
|
||||||
val intent = Intent(this, UserDetailsActivity::class.java).apply {
|
val intent = Intent(this, UserDetailsActivity::class.java).apply {
|
||||||
putExtra("name", user.name)
|
putExtra("name", user.name)
|
||||||
@@ -91,9 +93,14 @@ class LinkedUserActivity : AppCompatActivity() {
|
|||||||
binding.rvLinkedUser.layoutManager = LinearLayoutManager(this)
|
binding.rvLinkedUser.layoutManager = LinearLayoutManager(this)
|
||||||
binding.rvLinkedUser.adapter = adapter
|
binding.rvLinkedUser.adapter = adapter
|
||||||
|
|
||||||
val swipeThreshold = -300f
|
// 根据模式只显示一个按钮,滑动露出完整按钮
|
||||||
|
val swipeThresholdPx = TypedValue.applyDimension(
|
||||||
|
TypedValue.COMPLEX_UNIT_DIP, -100f, resources.displayMetrics
|
||||||
|
)
|
||||||
val heldPositions = mutableMapOf<Int, Boolean>()
|
val heldPositions = mutableMapOf<Int, Boolean>()
|
||||||
|
|
||||||
|
var currentlyHeldPosition: Int = -1
|
||||||
|
|
||||||
val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
|
val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
|
||||||
override fun onMove(
|
override fun onMove(
|
||||||
recyclerView: RecyclerView,
|
recyclerView: RecyclerView,
|
||||||
@@ -117,21 +124,53 @@ class LinkedUserActivity : AppCompatActivity() {
|
|||||||
val contentLayout = viewHolder.getContentLayout()
|
val contentLayout = viewHolder.getContentLayout()
|
||||||
val position = viewHolder.adapterPosition
|
val position = viewHolder.adapterPosition
|
||||||
|
|
||||||
|
// 如果当前滑动的位置和已展开的位置不同,先收起已展开的项
|
||||||
|
if (isCurrentlyActive && currentlyHeldPosition != -1 && currentlyHeldPosition != position) {
|
||||||
|
val oldViewHolder = recyclerView.findViewHolderForAdapterPosition(currentlyHeldPosition)
|
||||||
|
if (oldViewHolder is LinkedUserAdapter.LinkedUserViewHolder) {
|
||||||
|
oldViewHolder.getContentLayout().animate()
|
||||||
|
.translationX(0f)
|
||||||
|
.setDuration(200)
|
||||||
|
.start()
|
||||||
|
}
|
||||||
|
heldPositions.remove(currentlyHeldPosition)
|
||||||
|
currentlyHeldPosition = -1
|
||||||
|
}
|
||||||
|
|
||||||
if (isCurrentlyActive) {
|
if (isCurrentlyActive) {
|
||||||
val swipeDistance = if (dX < swipeThreshold) swipeThreshold else dX
|
val isHeld = heldPositions[position]
|
||||||
contentLayout.translationX = swipeDistance
|
if (isHeld == true) {
|
||||||
|
if (dX > 0) {
|
||||||
|
// 已展开时向右滑动 → 平滑收回
|
||||||
|
val newX = swipeThresholdPx + dX
|
||||||
|
// 不能超过原位
|
||||||
|
contentLayout.translationX = if (newX > 0) 0f else newX
|
||||||
|
} else {
|
||||||
|
// 保持展开或继续左滑(限制不超过阈值)
|
||||||
|
contentLayout.translationX = swipeThresholdPx
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 未展开,正常滑动限制(左滑不超过阈值,右滑不超过原位)
|
||||||
|
val swipeDistance = when {
|
||||||
|
dX < swipeThresholdPx -> swipeThresholdPx
|
||||||
|
dX > 0 -> 0f
|
||||||
|
else -> dX
|
||||||
|
}
|
||||||
|
contentLayout.translationX = swipeDistance
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
val isHeld = heldPositions[position]
|
val isHeld = heldPositions[position]
|
||||||
if (isHeld == true) {
|
if (isHeld == true) {
|
||||||
contentLayout.translationX = swipeThreshold
|
contentLayout.translationX = swipeThresholdPx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
- 滑动超过一半后松手:列表项 保持在滑动位置 ,显示"解除关联"按钮
|
- 滑动超过一半后松手:列表项 保持在滑动位置,显示按钮
|
||||||
- 滑动未超过一半松手:列表项 恢复原位
|
- 滑动未超过一半松手:列表项 恢复原位
|
||||||
|
- 已展开状态下向右拖动归位或拖动超过一半松手:恢复原位
|
||||||
* */
|
* */
|
||||||
override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
|
override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
|
||||||
super.clearView(recyclerView, viewHolder)
|
super.clearView(recyclerView, viewHolder)
|
||||||
@@ -139,11 +178,16 @@ class LinkedUserActivity : AppCompatActivity() {
|
|||||||
val position = viewHolder.adapterPosition
|
val position = viewHolder.adapterPosition
|
||||||
val contentLayout = viewHolder.getContentLayout()
|
val contentLayout = viewHolder.getContentLayout()
|
||||||
|
|
||||||
if (contentLayout.translationX < swipeThreshold / 2) {
|
// 判断滑动距离是否超过一半阈值(注意都是负数,所以绝对值比较)
|
||||||
|
if (Math.abs(contentLayout.translationX) > Math.abs(swipeThresholdPx / 2)) {
|
||||||
heldPositions[position] = true
|
heldPositions[position] = true
|
||||||
contentLayout.translationX = swipeThreshold
|
currentlyHeldPosition = position
|
||||||
|
contentLayout.translationX = swipeThresholdPx
|
||||||
} else {
|
} else {
|
||||||
heldPositions.remove(position)
|
heldPositions.remove(position)
|
||||||
|
if (currentlyHeldPosition == position) {
|
||||||
|
currentlyHeldPosition = -1
|
||||||
|
}
|
||||||
contentLayout.animate()
|
contentLayout.animate()
|
||||||
.translationX(0f)
|
.translationX(0f)
|
||||||
.setDuration(300)
|
.setDuration(300)
|
||||||
|
|||||||
@@ -1,40 +1,48 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<!-- 背景删除按钮 -->
|
<!-- 背景按钮层:删除 + 解除关联 两个按钮 -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/llDelete"
|
android:id="@+id/llActions"
|
||||||
android:layout_width="100dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="120dp"
|
android:layout_height="120dp"
|
||||||
android:background="@color/red"
|
android:gravity="end"
|
||||||
android:gravity="center"
|
android:orientation="horizontal">
|
||||||
android:orientation="vertical"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvDeleteAction"
|
android:id="@+id/tvDeleteAction"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="100dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/red"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/delete"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvUnlinkAction"
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/red"
|
||||||
|
android:gravity="center"
|
||||||
android:text="@string/unlink"
|
android:text="@string/unlink"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold"/>
|
android:textStyle="bold" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<!-- 前景内容 -->
|
<!-- 前景内容层:随 swipe 移动 -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/llContent"
|
android:id="@+id/llContent"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="120dp"
|
android:layout_height="120dp"
|
||||||
android:background="@color/white"
|
android:background="@color/white"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="16dp"
|
android:padding="16dp">
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -48,31 +56,31 @@
|
|||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:textColor="@color/black"
|
android:textColor="@color/black"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold"/>
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvTime"
|
android:id="@+id/tvTime"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="@color/gray"
|
android:textColor="@color/gray"
|
||||||
android:textSize="12sp"/>
|
android:textSize="12sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvPhone"
|
android:id="@+id/tvPhone"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
android:textColor="@color/gray"
|
android:textColor="@color/gray"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp" />
|
||||||
android:layout_marginTop="8dp"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvIdCard"
|
android:id="@+id/tvIdCard"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
android:textColor="@color/gray"
|
android:textColor="@color/gray"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp" />
|
||||||
android:layout_marginTop="4dp"/>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</FrameLayout>
|
||||||
|
|||||||
Reference in New Issue
Block a user