I'm making a simple app, that when the user is opening the app, to show every single article within this link's JSON data
My goal is to make every single element of that list a.k.a. the articles to display their own summary for each element of the list with a new activity with by using TextView to display the summary.
Here is the code by order:
Article.java
package com.example.spaceflightnews.get;
public class Article {
public String getTitle() {
return title;
}
//Trying to get this data for each individual item element within the RecycleView
public String getSummary() {
return summary;
}
public String getPublishedAt() {
return publishedAt;
}
public Article(String title, String summary, String publishedAt) {
this.title = title;
this.summary = summary;
this.publishedAt = publishedAt;
}
private final String title;
private final String summary;
private final String publishedAt;
}
SpaceflightAPI.kt Interface
package com.example.spaceflightnews.spaceflightNewsAPI
import com.example.spaceflightnews.get.Article
import retrofit2.Call
import retrofit2.http.GET
interface SpaceflightAPI {
@GET("articles")
fun getArticles(): Call<List<Article>>
}
RecyclerAdapter.kt
package com.example.spaceflightnews
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.spaceflightnews.get.Article
class RecyclerAdapter(var listItems: List<Article>, var context: Context) : RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
//Connecting the context then making a LayoutInflater along with it's context of the activity, then selecting the card_items.xml, then using the ViewGroup, making sure
//to put attachToRoot into false
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
this.context = parent.context
val v = LayoutInflater.from(context)
.inflate(R.layout.card_items, parent, false)
return ViewHolder(v)
}
//We connect the ViewHolder class that is in the ViewGroup and then using the those texts to get the JSON data and using listItems original position of that list
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val listItem = listItems[position]
holder.titleText.text = listItem.title
holder.publishedAtText.text = "Published: ${listItem.publishedAt}"
}
//Getting the item count of the max size of the list of items
override fun getItemCount(): Int = listItems.size
//Initializing the TextViews to it's ID here!
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var titleText: TextView = itemView.findViewById(R.id.titleText)
var publishedAtText: TextView = itemView.findViewById(R.id.publishedAtText)
init {
itemView.setOnClickListener {
val intent = Intent(itemView.context, SummeryActivity::class.java)
itemView.context.startActivity(intent)
}
}
}
}
MainActivity.kt
package com.example.spaceflightnews
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.spaceflightnews.get.Article
import com.example.spaceflightnews.spaceflightNewsAPI.SpaceflightAPI
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class MainActivity : AppCompatActivity() {
//Getting the RecyclerView and the Adapter ready
private lateinit var recyclerView: RecyclerView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//Connecting to it's ID from the XML
recyclerView = findViewById(R.id.recyclerView)
//RetroFit
val retrofit = Retrofit.Builder()
.baseUrl("https://api.spaceflightnewsapi.net/v3/")
.addConverterFactory(GsonConverterFactory.create())
.build()
//Creating the SpaceFlight interface and then assigning the same list to get the list of articles within the interface SpaceflightAPI
val jsonSpaceApi = retrofit.create(SpaceflightAPI::class.java)
val call: Call<List<Article>> = jsonSpaceApi.getArticles()
//Instead of using execute, we use enqueue to implement an interface Callback
call.enqueue(object : Callback<List<Article>> {
override fun onResponse(call: Call<List<Article>>, response: Response<List<Article>>) {
//We get the List of Article class as we assign a new variable to connect is as a response.
val articles = response.body()
//We are connecting the RecyclerView to it's LayoutManager, using LinearLayoutManager and connecting to it's context.
recyclerView.layoutManager = LinearLayoutManager(this@MainActivity)
//Then we make the RecyclerAdapter class for the RecyclerView, it's parameters is the List of Article class and it's context.
recyclerView.adapter = RecyclerAdapter(articles!!, this@MainActivity)
}
override fun onFailure(call: Call<List<Article>>, t: Throwable) {
Toast.makeText(this@MainActivity, "${t.message}", Toast.LENGTH_SHORT).show()
}
})
}
}
SummaryActivity.kt (Because wanting to make it simple, it can be used as a Fragment instead of Activity)
package com.example.spaceflightnews
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.MenuItem
import android.widget.TextView
import android.widget.Toast
import com.example.spaceflightnews.get.Article
import com.example.spaceflightnews.spaceflightNewsAPI.SpaceflightAPI
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class SummaryActivity : AppCompatActivity() {
private lateinit var summaryText: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_summery)
//Assigning the ActionBar's support
val actionBar = supportActionBar
actionBar!!.setDisplayHomeAsUpEnabled(true)
summaryText = findViewById(R.id.summeryText)
val retrofit = Retrofit.Builder()
.baseUrl("https://api.spaceflightnewsapi.net/v3/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val jsonSpaceApi = retrofit.create(SpaceflightAPI::class.java)
val call: Call<List<Article>> = jsonSpaceApi.getArticles()
call.enqueue(object : Callback<List<Article>> {
override fun onResponse(call: Call<List<Article>>, response: Response<List<Article>>) {
val articles = response.body()
for (article in articles!!) {
summaryText.text = article.summary
}
}
override fun onFailure(call: Call<List<Article>>, t: Throwable) {
summaryText.text = t.message
Toast.makeText(applicationContext, "${t.message}", Toast.LENGTH_LONG).show()
}
})
}
//This will make the button on the Top Left to destroy the activity and return and returns back to the main activity.
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> finish()
}
return super.onOptionsItemSelected(item)
}
}
CodePudding user response:
My understanding is, that on the SummaryActivity you want to display the selected item's description.
If this is the case, then I don't understand why are you making the API call once again. The SummaryActivity should receive either the description of the selected item or, the Article instance.
CodePudding user response:
Your summary Activity seems to have one text view:
summaryText = findViewById(R.id.summeryText)
But you are resetting it with every article:
for (article in articles!!) {
summaryText.text = article.summary
}
So basically, only the last article's summary will be shown.
Don't do that.
Instead you could pass the summary (and other information) to the Activity:
itemView.setOnClickListener {
val summary = getClickedItemSummary()
val intent = Intent(itemView.context, SummeryActivity::class.java)
intent.putExtra("Summary", summary)
itemView.context.startActivity(intent)
}
Then set it on the SummaryActivity:
summaryText = findViewById(R.id.summeryText)
summaryText.text = intent.getString("Summary")
And then remove the rest of the code that makes an API call again.