0

Who can help me on this wired exception? Feel I AM CRASHING. When I just add masters beans or remove it, or drag on it. After that, commit and notifyDataSetChange(), crash happened. It's very wired. Because when I debug on it. I found the if case is false. The program should not enter the throw cause. It 's very terrible for my debugging. I give up and hope to find some help here. Thanks a lot!

enter image description here

Here below is my code: Using

implementation ('com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.11.0@aar'){
    transitive=true
}


/**
 * Created by chenshusheng on 2018/2/27.
 */
class SelectedMastersNewAdapter(val mContext: Context, val recyclerView: RecyclerView,val data: MutableList<Master>, val listener: RefreshNotificationListener<Master>)
    : RecyclerView.Adapter<RecyclerView.ViewHolder>(), DraggableItemAdapter<RecyclerView.ViewHolder>{
    private var mItemMoveMode = RecyclerViewDragDropManager.ITEM_MOVE_MODE_DEFAULT
    private val HEIGHT: Int = 64

    var isEditable = false

    enum class ITEM_TYPE {
        ITEM_TYPE_MASTER,
        ITEM_TYPE_MASTER_FRAME
    }

    init {
        setHasStableIds(true)
    }

    override fun onCheckCanStartDrag(holder: RecyclerView.ViewHolder?, position: Int, x: Int, y: Int): Boolean {

        return if (isEditable) {
            getItemViewType(position) == ITEM_TYPE.ITEM_TYPE_MASTER.ordinal//To change body of created functions use File | Settings | File Templates.
        }else false
    }

    override fun onCheckCanDrop(draggingPosition: Int, dropPosition: Int): Boolean {
        return getItemViewType(draggingPosition) == ITEM_TYPE.ITEM_TYPE_MASTER.ordinal
            && getItemViewType(dropPosition) == ITEM_TYPE.ITEM_TYPE_MASTER.ordinal //To change body of created functions use File | Settings | File Templates.
    }

    override fun onGetItemDraggableRange(holder: RecyclerView.ViewHolder?, position: Int): ItemDraggableRange? {
        return if (isEditable) {
            ItemDraggableRange(0, itemCount - 2) //To change body of created functions use File | Settings | File Templates.
        }else{
            null
        }
    }

    override fun onItemDragStarted(position: Int) {
        notifyDataSetChanged() //To change body of created functions use File | Settings | File Templates.
    }

    override fun onItemDragFinished(fromPosition: Int, toPosition: Int, result: Boolean) {
        notifyDataSetChanged() //To change body of created functions use File | Settings | File Templates.
    }

    override fun onMoveItem(fromPosition: Int, toPosition: Int) {
        Log.d(TAG, "onMoveItem(fromPosition = $fromPosition, toPosition = $toPosition)");

        if (mItemMoveMode == RecyclerViewDragDropManager.ITEM_MOVE_MODE_DEFAULT) {
            data.add(toPosition, data.removeAt(fromPosition))
        } else {
            Collections.swap(data, toPosition, fromPosition)
        } //To change body of created functions use File | Settings | File Templates.
    }

    fun setItemMoveMode(itemMoveMode: Int) {
        mItemMoveMode = itemMoveMode
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        if (viewType == ITEM_TYPE.ITEM_TYPE_MASTER.ordinal) {
            val inflater = LayoutInflater.from(mContext)
            val view = inflater.inflate(R.layout.item_master, parent, false)
            val holder = MainViewHolder(view)
            view.setOnClickListener(holder)
            view.setOnLongClickListener(holder)

            view.post {
                view.layoutParams.width = (parent.width - 2 * DisplayUtil.dip2px(parent.context, 10f)) / 3
                view.layoutParams.height = DisplayUtil.dip2px(mContext, HEIGHT.toFloat())
                view.setBackgroundColor(Color.TRANSPARENT)
            }
            return holder
        }else{
            val inflater = LayoutInflater.from(mContext)
            val view = inflater.inflate(R.layout.item_master_add, parent, false)
            view.post {
                view.layoutParams.width = (parent.width - 2 * DisplayUtil.dip2px(parent.context, 10f)) / 3
                view.layoutParams.height = DisplayUtil.dip2px(mContext, HEIGHT.toFloat())
                view.setBackgroundColor(Color.TRANSPARENT)
            }

            return ImageViewHolder(view)
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val item = data[position]

        if (getItemViewType(position) == ITEM_TYPE.ITEM_TYPE_MASTER.ordinal) {
            (holder as MainViewHolder).bind(mContext, item, position)
            holder.itemView.tag = item
        }else{
            (holder as ImageViewHolder).bind(mContext, position)
        }
    }

    override fun getItemId(position: Int): Long {
        return data[position].hashCode().toLong()
    }

    override fun getItemCount(): Int {
        return data.size
    }

    override fun getItemViewType(position: Int): Int {
        return if (data[position].mid == Constants.UUIDFRAME)
                    ITEM_TYPE.ITEM_TYPE_MASTER_FRAME.ordinal
                else ITEM_TYPE.ITEM_TYPE_MASTER.ordinal
    }

    inner class MainViewHolder(iview: View)
        : AbstractDraggableItemViewHolder(iview),
            View.OnClickListener, View.OnLongClickListener {

        val view by lazy { iview }

        override fun onClick(v: View) {
            Log.d(TAG, " clicked!")
        }

        override fun onLongClick(v: View): Boolean {
            return true
        }

        fun bind(mContext: Context, bean: Master, position: Int) {
            view.cb_caring.setOnCheckedChangeListener(null)
            view.cb_caring.isChecked = bean.selected
            if (isEditable) {
                view.cb_caring.visibility = View.VISIBLE
            } else {
                view.cb_caring.visibility = View.GONE
            }

            if (bean.selected) {
                view.cb_caring.setViewWithNewTintColor(MasterHuijinIMApplication.mContext, R.drawable.cb_caring, R.color.color_master_caredbtn)
            } else {
                view.cb_caring.setViewWithNewTintColor(MasterHuijinIMApplication.mContext, R.drawable.cb_caring, R.color.color_master_uncared)
            }

            view.iv_portrait.setViewWithNewTintColor(MasterHuijinIMApplication.mContext, R.drawable.ic_master, R.color.dark)
            view.btn_stati.setViewWithNewTintColor(MasterHuijinIMApplication.mContext, R.drawable.btn_frame, R.color.color_master_normal)
            view.iv_star.setViewWithNewTintColor(MasterHuijinIMApplication.mContext, R.drawable.ic_star, R.color.color_master_normal)
            view.tv_name.setTextColor(MasterHuijinIMApplication.mContext.resources.getColor(R.color.dark))

            view.cb_caring.setOnCheckedChangeListener {
                _, isChecked ->
                addAndRemoveToChoosedMaster(bean, isChecked, position)
            }

            view.tv_name.text = bean.name

            view.btn_stati.setOnClickListener {
                if (!bean.url.isNullOrBlank()) {
                    val it = Intent()
                    it.action = Intent.ACTION_VIEW
                    val url: Uri? = Uri.parse(bean.url)
                    it.data = url
                    mContext.startActivity(it)
                }
            }
            if (!bean.icon.isNullOrBlank()) {
                ImageLoader.getInstance().displayImage(bean.icon, view.iv_portrait)
            } else {
                if (bean.selected) {
                    view.iv_portrait.setViewWithNewTintColor(MasterHuijinIMApplication.mContext, R.drawable.ic_master, R.color.color_master_cared)

                    view.iv_portrait.setViewWithNewTintColor(MasterHuijinIMApplication.mContext, R.drawable.ic_master, R.color.dark)
                } else {
                    view.iv_portrait.setViewWithNewTintColor(MasterHuijinIMApplication.mContext, R.drawable.ic_master, R.color.color_master_uncared)
                }
            }
        }

        private fun addAndRemoveToChoosedMaster(bean: Master, isChecked: Boolean, position: Int){
            bean.selected = isChecked

            if (isChecked){
                listener.onRefresh(RefreshNotificationListener.RefreshType.ADDMASTERTOCHOOSEDMASTERS, bean)
            }else{
                listener.onRefresh(RefreshNotificationListener.RefreshType.REMOVEMASTERFROMCHOOSED, bean)
            }
        }
    }

    inner class ImageViewHolder internal constructor(val view: View) : RecyclerView.ViewHolder(view) {

        init {
        }

        fun bind(context: Context, position: Int) {
            view.iv_master_add?.setImageResource(R.drawable.shortcut_channel_promo_bg)
            view.iv_master_add?.visibility = View.INVISIBLE
            view.iv_master_add.postDelayed({
                view.iv_master_add?.visibility = View.VISIBLE
            }, 200)
        }
    }

    companion object {
        val TAG: String = SelectedMastersNewAdapter.javaClass.simpleName
    }
}

here is the logcat:

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 6(offset:6).state:7 android.support.v7.widget.RecyclerView{7c71274 VFED..... .F....ID 15,15-987,681 #7f0900e5 app:id/gv_caredmaster}, adapter:com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemWrapperAdapter@af563e3, layout:android.support.v7.widget.GridLayoutManager@37ce1e0, context:com.jihui.lyracss.masterhuijin.activity.MainActivity@a946dba
    at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5654)
    at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5589)
    at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5585)
    at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2231)
    at android.support.v7.widget.GridLayoutManager.layoutChunk(GridLayoutManager.java:556)
    at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1518)
    at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:610)
    at android.support.v7.widget.GridLayoutManager.onLayoutChildren(GridLayoutManager.java:170)
    at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3719)
    at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:3135)
    at android.view.View.measure(View.java:19759)
    at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
    at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
    at android.view.View.measure(View.java:19759)
    at android.widget.ScrollView.measureChildWithMargins(ScrollView.java:1293)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
    at android.widget.ScrollView.onMeasure(ScrollView.java:340)
    at android.view.View.measure(View.java:19759)
    at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
    at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
    at android.view.View.measure(View.java:19759)
    at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
    at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
    at android.view.View.measure(View.java:19759)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6122)
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
    at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:1117)
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:642)
    at android.view.View.measure(View.java:19759)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6122)
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
    at android.view.View.measure(View.java:19759)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6122)
    at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:714)
    at android.support.design.widget.HeaderScrollingViewBehavior.onMeasureChild(HeaderScrollingViewBehavior.java:91)
    at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onMeasureChild(AppBarLayout.java:1361)
    at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:784)
    at android.view.View.measure(View.java:19759)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6122)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
    at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
    at android.view.View.measure(View.java:19759)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6122)
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
    at android.view.View.measure(Vie
#++++++++++++++++++++++++++++++++++++++++++#
  • 1
    Someone here had a similar problem, check it out https://stackoverflow.com/questions/30220771/recyclerview-inconsistency-detected-invalid-item-position – Saik Caskey Apr 12 '18 at 14:06
  • Possible duplicate of [RecyclerView: Inconsistency detected. Invalid item position](https://stackoverflow.com/questions/30220771/recyclerview-inconsistency-detected-invalid-item-position) – Gokul Nath KP Apr 12 '18 at 14:06

2 Answers2

0

Clear RecyclerView pool. Call notifyDataSetChanged.

mRecyclerView.getRecycledViewPool().clear();
mAdapter.notifyDataSetChanged();
Jay Rathod
  • 11,131
  • 6
  • 34
  • 58
Gokul Nath KP
  • 15,485
  • 24
  • 88
  • 126
0

After carefully check the codes with my friend. I found I duplicated invoking notifyDataSetChange(). In 10ms, invoke twice. And there may be data changes during it. I am not research on it anymore. Thanks.