【发布时间】:2021-11-04 09:12:00
【问题描述】:
我制作了一个基本的购物清单应用程序,它利用回收站视图来显示清单项目。我正在尝试使用带有片段的导航来添加设置屏幕。当我打开应用程序时,我遇到了我的 recyclerview 和数据显示的问题,但是当我转到设置菜单然后返回主屏幕时,没有 recyclerview。 Logcat 显示错误“W/RecyclerView:未连接适配器;跳过布局”
MainActivity.kt
package com.example.shoppinglist
import android.app.Dialog
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.findNavController
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.floatingactionbutton.FloatingActionButton
class MainActivity : AppCompatActivity(), RVAdapter.ListItemClickInterface {
lateinit var itemsRV: RecyclerView
lateinit var addFAB: FloatingActionButton
lateinit var list: List<ListItems>
lateinit var RVAdapter: RVAdapter
lateinit var viewModel: ViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupActionBarWithNavController(findNavController(R.id.fragment_main))
itemsRV = findViewById(R.id.recyclerView)
addFAB = findViewById(R.id.idFABAdd)
list = ArrayList<ListItems>()
RVAdapter = RVAdapter(list, this)
itemsRV.layoutManager = LinearLayoutManager(this)
itemsRV.adapter = RVAdapter
val repository = Repository(Database(this))
val factory = ViewModelFactory(repository)
viewModel = ViewModelProvider(this, factory).get(ViewModel::class.java)
viewModel.getAllListItems().observe(this, Observer {
RVAdapter.list = it
RVAdapter.notifyDataSetChanged()
})
addFAB.setOnClickListener {
openDialog()
}
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.fragment_main)
return navController.navigateUp() || super.onSupportNavigateUp()
}
fun openDialog() {
val dialog = Dialog(this)
dialog.setContentView(R.layout.add_dialog)
val cancelButton = dialog.findViewById<Button>(R.id.idBtnCancel)
val addButton = dialog.findViewById<Button>(R.id.idBtnAdd)
val itemEdt = dialog.findViewById<EditText>(R.id.idEditItemName)
val itemQuantityEdt = dialog.findViewById<EditText>(R.id.idEditItemQuantity)
cancelButton.setOnClickListener {
dialog.dismiss()
}
addButton.setOnClickListener {
val itemName: String = itemEdt.text.toString()
val itemQuantity: String = itemQuantityEdt.text.toString()
if (itemName.isNotBlank() && itemQuantity.isNotBlank()) {
val items = ListItems(itemName, itemQuantity)
viewModel.insert(items)
Toast.makeText(applicationContext, "Item Added", Toast.LENGTH_SHORT).show()
RVAdapter.notifyDataSetChanged()
dialog.dismiss()
} else {
Toast.makeText(applicationContext, "Enter All Info To Add Item",
Toast.LENGTH_SHORT)
.show()
}
}
dialog.show()
}
override fun onItemClick(listItems: ListItems) {
viewModel.delete(listItems)
RVAdapter.notifyDataSetChanged()
Toast.makeText(applicationContext, "Item Deleted", Toast.LENGTH_SHORT).show()
}
}
HomeFragment.kt
package com.example.shoppinglist
import android.os.Build
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.RequiresApi
import androidx.navigation.fragment.findNavController
import androidx.preference.PreferenceManager
import kotlinx.android.synthetic.main.fragment_home.*
class HomeFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home, container, false)
}
@RequiresApi(Build.VERSION_CODES.N)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
idFABSettings.setOnClickListener {
findNavController().navigate(R.id.action_homeFragment_to_settingsFragment)
}
loadSettings()
}
@RequiresApi(Build.VERSION_CODES.N)
private fun loadSettings(){
val sp = PreferenceManager.getDefaultSharedPreferences(context)
val theme = sp.getBoolean("theme_switch",false)
}
}
SettingsFragment.kt
package com.example.shoppinglist
import android.os.Bundle
import androidx.preference.PreferenceFragmentCompat
class SettingsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".MainActivity">
<fragment
android:id="@+id/fragment_main"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation"
/>
</RelativeLayout>
fragment_home.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="?attr/colorPrimary"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/list_rv_item"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/idFABAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:backgroundTint="?attr/colorSecondary"
android:contentDescription="Add Item Button"
android:src="@drawable/ic_add"
android:tint="@android:color/white" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/idFABSettings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:backgroundTint="?attr/colorSecondary"
android:contentDescription="Add Item Button"
android:src="@drawable/ic_settings"
android:tint="@android:color/white" />
</RelativeLayout>
导航.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation 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/navigation"
app:startDestination="@id/homeFragment">
<fragment
android:id="@+id/settingsFragment"
android:name="com.example.shoppinglist.SettingsFragment"
android:label="Settings" >
<action
android:id="@+id/action_settingsFragment_to_homeFragment"
app:destination="@id/homeFragment" />
</fragment>
<fragment
android:id="@+id/homeFragment"
android:name="com.example.shoppinglist.HomeFragment"
android:label="Shopping List"
tools:layout="@layout/fragment_home" >
<action
android:id="@+id/action_homeFragment_to_settingsFragment"
app:destination="@id/settingsFragment" />
</fragment>
</navigation>
不确定是否需要更多信息。提前道歉 - 我是 android studio 和 kotlin 的新手。
【问题讨论】:
-
lateinit与它无关,因为该适配器在onCreate()中初始化。 @Tokorae,您在哪里托管这些片段?如果您在 MainActivity 中托管您的 Fragment,那么在您的 MainActivity 中有一个 RecyclerView 会很奇怪。如果屏幕上也有 RecyclerView,那么如何有空间显示您正在导航的所有片段? -
通常,如果您使用 Fragments,托管 Activity 中的代码将是最少的。可能有一个布局会显示一些小的持久性内容,例如共享操作栏和可能的侧边抽屉菜单,以及占据大部分屏幕的片段容器。但由 Fragments 来显示应用程序的主要内容。
-
activity_main.xml中的fragment,包含androidx.navigation.fragment.NavHostFragment,就是你说的那个吗?
标签: android-studio kotlin android-recyclerview