简体   繁体   中英

How to display JSON data from Horizontal recycle view kotlin using MVP method

I hope is all well with you.

I have constructed my code and build according the MVP style as well pulling JSON data but when I run the the code the horizontal recycle view and the JSON data is not being displayed. I tried going through every line of code and watching other tutorials but still no results.

Here is below my main activity:

    class ProductCategoryActivity : BaseMvpActivity<ProductCategoryActivityView, ProductCategoryActivityPresnter> (),
    ProductCategoryActivityView, CategoryAdapter.onItemClickListener{


    private  lateinit var binding: FragmentProductCategoryBinding
    val data :MutableList<CateogryResponse> = ArrayList()
    val adapter= CategoryAdapter(data, this)
    @Inject
    lateinit var presenter: ProductCategoryActivityPresnter

    @Inject
    lateinit var progressDialog: ProgressDialog

    override fun onCreateComponent() {
        userComponent.plus(CategoryActivityModule(this)).inject(this)
    }

    override fun providePresenter(): ProductCategoryActivityPresnter {
        return presenter
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = FragmentProductCategoryBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)
        presenter.fetchcatogries()
        showdata(ArrayList())

    }

    override fun showError(message: String) {

    }

    override fun showProgress() {

    }

    override fun hideProgress() {

    }


    override fun showdata(data: ArrayList<CateogryResponse>) {

        val layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
        recyclerViewPrimary.layoutManager = layoutManager
        recyclerViewPrimary.setHasFixedSize(true)
        recyclerViewPrimary.adapter = adapter

        for(i in data)
          data.add(CateogryResponse("product"))


    }

    override fun onItemClick(position: Int) {
        Toast.makeText(this, "Item $position clicked", Toast.LENGTH_SHORT).show()
        val clickedItem = data[position]
        adapter.notifyItemChanged(position)
    }

}

Here is my presenter:

@ActivityScope

class ProductCategoryActivityPresnter @Inject constructor(
    private val stringProvider: StringProvider,
    @AndroidScheduler private val observeOnScheduler: Scheduler,
    @IOScheduler private val subscribeOnScheduler: Scheduler,
    private val getCategoryUseCase: CategoryUseCase


) : BasePresenter<ProductCategoryActivityView>() {

    lateinit var catogriesservice: CategoryRepositoryImpl
    val catogriesLoadError = MutableLiveData<Boolean>()
    val loading = MutableLiveData<Boolean>()
    var catogries: ArrayList<CateogryResponse> = arrayListOf()
    override fun onCreatePresenter(savedInstanceState: Bundle?) {
    }

    override fun onSaveInstanceState(outState: Bundle?) {
    }

    override fun onLoadData(arguments: Bundle?) {
        fetchcatogries()
    }

    fun fetchcatogries() {
        getCategoryUseCase.execute()
            .observeOn(observeOnScheduler)
            .subscribeOn(subscribeOnScheduler)
            .subscribe(
                SingleRequestSubscriber(
                    {
                        it
                        if (it != null && it.size > 0) {
                            catogries.removeAll(catogries)
                            catogries.addAll(it)
                        }
                    },
                    onFailure = { appException ->
                        view?.showError(
                            ErrorHandler.getErrorMessage(
                                appException,
                                stringProvider
                            )
                        )
                    },
                    onApiError = { apiException ->
                        view?.showError(
                            ErrorHandler.getErrorMessage(
                                apiException,
                                stringProvider
                            )
                        )
                    },
                    onAuthenticationError = { requestxception ->
                        view?.showError(
                            ErrorHandler.getErrorMessage(
                                requestxception,
                                stringProvider
                            )
                        )
                    },
                    onShowProgress = {
                        if (it) {
                            view?.showProgress()
                        } else {
                            view?.hideProgress()
                        }
                    },
                    onSubscribed = {
                        disposable.add(it)
                    })
            )
    }


}

Here is my view:

interface ProductCategoryActivityView {
    fun showError(message: String)
    fun showProgress()
    fun hideProgress()
    fun showdata ( data: ArrayList<CateogryResponse>)


}

Here is my adapter:

