Skip to content

Snappy1

  • Home
  • Android
  • What
  • How
  • Is
  • Can
  • Does
  • Do
  • Why
  • Are
  • Who
  • Toggle search form

[FIXED] android – Load Details view from Kotlin RecyclerView(cardview) onclick

Posted on November 11, 2022 By

Solution 1 :

First you need to pass the data from your cardView’s onclick and then start activity, finally handle those data in your desired item details activity…
You’ll need context/AppCompatActivity while starting activity, so you can modify your Adapter’s constructor to receive Context:

class ArticleAdapter(
   private val context: Context,
    private var articleList: ArrayList<Article>
) : RecyclerView.Adapter<ArticleViewHolder>()

Use this constructor while initializing it from your fragment:

articleAdapter = ArticleAdapter(activity, articleList) // activity => getActivity()

In your item click listener:

 override fun onBindViewHolder(articleViewHolder: ArticleViewHolder, itemIndex: Int) {
    val article: Article = articleList?.get(itemIndex)
    setPropertiesForArticleViewHolder(articleViewHolder, article)
    articleViewHolder.cardView.setOnClickListener {

        val titleString = article.title
        val descString = article.description
        val urlString = article.url

        val toPass = Bundle()
        toPass.putString("url", urlString)
        toPass.putString("title", titleString)
        toPass.putString("desc", descString)

        val intent =
            Intent(context, YourActivity::class.java) //context we got from constructor
        intent.putExtras(toPass)
        context.startActivity(intent) // or we can use ContextCompat
    }
}

Now handle this data and set views accordingly:

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

    val bundle = intent.extras
    val url = bundle?.get("url")
    val title = bundle?.get("title")
    val desc = bundle?.get("desc")

    // now handle those...

    titleTextView.text = title!!
//            ...

}

Solution 2 :

Update: I see someone already gave a similar answer. However, I’m still keeping it as I see some problems in that answer. You can’t start an activity from Adapter with startActivity, it has to be activity.startActivity

I will break the thing for you.

At first, you need to pass the list and context/activity to the adapter. You can pass it through the constructor of the adapter.

class ArticleAdapter(
    val activity: AppCompatActivity
    val itemList: MutableList<String>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
}

So, from the fragment, you need to send the context/activity like this:

recyclerView.adapter = ArticleAdapter(activity!!, articleList)

Now, in your adapter, in the onBindViewHolder method, you need to listen the click.

articleViewHolder.itemView.setOnClickListener {
    val intent = Intent(activity, YourDesiredActivity::class.java)
    activity.startActivity(intent)
}

If there is an error in itemView, check the ArticleViewHolder class and rename the view from its constructor. Let me know if you face any problem.

READ  [FIXED] android - React Native App and a UnStable Internet Connection
Powered by Inline Related Posts

Solution 3 :

Pass Fragment context while initializing adapter class

val adapter = ArticleAdapter(listItems, context);

Inside onClickListener

articleViewHolder.cardView.setOnClickListener {
    context.startActivity(context, TargetActivity);
}

Problem :

I have a fragment which has a RecyclerView with items are in CardViews. I have an adapter which will populate the RecyclerView with data from newsapi.org. what I need to achieve is when I click on a item(CardView) to load an activity with image, title and description. I’m quite new to kotlin and find I’m stuck in here and need help to follow up. Would be really helpful. I’ll attach my adapter and fragment(which has the RecyclerView).

What bugs me is should i start the activity within onBindViewHolder -> ….cardView.setOnClickListener or else? and the confusing part is to set the image(which comes from url) into passing value to the details view.

Adapter Class

