0

trying to add a recyclerview to a fragment is driving me crazy... I have Fragment A where I use a button to start 2 retrofit request, the first request fetches a token, that is used for the second request. When debugging I can see that the requests work and the needed data is fetched. Then I have Fragment B, there I want the data from the second request to been shown in a recyclerview. So first, is this easily handable or should I try to move the call of the second request in the Fragment B? (In that case I would have to pass the values entered in 2 edittext-fields in Fragment A to Fragment B).

To begin slowly I tried to create the recyclerview in Fragment A, having the request and the recyclerview in the same Fragment. It worked:

class AddStalkerFragment : Fragment(R.layout.fragment_add_stalker) {
    private lateinit var binding: FragmentAddStalkerBinding
    private lateinit var sessionManager: SessionManager
    private lateinit var tvCategoryAdapter: TvCategoryAdapter

    val viewModel: StalkerViewModel by lazy {
        ViewModelProvider(this)[StalkerViewModel::class.java]
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentAddStalkerBinding.inflate(inflater, container, false)
        val view = binding.root
        return view
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        prepareRecyclerView()

        sessionManager = SessionManager(this@AddStalkerFragment.requireActivity())

        val stalkerUrl = binding.etServerUrl.text
        val macAddress = binding.etMacAddress.text
        val buttonSave = binding.btnSaveStalker

        buttonSave.setOnClickListener {
            viewModel.getToken(
                url = stalkerUrl.toString(),
                cookie = "mac=${macAddress};stb_lang=en;timezone=Europe/Amsterdam;",
            )
            viewModel.getTvCategory(
                url = stalkerUrl.toString(),
                cookie = "mac=${macAddress};stb_lang=en;timezone=Europe/Amsterdam;",
                token = "Bearer ${sessionManager.fetchAuthToken()}"
            )
        }
            viewModel.getTokenLiveData.observe(viewLifecycleOwner) { response ->
                if (response == null) {
                    Toast.makeText(
                        this@AddStalkerFragment.requireActivity(),
                        "Token Error",
                        Toast.LENGTH_SHORT
                    ).show()
                    return@observe
                }
                val loginResponse = response.js.token
                Toast.makeText(
                    this@AddStalkerFragment.requireActivity(),
                    "Token Ok",
                    Toast.LENGTH_SHORT
                ).show()
                sessionManager.saveAuthToken(loginResponse)
            }
        viewModel.getTvCategoryLiveData.observe(viewLifecycleOwner) { response ->
            if (response == null) {
                Toast.makeText(
                    this@AddStalkerFragment.requireActivity(),
                    "Categories Error",
                    Toast.LENGTH_SHORT
                ).show()
                return@observe
            }
            Toast.makeText(
                this@AddStalkerFragment.requireActivity(),
                "Categories Ok",
                Toast.LENGTH_SHORT
            ).show()
            tvCategoryAdapter.setTvGenresList(response.js)
        }

        }
    private fun prepareRecyclerView() {
        tvCategoryAdapter = TvCategoryAdapter()
        binding.rvTest.apply {
            layoutManager = LinearLayoutManager(context)
            adapter = tvCategoryAdapter
        }
    }
}

And here is what I try in Fragment B to show the recyclerview with the data from Fragment A Debugging"tvCategoryAdapter.setTvGenresList(response)" doesn't work in Fragment B, so it isn't even getting there :-) I assume that I have to connect the two Fragments somehow (I did in Navigation Graph, is this enough?)

class TvCategoryFragment : Fragment(R.layout.fragment_tv_category) {
    private lateinit var binding: FragmentTvCategoryBinding
    private lateinit var tvCategoryAdapter: TvCategoryAdapter

    val viewModel: StalkerViewModel by lazy {
        ViewModelProvider(this)[StalkerViewModel::class.java]
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentTvCategoryBinding.inflate(inflater, container, false)
        val view = binding.root
        return view
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        prepareRecyclerView()


        viewModel.getTvCategoryLiveData.observe(viewLifecycleOwner) { response ->
            if (response == null) {
                Toast.makeText(
                    this@TvCategoryFragment.requireActivity(),
                    "Categories Error",
                    Toast.LENGTH_SHORT
                ).show()
                return@observe
            }
            Toast.makeText(
                this@TvCategoryFragment.requireActivity(),
                "Categories Ok",
                Toast.LENGTH_LONG
            ).show()
            tvCategoryAdapter.setTvGenresList(response.js)
        }

    }
    private fun prepareRecyclerView() {
        tvCategoryAdapter = TvCategoryAdapter()
        binding.rvLayoutTvCategory.apply {
            layoutManager = LinearLayoutManager(context)
            adapter = tvCategoryAdapter
        }
    }

}

My adapter looks like this:

class TvCategoryAdapter : RecyclerView.Adapter<TvCategoryAdapter.ViewHolder>() {
    private var genreList = ArrayList<J>()
    fun setTvGenresList(genreList: List<J>) {
        this.genreList = genreList as ArrayList<J>
        notifyDataSetChanged()
    }

    class ViewHolder(val binding: RvItemTvcategoryBinding) : RecyclerView.ViewHolder(binding.root) {}

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(
            RvItemTvcategoryBinding.inflate(
                LayoutInflater.from(
                    parent.context
                )
            )
        )
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.binding.rvItemTvcategory.text = genreList[position].title
    }

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

Any hint that could help me to solve this? :-)

thanks in advance

Alex Mutschl
  • 27
  • 1
  • 7
  • I think the way it is written now the view models for each fragment are separate instances, I think it would be much easier if it was a [shared view model](https://stackoverflow.com/questions/68058302/difference-between-activityviewmodels-and-lazy-viewmodelprovider) – Stachu Jan 02 '23 at 16:15
  • @Stachu oh, I tought I am using a shared viewmodel when referring on the same viewmodel. I will change that and give feedback if it's working with the shared viewmodel (what I read it's exactly what I need). Thanks for the hint :) – Alex Mutschl Jan 02 '23 at 19:45
  • @Stachu changed to shared-viewmodel -> everything seems to work fine now ;-) thanks for your help! – Alex Mutschl Jan 03 '23 at 09:45

0 Answers0