Home > Mobile >  Arraylist loop unexpectedly on kotlin recycleview
Arraylist loop unexpectedly on kotlin recycleview

Time:10-18

Here is when the list increase

I call data from API and place it in recycleview horizontal and vertical, but when I try to move on Profile Menu with bottom navigation and back again on Home Menu where my horizontal and vertical recycleview is, the data on recycleview start to increase, it only happen for vertical recycleview

Here is my code: SectionPagerAdapter for vertical recycleview

class SectionsPagerAdapter(fm: FragmentManager) :
    FragmentPagerAdapter(
        fm
    ) {


    var new_craft: ArrayList<Data>? = ArrayList()
    var popular: ArrayList<Data>? = ArrayList()
    var recommended: ArrayList<Data>? = ArrayList()

    override fun getItem(position: Int): Fragment {

        var fragment : Fragment
        return when (position) {
            0 -> {
                fragment = HomeNewCraftFragment()
                val bundle = Bundle()
                bundle.putParcelableArrayList("data", new_craft)
                fragment.setArguments(bundle)
                return fragment
            }
            1 -> {
                fragment = HomePopularFragment()
                val bundle = Bundle()
                bundle.putParcelableArrayList("data", popular)
                fragment.setArguments(bundle)
                return fragment
            }
            2 -> {
                fragment = HomeRecommendedFragment()
                val bundle = Bundle()
                bundle.putParcelableArrayList("data", recommended)
                fragment.setArguments(bundle)
                return fragment
            }
            else -> {
                fragment = HomeNewCraftFragment()
                val bundle = Bundle()
                bundle.putParcelableArrayList("data", new_craft)
                fragment.setArguments(bundle)
                return fragment
            }
        }
    }

    override fun getPageTitle(position: Int): CharSequence? {
        return when (position) {
            0 -> "New Craft"
            1 -> "Popular"
            2 -> "Recommended"
            else -> null
        }
    }

    override fun getCount(): Int {
        return 3
    }

    fun setData(newStateListParms: ArrayList<Data>?, popularListParms: ArrayList<Data>?, recomendedListParms: ArrayList<Data>?) {
        new_craft = newStateListParms
        popular = popularListParms
        recommended = recomendedListParms
    }
}

Home Fragment:

class HomeFragment : Fragment(), HomeAdapter.ItemAdapterCallback, HomeContract.View {

    private var adapter: HomeAdapter? = null
    var progressDialog: Dialog? = null
    private var newStateList: ArrayList<Data>? = ArrayList()
    private var popularList: ArrayList<Data>? = ArrayList()
    private var recomendedList: ArrayList<Data>? = ArrayList()

    private lateinit var presenter: HomePresenter

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

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        initView()
        presenter = HomePresenter(this)
        presenter.getHome()

    }
    
    private fun initView() {
        progressDialog = Dialog(requireContext())
        val dialogLayout = layoutInflater.inflate(R.layout.dialog_loader, null)

        progressDialog?.let {
            it.setContentView(dialogLayout)
            it.setCancelable(false)
            it.window?.setBackgroundDrawableResource(android.R.color.transparent)
        }

        var user = IcaCraft.getApp().getUser()
        var userResponse = Gson().fromJson(user, User::class.java)

        if (!userResponse.profile_photo_url.isNullOrEmpty()) {
            Glide.with(requireActivity())
                .load(userResponse.profile_photo_url)
                .into(ivProfile)
        }

    }

    override fun onClick(v: View?, data: Data) {
        var bundle = Bundle()
        bundle.putParcelable("data", data)
        val detail = Intent(activity, DetailActivity::class.java).putExtras(bundle)
        startActivity(detail)
    }

    override fun onHomeSuccess(homeResponse: HomeResponse) {

        for (a in homeResponse.data.indices) {

            var items: List<String> = homeResponse.data[a].types?.split(",") ?: ArrayList()
            for (x in items.indices)
            {
                if (items[x].equals("new_craft", true)) {
                    newStateList?.add(homeResponse.data[a])
                } else if (items[x].equals("recommended", true)) {
                    recomendedList?.add(homeResponse.data[a])
                } else if (items[x].equals("popular", true)) {
                    popularList?.add(homeResponse.data[a])
                }
            }
        }
        adapter = HomeAdapter(homeResponse.data, this)
        val layoutManager: RecyclerView.LayoutManager =
            LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
        rvList.layoutManager = layoutManager
        rvList.adapter = adapter

        val sectionsPagerAdapter = SectionsPagerAdapter(
            childFragmentManager
        )
        sectionsPagerAdapter.setData(newStateList, popularList, recomendedList)
        viewPager.adapter = sectionsPagerAdapter
        tabLayout.setupWithViewPager(viewPager)
    }

    override fun onHomeFailed(message: String) {
        Toast.makeText(activity, message, Toast.LENGTH_LONG).show()
    }

    override fun showLoading() {
        progressDialog?.show()
    }

    override fun dismissLoading() {
        progressDialog?.dismiss()
    }
}

HomeCraftAdapter: adapter for vertical recycleview

class HomeNewCraftAdapter (
    private val listData: ArrayList<Data>,
    private val itemAdapterCallback: ItemAdapterCallback
) : RecyclerView.Adapter<HomeNewCraftAdapter.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        val view = layoutInflater.inflate(R.layout.item_home_vertical, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(listData[position], itemAdapterCallback)

    }

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

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(data : Data, itemAdapterCallback : ItemAdapterCallback) {
            itemView.apply {
                tvTitle.text = data.name
                tvPrice.formatPrice(data?.price.toString())
                rbCraft.rating = data.rate?.toFloat() ?: 0f
                Glide.with(context)
                    .load(data.picturePath)
                    .into(ivPoster)
                itemView.setOnClickListener { view -> itemAdapterCallback.onClick(view, data) }
            }
        }
    }

    interface ItemAdapterCallback {
        fun onClick(v: View?, data:Data)
    }
}

And HomeNewCraftFragment : for vertical recycleview fragment

class HomeNewCraftFragment : Fragment() , HomeNewCraftAdapter.ItemAdapterCallback {

    private var adapter: HomeNewCraftAdapter? = null
    private var newcraftlist: ArrayList<Data>? = ArrayList()
    private var test: String? = null

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

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        newcraftlist = arguments?.getParcelableArrayList("data")

        adapter = HomeNewCraftAdapter(newcraftlist!!, this)
        val layoutManager: RecyclerView.LayoutManager = LinearLayoutManager(activity)
        rcListNewCraft.layoutManager = layoutManager
        rcListNewCraft.adapter = adapter
    }

    override fun onClick(v: View?, data: Data) {
        val detail = Intent(activity, DetailActivity::class.java).putExtra("data", data)
        startActivity(detail)
    }
}

CodePudding user response:

When you leave from your HomeFragment and coming back again, your HomeFragment keeps the old newStateList and add same values in it again. So, you need to empty the values before adding new values.

override fun onHomeSuccess(homeResponse: HomeResponse) {
        newStateList = ArrayList() // empty it before load it again.
        for (a in homeResponse.data.indices) {

You might need to empty the recomendedList and popularList as well.

  • Related