java - 如何从 API 显示一定数量的图像 - Kotlin - 改造
问题描述
我正在从 API 调用数据以显示它以供使用,但在我的情况下,我想显示 API 的最新 4 个图像,我不想调用所有这些图像
那么正确的方法是什么?
这是我的代码:
界面:
interface facebookInterface {
@GET(" ")
fun getServices(): Call<List<facebookData>>
companion object Factory {
fun create(): facebookInterface {
val retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("API_URL")
.build()
return retrofit.create(facebookInterface::class.java)
}
}
}
适配器:
class facebookAdapter(var countryList: List<facebookData>, var activity: MainActivity): RecyclerView.Adapter<facebookAdapter.ViewHolder>(){
lateinit var context: Context
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): facebookAdapter.ViewHolder {
context = parent.context!!
val view = LayoutInflater.from(context).inflate(R.layout.facebook_list_item, parent, false)
return ViewHolder(view)
}
override fun getItemCount(): Int {
return countryList.size
}
override fun onBindViewHolder(holder: facebookAdapter.ViewHolder, position: Int) {
holder.name.text = countryList[position].source
holder.capital.text = countryList[position].imageLink
Picasso.get()
.load(countryList[position].imageUrl)
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
.networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE)
.into(holder.thumbnailUrl)
}
class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
val name: TextView = itemView.findViewById(R.id.country_name)
val capital: TextView = itemView.findViewById(R.id.country_capital)
val thumbnailUrl: ImageView = itemView.findViewById(R.id.country_flag)
}
}
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:id="@+id/frame_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:id="@+id/list_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="4dp"
app:contentPadding="8dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/list_constraint"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/country_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="monospace"
android:text="TextView"
android:textSize="24sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/country_capital"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:fontFamily="monospace"
android:text="TextView"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/country_name" />
<ImageView
android:id="@+id/country_flag"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</FrameLayout>
活动:
val recyclerView: RecyclerView = findViewById(R.id.list_recycler4)
recyclerView.layoutManager = LinearLayoutManager(this)
val facebookInterface = facebookInterface.Factory.create()
val facebok: Call<List<facebookData>> = facebookInterface.getServices()
facebok.enqueue(object : Callback<List<facebookData>> {
override fun onFailure(call: Call<List<facebookData>>, t: Throwable) {
Log.d("xxxx", t.toString())
Toast.makeText(this@MainActivity, t.message, Toast.LENGTH_SHORT).show()
}
override fun onResponse(
call: Call<List<facebookData>>,
response: Response<List<facebookData>>
) {
Log.d("xxxx", response.body().toString())
val list = response.body()!!
recyclerView.adapter = facebookAdapter(list, this@MainActivity)
}
})
数据类:
data class facebookData (
val imageUrl : String,
val imageLink: String,
val source: String
)
我正在获取数据,我可以在设备上看到它,但有没有办法只显示来自 API 的最新 4 张图像?
以及如何链接每个图像的 url,以便用户可以转到每个图像的 url
“英语不是我的母语,如果你不明白我会解释更多”
解决方案
正如 Teo 所说,您最好将过滤器直接应用于您的 API 调用,但如果这不可能,您可以删除您收到的列表。我能想到的主要有两种方法,可以得到你想要的,首先是制作一个子列表,然后按如下方式分配适配器。
val trimmedList = if(list.size > 4){
list.subList(fromIndex = 0, toIndex = 3)
} else {
list
}
recyclerView.adapter = facebookAdapter(trimmedList , this@MainActivity)
在 Recycler View Adapter 中覆盖 itemCount 方法的第二种方法,同样的逻辑应该适用于那里。如下。
override fun getItemCount(): Int {
return if(countryList.size > 4) {
4
} else {
countryList.size
}
}
对于您答案的第二部分,我添加了以下代码供您参考,但我仍然相信您最好了解正在发生的事情。
要在浏览器中打开 url,首先需要从 Adapter 回调到 MainActivity。
您的适配器将被修改如下。
class facebookAdapter(var countryList: List<facebookData>,
private val facebookAdapterCallback: FacebookAdapterCallback)
: RecyclerView.Adapter<facebookAdapter.ViewHolder>(){
lateinit var context: Context
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): facebookAdapter.ViewHolder {
context = parent.context!!
val view = LayoutInflater.from(context).inflate(R.layout.facebook_list_item, parent, false)
return ViewHolder(view)
}
override fun getItemCount(): Int {
return countryList.size
}
override fun onBindViewHolder(holder: facebookAdapter.ViewHolder, position: Int) {
holder.name.text = countryList[position].source
holder.capital.text = countryList[position].imageLink
holder.thumbnailUrl.setOnClickListener {
facebookAdapterCallback.onFacebookAdapterItemClick(countryList[position])
}
Picasso.get()
.load(countryList[position].imageUrl)
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
.networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE)
.into(holder.thumbnailUrl)
}
class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
val name: TextView = itemView.findViewById(R.id.country_name)
val capital: TextView = itemView.findViewById(R.id.country_capital)
val thumbnailUrl: ImageView = itemView.findViewById(R.id.country_flag)
}
interface FacebookAdapterCallback{
fun onFacebookAdapterItemClick(data: facebookData)
}
}
接下来,我们将不得不修改您的活动,以在其中实现上述接口
class MainActivity : AppCompatActivity(), facebookAdapter.FacebookAdapterCallback {
override fun onFacebookAdapterItemClick(data: facebookData) {
openLinkInBrowser(this@MainActivity, data.imageLink)
}
fun openLinkInBrowser(context: Context, url: String) {
try {
val url = if (Uri.parse(url).scheme == null || !url.startsWith("https://") && !url.startsWith("http://")) {
"https://$url"
} else url
val webPage: Uri = Uri.parse(url)
val intent = Intent(Intent.ACTION_VIEW, webPage)
if (intent.resolveActivity(context.packageManager) != null) {
context.startActivity(intent)
} else {
Toast.makeText(context, "No App Available for this action", Toast.LENGTH_SHORT).show()
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
我还添加了一个帮助方法来在浏览器中打开链接,它使用默认的 Android Intents 并检查可以执行此操作的可用应用程序。我们还检查 URL 是否已添加http
或https
附加,否则我们添加它。
虽然我已经为您提供了代码,但我仍然建议您在执行此操作之前了解正在发生的事情。
推荐阅读
- java - 在 Java 中为 servlet 分配异常
- swiftui - SwiftUI/UIKit Nav 组合中的 iOS 15 状态栏背景颜色
- netsuite - 获取 Invoice -Netsuite 中的“行项目”描述字段
- ethereum - 智能合约可以检查当前区块中的交易吗?
- c# - Environment.CurrentDirectory 是如何工作的?
- flutter - 如何处理缓存,因为缓存包不适用于 pub.dev 中的颤振版本 2
- windows-subsystem-for-linux - 在 WSL 容器中的 CentOS 启动时运行挂载
- reactjs - React native:为什么我会收到“未捕获的错误:超出最大调用堆栈大小”?
- javascript - 无法读取 useEffect 中未定义的属性“样式”
- python - 在 3 组中打印可能的子字符串并与 python 中的字典键匹配