Странная проблема с менеджером Madeout Recyclerview по -прежнему обрабатывает свои взгляды на ребенка после удаления преAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Странная проблема с менеджером Madeout Recyclerview по -прежнему обрабатывает свои взгляды на ребенка после удаления пре

Сообщение Anonymous »

Я экспериментирую с функциональностью с участием экрана, который имеет рециклирование, расположенное внизу. < /p>
xml: < /p>
Пользователь может перетащить элемент из повторного обзора и повторно его в RELATIVERAUT. Как правило, это работает правильно. Однако, если пользователь быстро перетаскивает и бросает элемент на экран, происходит сбой из -за того, что, по -видимому, является внутренней проблемой переработки. В настоящее время я не уверен, как решить эту проблему. Другими словами, представление удаляется из адаптера (и его параметры макета изменились) до того, как переработка завершит свои внутренние обновления, что приводит к неверному составу.

Код: Выделить всё

import android.annotation.SuppressLint
import android.graphics.Canvas
import android.graphics.Point
import android.os.Bundle
import android.view.DragEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlin.math.abs

class MainActivity4 : AppCompatActivity() {
private lateinit var parentLayout: RelativeLayout
private lateinit var recyclerView: RecyclerView
private lateinit var adapter: DraggableAdapter
private var removalTriggered = false

private var parentLeft = 0
private var parentTop = 0
private var recyclerLeft = 0
private var recyclerTop = 0

@SuppressLint("ClickableViewAccessibility")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main4)

parentLayout = findViewById(R.id.parent_layout)
recyclerView = findViewById(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)

adapter = DraggableAdapter(removed = {
removalTriggered = false
})

recyclerView.adapter = adapter

// Get parent's location on screen.
val parentLoc = IntArray(2)
parentLayout.getLocationOnScreen(parentLoc)
parentLeft = parentLoc[0]
parentTop = parentLoc[1]

// Get recyclerView's location on screen.
val recLoc = IntArray(2)
recyclerView.getLocationOnScreen(recLoc)
recyclerLeft = recLoc[0]
recyclerTop = recLoc[1]

parentLayout.setOnDragListener { view, event ->
when (event.action) {
DragEvent.ACTION_DRAG_STARTED -> true

DragEvent.ACTION_DRAG_ENTERED -> {
view.invalidate()
true
}

DragEvent.ACTION_DRAG_LOCATION -> true

DragEvent.ACTION_DROP -> {
// Retrieve the original view from localState.
val draggedView = event.localState as? View

draggedView?.let { view ->
// Remove the view from its old parent.
(view.parent as? ViewGroup)?.removeView(view)

// Retrieve the stored initial touch offset from the view's tag.
@Suppress("UNCHECKED_CAST")
val initialTouch = view.getTag(R.id.initial_touch_point) as? Pair
// Use the stored touch offsets, defaulting to the center if not available.
val touchOffsetX = initialTouch?.first ?: (view.width / 2)
val touchOffsetY = initialTouch?.second ?: (view.height / 2)

// Calculate new position based on the drop coordinates and the initial touch offsets.
// event.x and event.y are assumed to be in the coordinate space of the parent layout.
var newX = event.x - touchOffsetX
var newY = event.y - touchOffsetY

// Optionally, clamp the new position so the view stays within the parent's bounds.
newX = newX.coerceIn(0f, (parentLayout.width - view.width).toFloat())
newY = newY.coerceIn(0f, (parentLayout.height - view.height).toFloat())

view.x = newX
view.y = newY

// Update layout parameters if needed.
view.layoutParams = RelativeLayout.LayoutParams(view.width, view.height)
parentLayout.addView(view)
view.visibility = View.VISIBLE
view.bringToFront()
}

true
}

DragEvent.ACTION_DRAG_ENDED ->  {
view.invalidate()
true
}

else -> false
}
}

var itemTouchHelper: ItemTouchHelper? = null

val swipeCallback: ItemTouchHelper.SimpleCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.UP) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean = false

override fun getSwipeThreshold(viewHolder: RecyclerView.ViewHolder): Float {
return 1f
}

override fun onChildDraw(
c: Canvas,
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
dX: Float,
dY: Float,
actionState: Int,
isCurrentlyActive: Boolean
) {
// Let the default implementation update the translation.
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)