class ArticleAdapter(
private var articleList: ArrayList<Article>
) : RecyclerView.Adapter<ArticleViewHolder>() {

private val placeHolderImage = "https://picsum.photos/200/200/?blur"
private lateinit var viewGroupContext: Context

override fun onCreateViewHolder(viewGroup: ViewGroup, p1: Int): ArticleViewHolder {
    viewGroupContext = viewGroup.context
    val itemView: View =
        LayoutInflater.from(viewGroup.context).inflate(R.layout.article_item, viewGroup, false)
    return ArticleViewHolder(itemView)
}

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

override fun onBindViewHolder(articleViewHolder: ArticleViewHolder, itemIndex: Int) {
    val article: Article = articleList.get(itemIndex)
    setPropertiesForArticleViewHolder(articleViewHolder, article)
    articleViewHolder.cardView.setOnClickListener {
        //do something
    }
}

private fun setPropertiesForArticleViewHolder(
    articleViewHolder: ArticleViewHolder,
    article: Article
) {
    checkForUrlToImage(article, articleViewHolder)
    articleViewHolder.title.text = article?.title
    articleViewHolder.description.text = article?.description
    articleViewHolder.url.text = article?.url
}

private fun checkForUrlToImage(article: Article, articleViewHolder: ArticleViewHolder) {
    if (article.urlToImage == null || article.urlToImage.isEmpty()) {
        Picasso.get()
            .load(placeHolderImage)
            .centerCrop()
            .fit()
            .into(articleViewHolder.urlToImage)
    } else {
        Picasso.get()
            .load(article.urlToImage)
            .centerCrop()
            .fit()
            .into(articleViewHolder.urlToImage)
    }
}

fun setArticles(articles: ArrayList<Article>) {
    articleList = articles
    notifyDataSetChanged()
}
}

//interface ItemClickListener{
//    fun onItemClick(articleList: Article, position:Int)
//}

Fragment

class HomeFragment : Fragment(), SwipeRefreshLayout.OnRefreshListener {

//    private lateinit var homeViewModel: HomeViewModel
private val ENDPOINT_URL by lazy { "https://newsapi.org/v2/" }
private lateinit var topHeadlinesEndpoint: TopHeadlinesEndpoint
private lateinit var newsApiConfig: String
private lateinit var articleAdapter: ArticleAdapter
private lateinit var articleList: ArrayList<Article>
private lateinit var userKeyWordInput: String
// RxJava related fields
private lateinit var topHeadlinesObservable: Observable<TopHeadlines>
private lateinit var compositeDisposable: CompositeDisposable

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {

    return inflater.inflate(R.layout.fragment_home, container, false)
}

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

    swipe_refresh.setOnRefreshListener {
        queryTopHeadlines()
 //            refreshAction()  //refresh the list
        swipe_refresh.isRefreshing = false
    }

    //Network request
    val retrofit: Retrofit = generateRetrofitBuilder()
    topHeadlinesEndpoint = retrofit.create(TopHeadlinesEndpoint::class.java)
    newsApiConfig = resources.getString(R.string.api_key)
    swipe_refresh.setOnRefreshListener(this)
    swipe_refresh.setColorSchemeResources(R.color.colorAccent)
    articleList = ArrayList()
    articleAdapter = ArticleAdapter(articleList)

 //        userKeyWordInput = ""

    compositeDisposable = CompositeDisposable()
    recycler_viewHome.setHasFixedSize(true)
    recycler_viewHome.layoutManager = LinearLayoutManager(context)
    recycler_viewHome.itemAnimator = DefaultItemAnimator()
    recycler_viewHome.adapter = articleAdapter

}
override fun onStart() {
    super.onStart()
    queryTopHeadlines()
}
override fun onDestroy() {
    super.onDestroy()
    compositeDisposable.clear()
}
override fun onRefresh() {
    queryTopHeadlines()
}

private fun queryTopHeadlines() {
    swipe_refresh.isRefreshing = true
    topHeadlinesObservable = topHeadlinesEndpoint.getTopHeadlines("us", newsApiConfig)
    subscribeObservableOfArticle()
}

private fun subscribeObservableOfArticle() {
    articleList.clear()
    compositeDisposable.add(
        topHeadlinesObservable.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .flatMap {
                Observable.fromIterable(it.articles)
            }
            .subscribeWith(createArticleObserver())
    )
}

private fun createArticleObserver(): DisposableObserver<Article> {
    return object : DisposableObserver<Article>() {
        override fun onNext(article: Article) {
            if (!articleList.contains(article)) {
                articleList.add(article)
            }
        }

        override fun onComplete() {
            showArticlesOnRecyclerView()
        }

        override fun onError(e: Throwable) {
            Log.e("createArticleObserver", "Article error: ${e.message}")
        }
    }
}

