I have a News app where I have used Retrofit to get data from API. I have shown news with cardView and Recycler view. Now I want to implement the the next step where I want if a user click on a card the whole news should display on a new activity. But to implement this I don’t have the proper idea that how to do this. Here I am providing my MainActivity , the adapter class and the interface for retrofit. I am looking for the help to implement the next step.
MainActivity.kt
class MainActivity : AppCompatActivity() {
lateinit var adapter: NewsAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
getNews()
}
private fun getNews() {
val news :Call<News> = NewsSeversis.newsIntence.getHeadlines("in",1)
news.enqueue(object :Callback<News>{
override fun onResponse(call: Call<News>, response: Response<News>) {
//here response is a News response
val news:News?=response.body()
if (news!=null){
Log.d("response",news.toString())
adapter= NewsAdapter(news.articles)
newsList.adapter=adapter
newsList.layoutManager=LinearLayoutManager(this@MainActivity)
}
}
override fun onFailure(call: Call<News>, t: Throwable) {
Log.d("response","error occur",t)
}
})
}
}
Adapter class for recycler view
class NewsAdapter (val artical: List<Artical>):RecyclerView.Adapter<NewsAdapter.articalViewHolder>(){
inner class articalViewHolder(itemView: View):RecyclerView.ViewHolder(itemView)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): articalViewHolder {
val view:View=LayoutInflater.from(parent.context).inflate(R.layout.item_layout,parent,false)
return articalViewHolder(view)
}
override fun onBindViewHolder(holder: articalViewHolder, position: Int) {
val articals:Artical=artical[position]
holder.itemView.apply {
newsTitle.text=articals.title
newsDescription.text=articals.description
Glide.with(context).load(articals.urlToImage).into(newsImage)
}
}
override fun getItemCount(): Int {
return artical.size
}
}
interface class
const val BASE_URL="https://newsapi.org/"
const val API_KEY="b461fea21cc242458825d1be951ebe1c"
interface NewsInterface{
@GET("v2/top-headlines?apiKey=$API_KEY")//@GET is to tell the it is a get request
fun getHeadlines(@Query("country")country:String, @Query("page") page:Int) : Call<News>
}
object NewsSeversis {
val newsIntence:NewsInterface
init {
val retrofit=Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
newsIntence=retrofit.create(NewsInterface::class.java)
}
}
layout for every card view
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:cardUseCompatPadding="true"
app:cardCornerRadius="8dp"
app:cardElevation="4dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#F1F1F1"
android:padding="16dp">
<ImageView
android:id="@+id/newsImage"
android:layout_width="match_parent"
android:layout_height="180dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_launcher_background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/newsTitle"
style="@style/TextAppearance.AppCompat.Headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:maxLines="2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="8dp"
android:text="Title"
app:layout_constraintTop_toBottomOf="@+id/newsImage" />
<TextView
android:id="@+id/newsDescription"
style="@style/TextAppearance.AppCompat.Body1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:maxLines="2"
android:text="Description"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/newsTitle" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
main activity layout
<?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"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/newsList"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Along with those I have a Artical and a News class with constructor and a Whole new activity for display the whole news on that activity
News class
ata class News(
val totalResults:Int,
val articles:List<Artical>
)
Artical class
data class Artical(
val author:String,
val title:String,
val description:String,
val url:String,
val urlToImage:String)
2
Answers
Following are the steps to get callback to activity of an item click from adapter.
In your
NewsAdapter
class use aHigherOrder Function
to get call back of item click.1. First Update the NewsAdapter
2. Now update the code in
MainActivity
where you are creating object ofNewsAdapter
.Feel free to ask if you have any queries.
To Identify which item was clicked we need to have an interface from which can get us the callback from Adapter to Activity, so create a interface class in Adapter. (In your case you can create it in last second line of NewsAdapter)
Then we need to take an oject of this interface in Adapter’s Constructor
Then we have to use callback object on click of view(s). (In your case do the following in adapter class’s onBindViewHolder)
Now we need to listen this callback in our Activity, so we need create object in Activity in the following way
Now as we have object of AdapterCallback in our Activity, we need to pass it to Adapter
Note: You need to make Artical Class Parcelable