// Define a removal threshold: 80% of the item's height.
val removalThreshold = viewHolder.itemView.height * 0.8f

// Get the current vertical translation.
val currentTranslationY = viewHolder.itemView.translationY

// If the view's vertical translation meets/exceeds the threshold, trigger removal.
if (abs(currentTranslationY) >= removalThreshold && !removalTriggered && isCurrentlyActive) {
removalTriggered = true

recyclerView.post {
onSwiped(viewHolder = viewHolder, direction = ItemTouchHelper.UP)
}
}
}

override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val view: View = viewHolder.itemView
val position: Int = viewHolder.bindingAdapterPosition

if (position != RecyclerView.NO_POSITION) {
adapter.removeItem(position)
view.visibility = View.INVISIBLE
}

val shadowBuilder = MyDragShadowBuilder(view = view)
view.startDragAndDrop(null, shadowBuilder, view, 0)
}
}

itemTouchHelper = ItemTouchHelper(swipeCallback)
itemTouchHelper.attachToRecyclerView(recyclerView)
}
}

private class MyDragShadowBuilder(view: View) : View.DragShadowBuilder(view) {
override fun onProvideShadowMetrics(shadowSize: Point, shadowTouchPoint: Point) {
val width = view.width
val height = view.height
shadowSize.set(width, height)
val clampedX = width / 2
val clampedY = height / 2
shadowTouchPoint.set(clampedX, clampedY)
}

override fun onDrawShadow(canvas: Canvas) {
view.draw(canvas)
}
}

class DraggableAdapter(
val removed: () -> Unit
) : RecyclerView.Adapter() {

// Use a mutable list so we can remove items.
private val items: MutableList  = mutableListOf()

init {
for (i in 0 until 10) {
items.add("Drag me $i")
}
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DraggableViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_draggable, parent, false) as TextView
return DraggableViewHolder(view)
}

override fun getItemCount(): Int = items.size

override fun onBindViewHolder(holder: DraggableViewHolder, position: Int) {
holder.textView.text = items[position]
}

fun removeItem(position: Int) {
if (position in 0 until items.size) {
items.removeAt(position)
notifyItemRemoved(position)
}

removed()
}

class DraggableViewHolder(val textView: TextView) : RecyclerView.ViewHolder(textView)
}
< /code>
ошибка: < /p>
FATAL EXCEPTION: main (Ask Gemini)
Process: com.dragndrop, PID: 12824
java.lang.ClassCastException:  a n d r o i d . w i d g e t . R e l a t i v e L a y o u t $ L a y o u t P a r a m s   c a n n o t   b e   c a s t   t o   a n d r o i d x . r e c y c l e r v i e w . w i d g e t . R e c y c l e r V i e w $ L a y o u t P a r a m s < b r   / >                                         a t androidx.recyclerview.widget.RecyclerView.getChildViewHolderInt(RecyclerView.java:5422)
at androidx.recyclerview.widget.RecyclerView$6.getChildViewHolder(RecyclerView.java:1043)
at androidx.recyclerview.widget.ChildHelper.findHiddenNonRemovedView(ChildHelper.java:257)
at androidx.recyclerview.widget.RecyclerView$Recycler.getScrapOrHiddenOrCachedHolderForPosition(RecyclerView.java:7409)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6890)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6853)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6849)
at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2422)
at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1722)
at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1682)
at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:747)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4737)
at androidx.recyclerview.widget.RecyclerView.onMeasure(RecyclerView.java:4133)
at android.view.View.measure(View.java:27853)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:735)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:481)
at android.view.View.measure(View.java:27853)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7403)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:141)
at android.view.View.measure(View.java:27853)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7403)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
at android.view.View.measure(View.java:27853)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7403)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:27853)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7403)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
at android.view.View.measure(View.java:27853)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7403)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:1390)
at android.view.View.measure(View.java:27853)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:4882)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:3461)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3767)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:3151)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:11068)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1321)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1329)
at android.view.Choreographer.doCallbacks(Choreographer.java:930)
at android.view.Choreographer.doFrame(Choreographer.java:859)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1303)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
Пожалуйста, дайте мне знать, если есть какие -либо идеи о возможных решениях здесь

Подробнее здесь: https://stackoverflow.com/questions/795 ... hild-views
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»