android-fragments E/回收机视图:未连接适配器;使用Kotlin在fragment android studio中跳过布局

pexxcrt2  于 2022-11-14  发布在  Android
关注(0)|答案(1)|浏览(126)

我是一个初学者在android工作室与Kotlin我总是挣扎在片段,他们很难科普。我试图实现recyclerview在片段,但它不工作,我不断得到这个错误E/RecyclerView:未连接适配器;跳过布局这里是我的片段

package com.example.pgm

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

/**
 * A simple [Fragment] subclass.
 * Use the [VSFragment.newInstance] factory method to
 * create an instance of this fragment.
 */
class VSFragment : Fragment() {

    // TODO: Rename and change types of parameters
    private var param1: String? = null
    private var param2: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val rv   = view?.findViewById<RecyclerView>(R.id.activeSubsRecycler)

       val subscription = ArrayList<SubscriptionData>()
        subscription.add(SubscriptionData("ghassan","1000","2002/1/1","2002/1/3"))
        subscription.add(SubscriptionData("ameer","2000","2002/1/1","2002/1/3"))
        subscription.add(SubscriptionData("ahmad","9893", "2002/1/1","2002/1/3"))
        subscription.add(SubscriptionData("saif","42452", "2002/1/1","2002/1/3"))
        subscription.add(SubscriptionData("ghassan","453", "2002/1/1","2002/1/3"))
        subscription.add(SubscriptionData("ameer","3354", "2002/1/1","2002/1/3"))
        subscription.add(SubscriptionData("ghassan","1000","2002/1/1","2002/1/3"))
        subscription.add(SubscriptionData("ameer","2000","2002/1/1","2002/1/3"))
        subscription.add(SubscriptionData("ahmad","9893", "2002/1/1","2002/1/3"))
        subscription.add(SubscriptionData("saif","42452", "2002/1/1","2002/1/3"))
        subscription.add(SubscriptionData("ghassan","453", "2002/1/1","2002/1/3"))
        subscription.add(SubscriptionData("ameer","3354", "2002/1/1","2002/1/3"))


        rv?.setHasFixedSize(true);
        if (rv != null) {
            rv.layoutManager = LinearLayoutManager(activity, RecyclerView.VERTICAL, false)
        }
        if (rv != null) {
            rv.adapter = activity?.let { SubscriptionAdapter(it,subscription) }
        }

        return inflater.inflate(R.layout.fragment_v_s, container, false)

    }

    companion object {
        /**
         * Use this factory method to create a new instance of
         * this fragment using the provided parameters.
         *
         * @param param1 Parameter 1.
         * @param param2 Parameter 2.
         * @return A new instance of fragment VSFragment.
         */
        // TODO: Rename and change types and number of parameters
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            VSFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}

我的适配器

package com.example.pgm

import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.recyclerview.widget.RecyclerView

class SubscriptionAdapter (private val context: Context, private val subscriptions : ArrayList<SubscriptionData>):
    RecyclerView.Adapter<SubscriptionAdapter.ViewHolder>() {
    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var my_name = itemView.findViewById<TextView>(R.id.tx_name) as TextView
        var my_value = itemView.findViewById<TextView>(R.id.tx_value) as TextView
        var card_View = itemView.findViewById<CardView>(R.id.cardViewooo) as CardView
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val v = LayoutInflater.from(parent.context).inflate(R.layout.design2,parent, false)
        return ViewHolder(v)
    }


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

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val data = subscriptions[position]
        holder.my_name.text = data.name
        holder.my_value.text = data.value
        holder.card_View.startAnimation(AnimationUtils.loadAnimation(holder.itemView.context,R.anim.main_anim))
        holder.itemView.setOnClickListener {
            val i = Intent(context,Subscription::class.java)
            i.putExtra("name",subscriptions[position].name)
            i.putExtra("value",subscriptions[position].value)
            i.putExtra("startDate",subscriptions[position].startDate)
            i.putExtra("endDate",subscriptions[position].endDate)
            context.startActivity(i)

        }    }
}

可扩展标记语言

<?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=".VSFragment">

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/activeSubsRecycler"

        />

</FrameLayout>

我该怎么办?

qlckcl4x

qlckcl4x1#

onCreateView是你要在inflate中为Fragment显示一个布局,然后返回它的地方。你在最后做的是:

return inflater.inflate(R.layout.fragment_v_s, container, false)

但是,在您这样做之前,Fragment没有视图!当您试图在开始时访问view时,实际上是在调用getView()
获取片段布局的根视图(**由onCreateView**返回的视图)(如果提供)。
因此,当您在onCreateView的开头执行此操作时:

val rv   = view?.findViewById<RecyclerView>(R.id.activeSubsRecycler)

没有view,所以rvnull。所以您尝试执行的所有设置都不会发生,因为您在执行之前对rv进行了null检查,由于它是 null,因此什么也不会发生。
当你想在onCreateView中进行设置时,你需要 * 首先 * 膨胀你的视图,然后在它上面进行所有的设置,* 然后 * 返回该视图:

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    // get your view inflated
    val view = inflater.inflate(R.layout.fragment_v_s, container, false)

    // you can make a list like this, if you make your adapter take a
    // List<SubscriptionData> instead of an ArrayList<SubscriptionData> (which you should)
    val subscription = listOf(
        SubscriptionData("ghassan","1000","2002/1/1","2002/1/3"),
        SubscriptionData("ameer","2000","2002/1/1","2002/1/3"),
        ...
    )

    // Poke around at the stuff in it to get it set up

    // This is just a way to null-check once - if it's found (not null),
    // this 'let' block will run with the RecyclerView as a variable called 'rv'
    view.findViewById<RecyclerView>(R.id.activeSubsRecycler)?.let { rv ->
        // don't use an Activity as a context here - just use requireContext,
        // you'll have access to one at this point
        rv.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false)
        rv.adapter = SubscriptionAdapter(requireContext(),subscription)
    }

    // now return the inflated view, which you've set up!
    return view
}

明白了吗?你膨胀了一个布局,你要传递回来,但是如果你需要在它上面设置任何东西,你在返回它之前做。(你可以在那里更聪明,使用run或更好的apply,但是如果你不知道如何更优雅,不要担心它!)
另一种选择是覆盖onViewCreated来处理您的设置内容--因此在onCreateView中扩展一个视图,然后将其传递到onViewCreated,在那里您可以使用它,进行设置等。

相关问题