试图影响片段内的视图的问题

时间:2019-05-04 00:07:08

标签: android android-fragments kotlin android-recyclerview

因此,我目前正在使用Android Studio构建一个Android应用。我正在使用Kotlin构建它,有关该应用程序的特定要点是:

  • 我正在将BottomNavigationViewNavFragmentView一起使用。那部分工作正常。
  • 我有5个主要片段,它们是应用程序的主要部分,基本上,当您点击Navigation Graph的一项时,正确的片段就会拉到主要的BottonNavigationView上。

我目前无法实现使用NavFragmentView来显示某种日历的RecyclerView

我已经准备好用户界面,并用GridLayout适配器内部列表中的静态数据填充RecyclerView

我接下来要做的是使用RecyclerView从API中获取JSON数据,然后使用OkHTTP为其提供格式。到目前为止,一切工作正常,JSON格式正确并已获得。当我想将其传递给适配器时,麻烦就开始了。

在此之前,我在访问内容时遇到了一些麻烦,因为当我刚接触Kotlin和Android时,我在直接从片段访问内容时遇到了麻烦,但是后来我发现可以将片段的主视图分配给变量并从那里参考。这部分解决了我的问题。所以,我的代码是这样的:

MesFragment.kt-这是我的片段的Kotlin文件,如您所见,我将主视图分配给了GSON变量,我不得不在main函数之外创建它,因为当尝试在mesView函数中分配适配器,它无权访问视图

fetchMes()

MesAdapter.kt-这是我的适配器,如您所见,我已经评论了我的静态列表,而我唯一要做的UI更改是class MesFragment : Fragment() { var mesView : View? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { mesView = inflater.inflate(R.layout.fragment_mes, container, false) //mesView.calendario_mes.adapter = MesAdapter() fetchInfoMes("201905") return mesView } fun fetchInfoMes(mes: String) { val url = "https://www.myoriginalsite.com/api/mes/"+ mes +"/-0500/norte" val request = Request.Builder().url(url).build() val client = OkHttpClient() client.newCall(request).enqueue(object: Callback { override fun onResponse(call: Call, response: Response) { var body = response.body()?.string() val gson = GsonBuilder().create() val mesFeed : List<FechaCompleta> = gson.fromJson(body, object: TypeToken<List<FechaCompleta>>() {}.type) mesView?.calendario_mes?.adapter = MesAdapter(mesFeed) } override fun onFailure(call: Call, e: IOException) { println("Error") } }) } } class FechaCompleta(val vacia: Boolean, val imagen_signo: String, val imagen_luna: String, val fecha: String, val dia: String, val id_entrada: Int)

mes_fecha.text

一旦打开片段,应用程序将关闭,并且出现此错误:

class MesAdapter(val mesFeed: List<FechaCompleta>): RecyclerView.Adapter<MesViewHolder>() {

    //val list = listOf<String>("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31")

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MesViewHolder {
        val layoutInflater = LayoutInflater.from(parent?.context)
        val cell = layoutInflater.inflate(R.layout.celda_mes_layout, parent, false)

        return MesViewHolder(cell)
    }

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

    override fun onBindViewHolder(holder: MesViewHolder, position: Int) {
        holder?.view?.mes_fecha.text = mesFeed[position].dia
    }

}

class MesViewHolder(val view: View): RecyclerView.ViewHolder(view) {

}

1 个答案:

答案 0 :(得分:0)

OkHttpClient在后台线程上调用回调。

所以您应该:

1。)改用Retrofit,它会在UI线程上调用您的回调

2。)使用处理程序从后台线程返回UI线程

private val handler = Handler(Looper.getMainLooper())

call.enqueue(object: Callback {
        override fun onResponse(call: Call, response: Response) {
            var body = response.body()?.string()

            val gson = GsonBuilder().create()

            val mesFeed : List<FechaCompleta> = gson.fromJson(body, object: TypeToken<List<FechaCompleta>>() {}.type)

            handler.post {
                mesView?.calendario_mes?.adapter = MesAdapter(mesFeed)
            }
        }

        override fun onFailure(call: Call, e: IOException) {
            println("Error")
        }
})