Android Fragments 已获取API数据,但无法显示在回收程序视图中

j5fpnvbx  于 11个月前  发布在  Android
关注(0)|答案(1)|浏览(135)

我目前面临着一个问题与API,问题是,我得到的数据是200 OK,但适配器无法显示数据,即使没有错误,我接收数据
这是家园的碎片

package com.example.papb_tubes

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.papb_tubes.databinding.FragmentHomeBinding
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class HomeFragment : Fragment() {

    private var _binding: FragmentHomeBinding? = null
    private val binding get() = _binding!!

    private lateinit var apiService: ApiService
    private lateinit var weatherAdapter: WeatherAdapter

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentHomeBinding.inflate(inflater, container, false)
        return binding.root
    }

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

        apiService = ApiConfig.getApiService("London") // Set initial city

        weatherAdapter = WeatherAdapter(object : WeatherAdapter.OnClickListener {
            override fun onClickItem(data: WeatherResponse) {
                // Handle item click if needed
            }
        })

        binding.rvHomepage.apply {
            layoutManager = LinearLayoutManager(requireContext())
            adapter = weatherAdapter
        }

        binding.ivPerson.setOnClickListener {
            // Navigate to profile fragment if needed
        }

        // Fetch initial weather data for London
        fetchWeatherData("London")
    }

    private fun fetchWeatherData(city: String) {
        apiService = ApiConfig.getApiService(city)

        apiService.getAllProvinsi(city).enqueue(object : Callback<WeatherResponse> {
            override fun onResponse(
                call: Call<WeatherResponse>,
                response: Response<WeatherResponse>
            ) {
                if (response.isSuccessful) {
                    val weatherResponse = response.body()
                    if (weatherResponse != null) {
                        Log.d("WeatherResponse", weatherResponse.toString())
                        weatherAdapter.submitData(weatherResponse)
                    } else {
                        Log.e("WeatherResponse", "Response body is null")
                    }
                } else {
                    Log.e("WeatherResponse", "Error: ${response.code()}")
                }
            }

            override fun onFailure(call: Call<WeatherResponse>, t: Throwable) {

            }
        })
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

字符串
这是适配器

package com.example.papb_tubes

import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.example.papb_tubes.databinding.ItemRowBinding

class WeatherAdapter(
    private val onClickItem: OnClickListener // Use the correct interface name here
) : RecyclerView.Adapter<WeatherAdapter.ViewHolder>() {

    private val differCallback = object : DiffUtil.ItemCallback<WeatherResponse>() {
        override fun areItemsTheSame(oldItem: WeatherResponse, newItem: WeatherResponse): Boolean {
            return oldItem.id == newItem.id
        }
        override fun areContentsTheSame(oldItem: WeatherResponse, newItem: WeatherResponse): Boolean = oldItem.hashCode() == newItem.hashCode()

    }

    val differ = AsyncListDiffer(this, differCallback)
    fun submitData(value: WeatherResponse) = differ.submitList(listOf(value))
    inner class ViewHolder(private val binding: ItemRowBinding) :
        RecyclerView.ViewHolder(binding.root) {

        fun bind(data: WeatherResponse) {
            val temp = (data.main.temp) - 273
            binding.apply {
                tvNamakota.text = data.name.toString()
                tvTemperatur.text = temp.toString()
                tvTipe.text = data.weather[0].description.toString()

                root.setOnClickListener {
                    onClickItem.onClickItem(data)
                }
            }
        }
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val data = differ.currentList[position]
        Log.d("WeatherAdapter", "Data size: ${differ.currentList.size}")
        data.let { holder.bind(data) }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        return ViewHolder(ItemRowBinding.inflate(inflater,parent,false))
    }

    override fun getItemCount(): Int = differ.currentList.size

    interface OnClickListener {
        fun onClickItem(data: WeatherResponse)
    }
}


这是一个顶点

package com.example.papb_tubes

import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

class ApiConfig {
    companion object {
        private const val BASE_URL = "https://api.openweathermap.org/data/2.5/"
        private const val API_KEY = ""

        fun getApiService(city: String): ApiService {
            val loggingInterceptor =
                HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)

            val authInterceptor = Interceptor { chain ->
                val originalRequest = chain.request()
                val newUrl = originalRequest.url.newBuilder()

                    .addQueryParameter("appid", API_KEY)
                    .build()

                val newRequest = originalRequest.newBuilder()
                    .url(newUrl)
                    .build()

                chain.proceed(newRequest)
            }

            val client = OkHttpClient.Builder()
                .addInterceptor(loggingInterceptor)
                .addInterceptor(authInterceptor)
                .build()

            val retrofit = Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build()

            return retrofit.create(ApiService::class.java)
        }
    }
}


这就是服务

package com.example.papb_tubes

import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Query

interface ApiService {
    @GET("weather")
        fun getAllProvinsi(
            @Query("q") city:String,
    ): Call<WeatherResponse>
}


这是homefragment.xml文件

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".HomeFragment"
    android:background="@color/primary">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_ellipse"
        android:id="@+id/iv_elipse_1"/>
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_ellipse"
        android:id="@+id/iv_elipse_2"
        android:layout_marginTop="300dp"
        android:layout_marginLeft="160dp"/>
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_ellipse"
        android:id="@+id/iv_elipse_3"
        android:layout_marginTop="500dp"
        android:layout_marginLeft="0dp"/>
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_rectangle"
        android:layout_gravity="right"
        android:id="@+id/iv_rectangle1"/>
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_rectangle"
        android:layout_gravity="right|bottom"
        android:id="@+id/iv_rectangle2"/>
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_rectangle"
        android:layout_gravity="left|center"
        android:scaleX="-1"
        android:id="@+id/iv_rectangle3"/>
    <LinearLayout
        android:id="@+id/ll_homepage"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_marginTop="20sp"
        android:layout_marginBottom="20sp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:paddingLeft="20dp"
        android:paddingTop="30dp"
        android:paddingRight="20dp"
        >

        <TextView
            android:id="@+id/tv_username_homepage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:fontFamily="@font/poppins_r"
            android:text="Welcome, Username"
            android:textSize="15sp"
            android:textStyle="normal"
            android:textColor="@color/white"/>

        <ImageView
            android:id="@+id/iv_person"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:layout_weight="1"
            android:paddingLeft="90dp"
            android:src="@drawable/baseline_person_24" />
    </LinearLayout>
        <EditText
            android:id="@+id/etSearch"
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:hint="Search City"
            android:imeOptions="actionSearch"
            android:inputType="text"
            android:layout_margin="16dp"/>
    <TextView
        android:layout_marginTop="30dp"
        android:id="@+id/tv_home"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:fontFamily="@font/poppins_r"
        android:text="Home"
        android:textSize="20sp"
        android:textStyle="bold"
        android:textColor="@color/white"/>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_homepage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="10dp" />
        <androidx.recyclerview.widget.RecyclerView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/tv_weather"
            android:layout_gravity="center"
            android:layout_marginTop="10dp"/>
    </LinearLayout>

</FrameLayout>


我希望我可以接收到可以在回收器视图中显示的数据
我刚才试的是
1.添加日志以确保数据为200 OK
1.我使用了一个类似submitList和etc的函数来创建一个回收器视图,但是失败了
编辑:
1.我使用按钮手动插入搜索栏上的值,但它最终导致崩溃

whitzsjs

whitzsjs1#

我刚刚弄清楚,使用logcat将是非常有用的,我发现我完全错误的时候分配的类类型有浮动类型,但我分配它使用扩展是Int

相关问题