我正在做一个项目,现在在这上面坚持了3天。这个项目读取了一个JSON,使用了一个适配器,还有碎片。
json:https://opendata.visitflanders.org/accessibility/activities/sport_v2.json的子目录
运动项目片段列表.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ListOfSportsFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="List of sports and locations"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.022" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvSportList"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<Button
android:id="@+id/btnBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Back"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.049"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.976" />
</androidx.constraintlayout.widget.ConstraintLayout>
ListOfSportsFragment.kt:
package vives.be.bedoerikproject
import SportsAdapter
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.get
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.fragment_list_of_sports.*
import kotlinx.android.synthetic.main.fragment_list_of_sports.view.*
import org.json.JSONException
import org.json.JSONObject
class ListOfSportsFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_list_of_sports, container, false)
val sportList: ArrayList<SportModelClass> = ArrayList()
try {
// As we have JSON object, so we are getting the object
//Here we are calling a Method which is returning the JSON object
val obj = JSONObject("Sports.json")
// fetch JSONArray named users by using getJSONArray
val sportsArray = obj.getJSONArray("sports")
// Get the users data using for loop i.e. id, name, email and so on
for (i in 0 until sportsArray.length()) {
// Create a JSONObject for fetching single User's Data
val sport = sportsArray.getJSONObject(i)
// Fetch id store it in variable
val id = sport.getInt("business_product_id")
val name = sport.getString("name")
val city_name = sport.getString("city_name")
val postal_code = sport.getInt("postal_code")
val website = sport.getString("website")
val phone = sport.getString("phone1")
val email = sport.getString("email")
// Now add all the variables to the data model class and the data model class to the array list.
val sportDetails =
SportModelClass(id, name, postal_code, city_name, phone, email, website)
// add the details in the list
sportList.add(sportDetails)
}
} catch (e: JSONException) {
//exception
e.printStackTrace()
}
// Set the LayoutManager that this RecyclerView will use.
rvSportList.layoutManager = LinearLayoutManager(activity) //rv = reciycleview
// Adapter class is initialized and list is passed in the param.
val itemAdapter = SportsAdapter(requireContext(), sportList)
// adapter instance is set to the recyclerview to inflate the items.
rvSportList.adapter = itemAdapter
return view
}
}
运动适配器:
import vives.be.bedoerikproject.SportModelClass
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import vives.be.bedoerikproject.R
import kotlinx.android.synthetic.main.sport_model_layout.view.*
class SportsAdapter(val context: Context, val items: ArrayList<SportModelClass>) :
RecyclerView.Adapter<SportsAdapter.ViewHolder>() {
/**
* Inflates the item views which is designed in xml layout file
*
* create a new
* {@link ViewHolder} and initializes some private fields to be used by RecyclerView.
*/
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
LayoutInflater.from(context).inflate(
R.layout.sport_model_layout,
parent,
false
)
)
}
/**
* Binds each item in the ArrayList to a view
*
* Called when RecyclerView needs a new {@link ViewHolder} of the given type to represent
* an item.
*
* This new ViewHolder should be constructed with a new View that can represent the items
* of the given type. You can either create a new View manually or inflate it from an XML
* layout file.
*/
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = items.get(position)
holder.name.text = item.name
holder.city_name.text = item.city_name
holder.postal_code.text = item.postal_code.toString()
holder.website.text = item.website
holder.phone1.text = item.phone1
holder.email.text = item.email
}
/**
* Gets the number of items in the list
*/
override fun getItemCount(): Int {
return items.size
}
/**
* A ViewHolder describes an item view and metadata about its place within the RecyclerView.
*/
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
// Holds the TextView that will add each item to
val name = view.name
val city_name = view.city_name
val postal_code = view.postal_code
val website = view.website
val phone1 = view.phone1
val email = view.email
}
}
SportModelClass.kt:
package vives.be.bedoerikproject
class SportModelClass (
val business_product_id : Int,
val name : String,
val postal_code : Int,
val city_name : String,
val phone1 : String,
val email : String,
val website : String
)
我在ListOfSportsFragment的第60行看到一个错误,这个错误是:E/AndroidRuntime: FATAL EXCEPTION: main Process: vives.be.bedoerikproject, PID: 7302 java.lang.NullPointerException: Attempt to invoke virtual method 'androidx.recyclerview.widget.RecyclerView$LayoutManager androidx.recyclerview.widget.RecyclerView.getLayoutManager()' on a null object reference at vives.be.bedoerikproject.ListOfSportsFragment.onCreateView(ListOfSportsFragment.kt:60) at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2995) at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:523) at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261) at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1840) at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1764) at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1701) at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:488) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) Disconnected from the target VM, address: 'localhost:52495', transport: 'socket'
5条答案
按热度按时间x33g5p2x1#
您可以在xml文件中设置布局管理器。
并且不必将上下文传递到适配器中,则可以在onCreateViewHolder中访问上下文,如下所示
hc8w905p2#
你能试着把你的代码从onCreateView移到onViewCreated fun并使用'context'而不是'requireContext()'吗?希望能帮上忙。
tcomlyy63#
按如下方式使用requireActivity():
vwoqyblh4#
只有在片段
onCreateView()
返回后,才能像这样使用合成视图绑定。使用合成代码(如
rvSportList.layoutManager = LinearLayoutManager(activity) //rv = reciycleview
)将视图设置代码移动到onViewCreated()
。另外值得注意的是,提供合成视图绑定的kotlin-android-extensions插件已被弃用,请考虑改用view binding。
ruarlubt5#
这是您的错误:
它试图调用一个方法(
getLayoutManager()
),但是它不是RecyclerView
,它是null。不能调用null对象上的方法,所以你得到NullPointerException
这是第60行,其中日志告诉您发生了错误:
所以如果问题是在一个空的
RecyclerView
上调用方法,并且它发生在那一行,那么rvSportList
就不是RecyclerView
,它是 null。您将从Kotlin合成扩展中获得神奇的
rvSportList
变量,该扩展已经被弃用很长时间了。您应该使用View Binding来代替-但同时,请尝试以下方法-找到视图的基本方法: