gpt4 book ai didi

android - fragment 重建后 ViewModel 不保留数据

转载 作者:行者123 更新时间:2023-12-02 12:31:11 25 4
gpt4 key购买 nike

我有三个带有底部导航栏的 fragment 应用程序,我使用 NavigationUI 进行切换。我还有一个创建数据的 View 模型(来自 assets foolder), fragment 观察我用来填充回收器 View 的实时数据数组列表。

我的问题是每当我切换 fragment 时,当 fragment 被重新创建时,我不希望每次重新创建 fragment 时都进行数据检索。因此使用了 View 模型。但就我而言, View 模型中的数据没有保留。我附上了 fragment 和 View 模型代码。我不确定这里有什么问题。

我已经尝试记录 aaraylist 中的条目数,如果我不调用填充数组列表的例程,它会返回 0。

歌曲 fragment

private const val TAG = "Songs Fragment"

class SongsFragment : Fragment(), android.widget.SearchView.OnQueryTextListener {

private val viewmodel: SongListViewModel by lazy { ViewModelProviders.of(this).get(SongListViewModel::class.java)}

private val songListAdapter = SongListAdapter(arrayListOf())
private var raga = "All"

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {

Log.d(TAG, "onCreateView called")

return inflater.inflate(R.layout.fragment_songs, container, false)
}

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

Log.d(TAG, "onViewCreated called")



val context: FragmentActivity? = activity

(activity as AppCompatActivity).supportActionBar?.subtitle = "Songs"

val assetsPath: AssetManager? = context?.assets
val assetList = assetsPath?.list("")
if (assetList != null) {
for (item in assetList)
Log.d("SongsFragment", assetsPath.toString() + item)
}

arguments?.let {
raga = SongsFragmentArgs.fromBundle(it).raga
}

Log.d("Song Fragment", "Raga passed: " + raga)

Log.d(TAG, "Number of songs: " + viewmodel.songList.size.toString())

if (raga == "All") {
viewmodel.allSongs()
viewmodel.allSongs(assetsPath!!)
} else {
viewmodel.songsForRaga(assetsPath!!, raga)
}

Log.d(TAG, ": Songlist size: " + viewmodel.songList.size.toString())


songList_RecyclerView.apply {
layoutManager = LinearLayoutManager(context)
adapter = songListAdapter
}

songSearchView.setOnQueryTextListener(this)

observeViewModel()
}

override fun onQueryTextSubmit(query: String): Boolean {

return false
}

override fun onQueryTextChange(newText: String): Boolean {
Log.i("Song Fragment", "Text change:" + newText.length.toString())

viewmodel.songSearchFilter(newText)

return false
}

fun observeViewModel() {
viewmodel.songs.observe(this, Observer { songs ->
songs?.let {
Log.d("Song Fragment", "ObserveViewModel")
songListAdapter.updateSongList(songs)
}
})
}
}

歌曲 ListView 模型

private const val TAG = "SongListViewModel"

class SongListViewModel : ViewModel() {

val songs = MutableLiveData<ArrayList<Song>>()
var songList = arrayListOf<Song>()

fun allSongs() {
songList = getAllSongs()

songs.value = ArrayList(songList.sortedWith(compareBy({ it.songName })))
}

fun allSongs(assetsPath: AssetManager) {

Log.d(TAG, "allSongs called")
Log.d(TAG, "Number of songs: " + songList.size.toString())
getAllSongs(assetsPath)
songs.value = ArrayList(songList.sortedWith(compareBy({ it.songName })))
}

fun songSearchFilter(text: String) {

var filteredList = arrayListOf<Song>()
filteredList.clear()

if (text.length != 0) {
for (song in songList) {
if (song.songName.toLowerCase().contains(text)) {
filteredList.add(song)
}

}
songs.value = ArrayList(filteredList.sortedWith(compareBy({ it.songName })))

} else {

songs.value = ArrayList(songList.sortedWith(compareBy({ it.songName })))
}


}

fun songsForRaga(assetsPath: AssetManager, raga: String) {

Log.d(TAG, "songsForRaga called")

var filteredList = arrayListOf<Song>()
filteredList.clear()
allSongs(assetsPath)
for (song in songList) {
if (song.raga == raga) {
filteredList.add(song)
}
}
songs.value = ArrayList(filteredList.sortedWith(compareBy({ it.songName })))
}

fun getAllSongs(assetsPath: AssetManager) {

Log.d(TAG, "getAllSongs called")
val bufferedReader = assetsPath.open("test.csv").bufferedReader()
val lineList = mutableListOf<String>()

bufferedReader.useLines { lines -> lines.forEach { lineList.add(it) } }
lineList.forEach {
val parts = it.split(",")
songList.add(Song(parts[0], parts[1], parts[2], parts[3], ""))
}


}
}

最佳答案

通过将 fragment 父 Activity 而不是 fragment 本身传递给 viewmodelprovider 来检索 View 模型。

ViewModelProviders.of(activity).get(SongListViewModel::class.java)

关于android - fragment 重建后 ViewModel 不保留数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58704965/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com