private fun showArticlesOnRecyclerView() {
    if (articleList.size > 0) {
        empty_text.visibility = View.GONE
        retry_fetch_button.visibility = View.GONE
        recycler_viewHome.visibility = View.VISIBLE
        articleAdapter.setArticles(articleList)
    } else {
        recycler_viewHome.visibility = View.GONE
        empty_text.visibility = View.VISIBLE
        retry_fetch_button.visibility = View.VISIBLE
 //            retry_fetch_button.setOnClickListener { checkUserKeywordInput()    }
    }
    swipe_refresh.isRefreshing = false
}

private fun generateRetrofitBuilder(): Retrofit {

    return Retrofit.Builder()
        .baseUrl(ENDPOINT_URL)
        .addConverterFactory(GsonConverterFactory.create())
        //Add RxJava2CallAdapterFactory as a Call adapter when building     your Retrofit instance
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .build()
}
}

Comments

Comment posted by some user

why don’t you start your activity from your item’s onclick listener..? pass necessary data while creating

READ  [FIXED] java - Null object reference when passing variable from activity to fragment
Powered by Inline Related Posts

Comment posted by jasonz

sorry to be sound so foolish, but kotlin is new to me and i maybe okay with a sample code

Comment posted by jasonz

thank you sir for the help, im still blank on how to pass the ulrToImage or image from list item click to details view to be viewed.

Comment posted by some user

firstly, please stop this sir thing, we all are learners, right? secondly, I’m going to update answer according to your need

Comment posted by jasonz

when i do “articleAdapter = ArticleAdapter(activity, articleList)” in fragment. it says type mismatch, required AppcompactActivity? found FragmentActivity.

Comment posted by some user

Happy coding 🙂

Comment posted by aleem md

Can u update your fragment code. It looks like your fragment and adapter code is same

Comment posted by aleem md

Modify your adater definition to this

Comment posted by aleem md

And pass context from fragment class

Comment posted by jasonz

i should put “articleAdapter = ArticleAdapter(articleList, context)) ” this in my Adapter class or in fragment class ?

Comment posted by aleem md

Replace

Android Tags:android, android-recyclerview, cardview, kotlin, onclicklistener

Post navigation

Previous Post: [FIXED] android – How to pass data by Back Button, Kotlin
Next Post: [FIXED] Project with external module issue in android studio 3.6

Related Posts

[FIXED] android – Question about defining resource layout id in the activity/fragment constructor Android
[FIXED] javascript – capacitor-admob Android compilation error? Android
[FIXED] java – How would you implement a stock chart into an Android app? Android
[FIXED] java – How to check only if the user allowed the permission Android
[FIXED] java – Android How Do I Call RecyclerVIew notifyDataSetChanged() after ThreadPoolExecutor finishes? Android
[FIXED] android – Running 10 kotlin async coroutines concurrently Android

Archives

  • March 2023
  • February 2023
  • January 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022

Categories

  • ¿Cómo
  • ¿Cuál
  • ¿Cuándo
  • ¿Cuántas
  • ¿Cuánto
  • ¿Qué
  • Android
  • Are
  • At
  • C'est
  • Can
  • Comment
  • Did
  • Do
  • Does
  • Est-ce
  • Est-il
  • For
  • Has
  • Hat
  • How
  • In
  • Is
  • Ist
  • Kann
  • Où
  • Pourquoi
  • Quand
  • Quel
  • Quelle
  • Quelles
  • Quels
  • Qui
  • Should
  • Sind
  • Sollte
  • Uncategorized
  • Wann
  • Warum
  • Was
  • Welche
  • Welchen
  • Welcher
  • Welches
  • Were
  • What
  • What's
  • When
  • Where
  • Which
  • Who
  • Who's
  • Why
  • Wie
  • Will
  • Wird
  • Wo
  • Woher
  • you can create a selvedge edge: You can make the edges of garter stitch more smooth by slipping the first stitch of every row.2022-02-04
  • you really only need to know two patterns: garter stitch

Recent Posts

  • What color are dead flea eggs?
  • What is Indiana vine?
  • What’s the downside of a Chromebook?
  • Is phosphide the same as phosphorus?
  • Why do you need an S bend?

Recent Comments

No comments to show.

Copyright © 2023 Snappy1.

Powered by PressBook Grid Dark theme