Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 片段重新创建后,ViewModel不保留数据_Android_Kotlin_Viewmodel - Fatal编程技术网

Android 片段重新创建后,ViewModel不保留数据

Android 片段重新创建后,ViewModel不保留数据,android,kotlin,viewmodel,Android,Kotlin,Viewmodel,我有三个带有底部导航栏的片段应用程序,我使用NavigationUI切换。 我还有一个viewmodel,它创建数据(来自assets愚弄者),片段观察我用来填充回收器视图的实时数据数组列表 我的问题是,每当我切换片段时,当片段被重新创建时,我不希望每次重新创建片段时都发生数据检索。因此使用了viewmodel。但在我的例子中,viewmodel中的数据不会被保留。 我已经附加了片段和viewmodel代码。我不确定这里出了什么问题 我尝试记录aaraylist中的条目数,如果我不调用填充arr

我有三个带有底部导航栏的片段应用程序,我使用NavigationUI切换。 我还有一个viewmodel,它创建数据(来自assets愚弄者),片段观察我用来填充回收器视图的实时数据数组列表

我的问题是,每当我切换片段时,当片段被重新创建时,我不希望每次重新创建片段时都发生数据检索。因此使用了viewmodel。但在我的例子中,viewmodel中的数据不会被保留。 我已经附加了片段和viewmodel代码。我不确定这里出了什么问题

我尝试记录aaraylist中的条目数,如果我不调用填充arraylist的例程,它将返回0

歌曲片段 SongListViewModel
private const val TAG=“SongListViewModel”
类SongListViewModel:ViewModel(){
val songs=MutableLiveData()
var songList=arrayListOf()
趣味所有歌曲(){
歌曲列表=getAllSongs()
songs.value=ArrayList(songList.sortedWith(compareBy({it.songName})))
}
趣味所有歌曲(AssetPath:AssetManager){
Log.d(标记“调用的所有歌曲”)
Log.d(标记“歌曲数:”+songList.size.toString())
getAllSongs(资产路径)
songs.value=ArrayList(songList.sortedWith(compareBy({it.songName})))
}
趣味歌曲搜索过滤器(文本:字符串){
var filteredList=arrayListOf()
filteredList.clear()
如果(text.length!=0){
for(歌曲列表中的歌曲){
if(song.songName.toLowerCase().contains(text)){
filteredList.add(歌曲)
}
}
songs.value=ArrayList(filteredList.sortedWith(compareBy({it.songName})))
}否则{
songs.value=ArrayList(songList.sortedWith(compareBy({it.songName})))
}
}
有趣的歌曲(AssetPath:AssetManager,raga:String){
Log.d(标记为“songsForRaga called”)
var filteredList=arrayListOf()
filteredList.clear()
所有歌曲(资产路径)
for(歌曲列表中的歌曲){
if(song.raga==raga){
filteredList.add(歌曲)
}
}
songs.value=ArrayList(filteredList.sortedWith(compareBy({it.songName})))
}
趣味getAllSongs(AssetPath:AssetManager){
Log.d(标记“getAllSongs调用”)
val bufferedReader=assetsPath.open(“test.csv”).bufferedReader()
val lineList=mutableListOf()
bufferedReader.useLines{lines->lines.forEach{lineList.add(it)}
lineList.forEach{
val parts=it.split(“,”)
歌曲列表。添加(歌曲(部分[0],部分[1],部分[2],部分[3],“”)
}
}
}

通过向viewmodelprovider传递片段父活动而不是片段本身来检索viewmodel


ValueMalvestPosial.GET(GoopListVistMe::Copy.java)

< P>我不认为它是一个答案,只是一个小小的解释,你的VIEW模型生命周期连接到你的片段生命周期,所以当你改变片段时,它会被破坏,并且你的视图模型也被破坏了。解决方案是将创建viewmodel移动到activity并像Nezih建议的那样使用它,但我不确定这是最好的选择。

注意,我们需要在activity scope中创建
viewmodel
实例,否则android将创建一个单独的实例,而不是共享同一个实例,我们将无法获得数据

对于fragment,请按如下方式执行:

activity?.let {
    val viewmodel = ViewModelProviders.of(it).get(SongListViewModel::class.java)

     viewmodel.songs.observe(this, Observer { songs ->
            songs?.let {
                Log.d("Song Fragment", "ObserveViewModel")
                songListAdapter.updateSongList(songs)
            }
        })
}
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], ""))
        }


    }
}
activity?.let {
    val viewmodel = ViewModelProviders.of(it).get(SongListViewModel::class.java)

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