class CategoryAdapter(
    private val data: List<CateogryResponse>,
    private val listener: onItemClickListener
) : RecyclerView.Adapter<CategoryAdapter.ViewHolder>() {

    private val items: MutableList<CardView>

    init {
        this.items = ArrayList()
    }

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

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.tvTitle.text = data[position].product

        items.add(holder.card)
    }

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

     inner class ViewHolder(itemView: View
    ) : RecyclerView.ViewHolder(itemView),
   View.OnClickListener {

         val tvTitle: TextView = itemView.featured_title
         val card: CardView = itemView.CardView

         init {
             itemView.setOnClickListener(this)
         }

         override fun onClick(v: View?) {

             val position: Int = adapterPosition
             if (position != RecyclerView.NO_POSITION) {
                 listener.onItemClick(position)
             }
         }
     }
    interface onItemClickListener {
        fun onItemClick(position: Int)

    }


}

Image:

在此处输入图像描述

Fragment Category Adapter:

    android:id="@+id/CardView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    app:cardCornerRadius="2dp"
    app:cardElevation="8dp">

    <!-- We Will Add here the card & ImageViews -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="15dp">

        <ImageView
            android:id="@+id/featured_image"
            android:layout_width="match_parent"
            android:layout_height="140dp"
            android:scaleType="centerCrop" />

        <TextView
            android:id="@+id/featured_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:lineHeight="23dp"
            android:text="Chairs"
            android:textColor="@color/colorAccent"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/featured_desc"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="asbkd asudhlasn saudnas jasdjasl hisajdl asjdlnas" />


    </LinearLayout>
</androidx.cardview.widget.CardView>

Fragment Product Category:

    <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fafcfe"
    tools:context="ui.category.ProductCategoryActivity">

    <ImageView
        android:id="@+id/imageView3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="0dp"

        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/constraintLayout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="32dp"
        android:layout_marginTop="48dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@+id/imageView"
        app:layout_constraintTop_toTopOf="parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerViewPrimary"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>


    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="48dp"
        android:layout_marginTop="20dp"
        android:text="@string/topselling"
        android:textSize="18sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/constraintLayout" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/constraintLayout2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="32dp"
        android:layout_marginLeft="32dp"
        android:layout_marginTop="16dp"
        app:layout_constraintBottom_toTopOf="@+id/imageView3"
        app:layout_constraintEnd_toEndOf="@+id/constraintLayout"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerViewSecondary"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>





    <ImageView
        android:id="@+id/imageView4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="32dp"
        app:layout_constraintBottom_toBottomOf="@+id/imageView3"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        />

    <TextView
        android:id="@+id/textViewCategories"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="48dp"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="15dp"
        android:text="@string/catogries"
        android:textSize="18sp"
        app:layout_constraintBottom_toTopOf="@+id/constraintLayout"
        app:layout_constraintStart_toStartOf="parent"
        tools:layout_editor_absoluteX="39dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

Not sure what went wrong. If someone can point it out or show me what needs to be done to be able to display the data in horzintal recycle view, I would be really thanlful

You should update your recycler view adapter once your fetch call is executed, not before it ends.
Modify your fetchcatogries declaration so it accepts a callback method, which will be executed after the data are loaded.
This method will accept a list object as a parameter, which you will manage in your ProductCategoryActivity to populate the RecyclerView .

fun fetchcatogries(callback: (MutableList<CateogryResponse>) -> Unit) {
    getCategoryUseCase.execute()
            .observeOn(observeOnScheduler)
            .subscribeOn(subscribeOnScheduler)
            .subscribe(
                SingleRequestSubscriber(
                    { categories -> 
                        callback(categories)
                    },
                    ...
            )
}

You can now edit your onCreate and showdata methods in ProductCategoryActivity like this:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = FragmentProductCategoryBinding.inflate(layoutInflater)
    val view = binding.root
    setContentView(view)
    presenter.fetchcatogries { categories -> 
        showdata(categories as ArrayList<CateogryResponse>)
    }
}

override fun showdata(data: ArrayList<CateogryResponse>) {
    val layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
    recyclerViewPrimary.layoutManager = layoutManager
    recyclerViewPrimary.setHasFixedSize(true)
    recyclerViewPrimary.adapter = CategoryAdapter(data.toList(), this)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM