How to remove an item in view-pager 2 with kotlin?

Viewed 918

I use view-pager2 and When I remove the first item of view-pager, It does not delete and still remains but another item removed.

For example, here I want to remove the first item of view pager but it's not be removed:

screen record

My Main Activity:

class MainActivity : AppCompatActivity() {

private lateinit var myPagerAdapter: MyPagerAdapter
private val mFragmentList: ArrayList<FragmentOne> = ArrayList()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    if (mFragmentList.isEmpty()) {
        mFragmentList.add(FragmentOne.newInstance(1))
        mFragmentList.add(FragmentOne.newInstance(2))
        mFragmentList.add(FragmentOne.newInstance(3))
    }

    myPagerAdapter = MyPagerAdapter(supportFragmentManager, lifecycle)
    view_pager.adapter = myPagerAdapter

    btn_show.setOnClickListener {
        val dialog = Dialog(this)
        dialog.setContentView(R.layout.fragment_dialog)
        dialog.btn_remove.setOnClickListener {
            //go to next item
            view_pager.currentItem = 1
            //remove first item
            mFragmentList.removeAt(0)
            //reload adapter
            myPagerAdapter.notifyDataSetChanged()
        }
        dialog.show()
    }

}

private inner class MyPagerAdapter(fragmentManager: FragmentManager, lifecycle: Lifecycle) :
    FragmentStateAdapter(fragmentManager, lifecycle) {

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

    override fun createFragment(position: Int): Fragment {
        return mFragmentList[position]
    }

}
}

FragmentOne:

class FragmentOne : Fragment() {

companion object {
    fun newInstance(position: Int): FragmentOne {
        val fragment = FragmentOne()
        val bundle = Bundle()
        bundle.putInt("id", position)
        fragment.arguments = bundle
        return fragment
    }
}

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    return inflater.inflate(R.layout.fragment_one, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    val id = arguments?.getInt("id")
    tv?.text = id.toString()
}

}

If I don't use view-pager2, Just enough to add PagerAdapter.POSITION_NONE like this answer.

Can you help me?!

3 Answers

If you read the documentation it says

Note: The DiffUtil utility class relies on identifying items by ID. If you are using ViewPager2 to page through a mutable collection, you must also override getItemId() and containsItem().

Taken from this post - Migrate to ViewPager2

Since you are using a mutable ArrayList() you should also override the getItemId() method in your adapter, for the itemId you need a unique ID for every fragment, I solved it using the hashCode() function like this

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

This should remove the first fragment and get the correct fragment from the list using the itemId Hope this solves your problem.

Actually delete functionality is working properly 0th index fragment is deleted but after calling notfiydataset changed the first fragment gets th value as 1 and second as 2.

I did the same for java, with viewpager2 and its works!

@Override
public long getItemId(int position) {
    Long longtype = Long.valueOf(mFragmentList.get(position).hashCode());
    return longtype;
}

@Override
public boolean containsItem(long itemId) {
    return super.containsItem(itemId);
}
Related