当我 select 项目时,同一片段、持有人或数据库的两个回收者视图带来错误数据

Two recycler view on same fragment, holder or db brings wrong data when I select item

如标题我无法获得正确的项目数据,现在假设我的主要片段上有 2 个回收视图列表,一个回收视图是垂直的,另一个是水平的。如果我只使用一个回收站,一切正常。但是当我添加另一个时,它会随机打开项目,但随机数据打开只会随机两个回收站的位置。就像我的第一个回收商有 [a,b,c,d] 一样,其他回收商有 [e,f,g,h]。当我单击第一个回收器的第一项时,它会转到显示详细信息的其他片段,它的开头是 e 而不是 a,如果我返回并重试,它会再次打开 e,重试,它是 a !!所以它随机打开,为什么会这样 为什么我不能打开正确的数据?我将 Log.d 放在我的适配器上,当我单击回收器项目时,适配器日志显示你单击了“a”,但我的详细信息片段显示了“e”的数据。我做错了什么?这是我的代码:(我有很多代码所以我分享我们需要的)

我的数据库 TvDAO:

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import com.bt.filmdenemesi.model.Result

@Dao
interface TVDAO {
//Veri erişim nesnesi
@Insert
suspend fun insertAll(vararg movie: Result) : List<Long>

@Query("SELECT * FROM Result")
suspend fun getAllTV() : List<Result>

@Query("SELECT * FROM Result WHERE uuid2=:diziId")
suspend fun getTV(diziId:Int) : Result

@Query("DELETE FROM Result")
suspend fun deleteAllTV(

)
}

电视数据库:

@Database(entities = arrayOf(Result::class), version = 1)
abstract class TvDatabase: RoomDatabase() {
abstract fun tvDao(): TVDAO

companion object{
    @Volatile
    private var INSTANCE: TvDatabase?=null
     fun databaseOlustur2(context: Context): TvDatabase {
        return INSTANCE ?: synchronized(this){
            val instance = Room.databaseBuilder(context.applicationContext,TvDatabase::class.java, "tvdatabase").fallbackToDestructiveMigration().build()
            INSTANCE=instance
            instance
         }
     }
 }

 }

电影道:

 @Dao
 interface MovieDAO {
//Veri erişim nesnesi
@Insert
suspend fun insertAll(vararg movie: Movie) : List<Long>

@Query("SELECT * FROM Movie")
suspend fun getAllMovie() : List<Movie>

@Query("Select * from Movie where uuid=:movieId")
suspend fun getMovie(movieId:Int) : Movie

@Query("Delete from Movie")
suspend fun deleteAllMovie(

)
}

电影数据库:

@Database(entities = arrayOf(Movie::class ), version = 1)
abstract class MovieDatabase:RoomDatabase() {
abstract fun movieDao(): MovieDAO

//singleton

companion object{

     @Volatile  private var instance: MovieDatabase? = null

    private val lock = Any()
    operator fun invoke(context: Context) = instance ?: synchronized(lock){
        instance?: databaseOlustur(context).also {
            instance = it
        }
    }


    private fun databaseOlustur(context: Context)= Room.databaseBuilder(
        context.applicationContext,
        MovieDatabase::class.java,"moviedatabase").build()
}


}

我的适配器:

 class vizyonrecycleradapter(val diziListesi: ArrayList<Result>):RecyclerView.Adapter<vizyonrecycleradapter.DiziViewHolder>() {
class DiziViewHolder(itemview: View) : RecyclerView.ViewHolder(itemview)

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DiziViewHolder {
    val inflater = LayoutInflater.from(parent.context)
    val view = inflater.inflate(R.layout.now_playing_recycler_row, parent, false)
    return DiziViewHolder(view)
}

override fun onBindViewHolder(holder: DiziViewHolder, konum: Int) {
    holder.itemView.tv_ismi.text=diziListesi.get(konum).name
    val fotoDenemeleri = "https://image.tmdb.org/t/p/w500"
    val fotobirlestirme: String = "${fotoDenemeleri}"+ diziListesi.get(konum).posterPath
    holder.itemView.vizyon.gorselIndir(fotobirlestirme, placeHolderYap(holder.itemView.context))
    holder.itemView.setOnClickListener {
        val action2 = AnaSayfaDirections.actionAnaSayfaToDetaySayfasi(diziListesi[konum].uuid2)
        Log.d("movie-title","${diziListesi.get(konum).originalName}")
        Navigation.findNavController(it).navigate(action2)
    }
}
override fun getItemCount(): Int {
    return diziListesi.size
}
fun diziListesiniGuncelle(yeniDiziListesi: List<Result>) {
    diziListesi.clear()
    diziListesi.addAll(yeniDiziListesi)
    notifyDataSetChanged()
}
}

其他适配器:

   class MovieRecyclerAdapter(val movieListesi: ArrayList<Movie>):RecyclerView.Adapter<MovieRecyclerAdapter.MovieViewHolder>() {
class MovieViewHolder(itemview: View) :RecyclerView.ViewHolder(itemview)

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieViewHolder {
    val inflater = LayoutInflater.from(parent.context)
    val view = inflater.inflate(R.layout.movie_recycler_row,parent,false)
    return MovieViewHolder(view)
}

override fun onBindViewHolder(holder: MovieViewHolder, position: Int) {
    holder.itemView.movieId.text= movieListesi.get(position).title

    val fotoDenemeleri = "https://image.tmdb.org/t/p/w500"
    val fotobirlestirme: String = "${fotoDenemeleri}"+movieListesi.get(position).backdropPath
    holder.itemView.ana_foto.gorselIndir(fotobirlestirme, placeHolderYap(holder.itemView.context))
    holder.itemView.setOnClickListener {
        val action = AnaSayfaDirections.actionAnaSayfaToDetaySayfasi(movieListesi.get(position).uuid)
        Log.d("movie-title","${movieListesi.get(position).title}")
        Navigation.findNavController(it).navigate(action)
    }
}
override fun getItemCount(): Int {
    return movieListesi.size
}
fun movieListesiniGuncelle(yeniMovieListesi: List<Movie>){
    movieListesi.clear()
    movieListesi.addAll(yeniMovieListesi)
    notifyDataSetChanged()
}
}

我的基础 ViewModel:

open class BaseViewModel(application: Application) : AndroidViewModel(application),CoroutineScope {

private val job = Job()
override val coroutineContext: CoroutineContext
    get() = job + Dispatchers.Main

override fun onCleared() {
    super.onCleared()
    job.cancel()
}

}

详细视图模型:

class MovieDetayiViewModel(application: Application): BaseViewModel(application) {

val diziLiveData = MutableLiveData<Result>()
val movieLiveData = MutableLiveData<Movie>()
val aramaLiveData = MutableLiveData<ResultX>()

fun roomVerisiniAl2(uuid2: Int){
    launch {
        val dao2=TvDatabase.databaseOlustur2(getApplication()).tvDao().getTV(uuid2)
        //val dizi = dao.getTV(uuid2)
        diziLiveData.value=dao2

    }
}

fun roomVerisiniAl(uuid: Int){
    launch {
        val dao= MovieDatabase(getApplication()).movieDao().getMovie(uuid)
   //     val film = dao.getMovie(uuid)

        movieLiveData.value=dao

    }
}
fun roomVerisiniAl3(uuid3: Int){
    launch {
        val dao= AramaDatabase(getApplication()).aramaDao()
        val arama = dao.getMovie(uuid3)
        aramaLiveData.value=arama
    }
}
}

movielistviewmvdel:

class MovieListesiViewModel(application: Application): BaseViewModel(application){
val filmler = MutableLiveData<List<Movie>>()
val dizi = MutableLiveData<List<Result>>()
val arama = MutableLiveData<List<ResultX>>()
val filmHataMesaji = MutableLiveData<Boolean>()
val filmYukleniyor = MutableLiveData<Boolean>()
private var guncellemeZamani = 1 * 60 * 1000 * 1000 * 1000L
private val filmApiServis = FilmAPIServis()
private val disposable = CompositeDisposable()
private val disposable2 = CompositeDisposable()
private val disposable3 = CompositeDisposable()//kullan at
private val ozelSharedPrefences = OzelSharedPrefences(getApplication())

fun refreshData(){
    val kaydedilmeZamani = ozelSharedPrefences.zamaniAl()
    if(kaydedilmeZamani != null && kaydedilmeZamani !=0L && System.nanoTime()-kaydedilmeZamani < guncellemeZamani){
        verileriSQLitedenAl()
    }else{
        verileriInternettenAl()
    }
}
fun refreshFromInternet(){

    verileriInternettenAl()
}
    private fun verileriSQLitedenAl(){
    filmYukleniyor.value = true
    launch {
       val movieListesi = MovieDatabase(getApplication()).movieDao().getAllMovie()
       movieleriGoster(movieListesi)
       val diziListesi = TvDatabase.databaseOlustur2(getApplication()).tvDao().getAllTV()
       tvleriGoster(diziListesi)
    }
  launch {
      val aramaListesi = AramaDatabase(getApplication()).aramaDao().getAllMovie()
      aramalariGoster(aramaListesi)
   }


}

private fun verileriInternettenAl(){
    filmYukleniyor.value = true
    disposable.add(
       filmApiServis.getData()
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeWith(object: DisposableSingleObserver<GetMoviesResponse>(){
                override fun onSuccess(t: GetMoviesResponse) {
                    filmler.value= t.results
                    filmHataMesaji.value=false
                    filmYukleniyor.value=false
                    sqliteSakla(t.results)
            //        Toast.makeText(getApplication(),"Filmler internetten yüklendi",Toast.LENGTH_LONG).show()
                }
                override fun onError(e: Throwable) {
                    filmHataMesaji.value=true
                    filmYukleniyor.value=false
                    e.printStackTrace()
                }
            })
    )
    disposable2.add(
        filmApiServis.getVizyondakiler()
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribeWith(object: DisposableSingleObserver<NowPlaying>(){
            override fun onSuccess(t: NowPlaying) {
                dizi.value= t.results
                filmHataMesaji.value=false
                filmYukleniyor.value=false
                diziSqLiteSakla(t.results)
            }
            override fun onError(e: Throwable) {
                filmHataMesaji.value=true
                filmYukleniyor.value=false
                e.printStackTrace()
            }
        })
    )
}
 fun aramayiInternettenAl(denemeText:String){
    disposable3.add(
        filmApiServis.getArama(denemeText)
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeWith(object: DisposableSingleObserver<search>(){
                override fun onSuccess(t: search) {
                    arama.value= t.results
                    aramaSqliteSakla(t.results)
                }
                override fun onError(e: Throwable) {
                    e.printStackTrace()
                }
            })
    )
}

 private fun movieleriGoster(filmlerListesi : List<Movie>?){
    filmler.value= filmlerListesi
    filmHataMesaji.value=false
    filmYukleniyor.value=false
}
private fun tvleriGoster(tvListesi: List<Result>?){
    dizi.value= tvListesi
    filmHataMesaji.value=false
    filmYukleniyor.value=false
}
private fun aramalariGoster(aramaListesi: List<ResultX>){
    arama.value= aramaListesi
}

private fun sqliteSakla(filmListesi : List<Movie>){
    launch {

        val dao = MovieDatabase(getApplication()).movieDao()//dao içerisindeki fonksiyonlara ulaşmak için
        dao.deleteAllMovie()
        val uuidListesi = dao.insertAll(*filmListesi.toTypedArray())//tek tek movie haline getirmek için typed array. (*) koymak lazım
        var i = 0
        while (i < filmListesi.size){
            filmListesi[i].uuid = uuidListesi[i].toInt()//uuid ye ulaştık modemdeki idleri eşledik
            i = i + 1
        }
        movieleriGoster(filmListesi)
    }
    ozelSharedPrefences.zamaniKaydet(System.nanoTime())
}
private fun diziSqLiteSakla(diziListesi : List<Result>){
    launch {

        val dao2 = TvDatabase.databaseOlustur2(getApplication()).tvDao()//dao içerisindeki fonksiyonlara ulaşmak için
        dao2.deleteAllTV()
        val uuidListesi2 = dao2.insertAll(*diziListesi.toTypedArray())//tek tek movie haline getirmek için typed array. (*) koymak lazım
        var i = 0
        while (i < diziListesi.size){
            diziListesi[i].uuid2 = uuidListesi2[i].toInt()//uuid ye ulaştık modemdeki idleri eşledik
            i = i + 1
        }
        tvleriGoster(diziListesi)
    }
    ozelSharedPrefences.zamaniKaydet(System.nanoTime())
}
private fun aramaSqliteSakla(aramaListesi : List<ResultX>){
    launch {

        val dao = AramaDatabase(getApplication()).aramaDao()//dao içerisindeki fonksiyonlara ulaşmak için
        dao.deleteAllMovie()
        val uuidListesi3 = dao.insertAll(*aramaListesi.toTypedArray())//tek tek movie haline getirmek için typed array. (*) koymak lazım
        var i = 0
        while (i < aramaListesi.size){
            aramaListesi[i].uuid3 = uuidListesi3[i].toInt()//uuid ye ulaştık modemdeki idleri eşledik
            i = i + 1
        }
        arama.value?.let { aramalariGoster(it) }
    }
    ozelSharedPrefences.zamaniKaydet(System.nanoTime())
}

}

这是我的详情页片段代码:

class DetaySayfasi : Fragment() {

private lateinit var viewModel : MovieDetayiViewModel
private lateinit var viewModel2: MovieListesiViewModel
var movieId : Int = 0
var getId : String =""
var listeIdAlma : Int = 0
private val ozelSharedPrefences2 = OzelSharedPrefences()


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

}
override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_detay_sayfa, container, false)

}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    viewModel2 = ViewModelProviders.of(this).get(MovieListesiViewModel::class.java)
    viewModel2.refreshData()
    arguments?.let {
       movieId = DetaySayfasiArgs.fromBundle(it).movieID
    }

    viewModel = ViewModelProviders.of(this).get(MovieDetayiViewModel::class.java)

    viewModel.roomVerisiniAl(movieId)
    observeLiveData2()
    viewModel.roomVerisiniAl2(movieId)
    observeLiveData()
    viewModel.roomVerisiniAl3(movieId)

    dislike.setOnClickListener {
        like()
    }
    like.setOnClickListener {
        dislike()
    }
    observeLiveData3()
    geri()
    uygulamaPaylas()

}
fun observeLiveData(){
    viewModel.movieLiveData.observe(viewLifecycleOwner, Observer { movie->
        movie?.let {
            getId = "movie/"+"${it.id}"
            listeIdAlma= it.id
            movie_title.text=it.title
            movie_overview.text= it.overview
            movie_rating_text.text=it.voteAverage.toFloat().toString()
            movie_rating.rating = it.voteAverage.toFloat()/2
            context?.let {
                movie_backdrop.gorselIndir("https://image.tmdb.org/t/p/w500"+"${movie.backdropPath}", placeHolderYap(it))
                movie_poster.gorselIndir("https://image.tmdb.org/t/p/w500"+"${movie.posterPath}", placeHolderYap(it))
            }
            if (!(listeIdAlma in ozelSharedPrefences2.korku())){
                Log.d("ozelshared","${ozelSharedPrefences2.korku()}")
                Log.d("listetaramaid","${listeIdAlma}")
                like.visibility=View.GONE
                dislike.visibility=View.VISIBLE
            }else{
                like.visibility=View.VISIBLE
                dislike.visibility=View.GONE
                Log.d("else","like kapalı olması lazım")
            }
        }
    })
}
fun observeLiveData2(){
    viewModel.diziLiveData.observe(viewLifecycleOwner, Observer { tv->
        tv?.let {
            getId = "tv/"+"${it.id}"
            listeIdAlma = it.id
            movie_title.text=it.name
            movie_overview.text= it.overview
            movie_rating_text.text= it.voteAverage?.toFloat().toString()
            movie_rating.rating = it.voteAverage!!.toFloat()/2
            context?.let {
                movie_backdrop.gorselIndir("https://image.tmdb.org/t/p/w500"+"${tv.backdropPath}", placeHolderYap(it))
                movie_poster.gorselIndir("https://image.tmdb.org/t/p/w500"+"${tv.posterPath}", placeHolderYap(it))
            }
            if (!(listeIdAlma in ozelSharedPrefences2.korku())){
                Log.d("ozelshared","${ozelSharedPrefences2.korku()}")
                Log.d("listetaramaid","${listeIdAlma}")
                like.visibility=View.GONE
                dislike.visibility=View.VISIBLE
            }else{
                like.visibility=View.VISIBLE
                dislike.visibility=View.GONE
                Log.d("else","like kapalı olması lazım")
            }
        }
    })
}

fun observeLiveData3(){
    viewModel.aramaLiveData.observe(viewLifecycleOwner, Observer { tv->
        tv?.let {
            if (it.voteAverage!=null){
                getId = "tv/"+"${it.id}"
                listeIdAlma = it.id!!
                movie_title.text=it.name
                movie_overview.text= it.overview
                movie_rating_text.text= it.voteAverage?.toFloat().toString()
                movie_rating.rating = it.voteAverage?.toFloat()!!/2
                context?.let {
                    movie_backdrop.gorselIndir("https://image.tmdb.org/t/p/w500"+"${tv.backdropPath}", placeHolderYap(it))
                    movie_poster.gorselIndir("https://image.tmdb.org/t/p/w500"+"${tv.posterPath}", placeHolderYap(it))
                }
            }else{
                getId = "tv/"+"${it.id}"
                listeIdAlma = it.id!!
                movie_title.text=it.name
                movie_overview.text= it.name
                movie_rating_text.text= ""
                movie_rating.rating = 10F
                context?.let {
                    movie_backdrop.gorselIndir("https://image.tmdb.org/t/p/w500"+"${tv.profile_path}", placeHolderYap(it))
                    movie_poster.gorselIndir("https://image.tmdb.org/t/p/w500"+"${tv.profile_path}", placeHolderYap(it))
                }
            }
            if (!(listeIdAlma in ozelSharedPrefences2.korku())){
                Log.d("ozelshared","${ozelSharedPrefences2.korku()}")
                Log.d("listetaramaid","${listeIdAlma}")
                like.visibility=View.GONE
                dislike.visibility=View.VISIBLE
            }else{
                like.visibility=View.VISIBLE
                dislike.visibility=View.GONE
                Log.d("else","like kapalı olması lazım")
            }
        }
    })
}

就像我说的,如果我删除我的一个回收器视图,它的工作完美,但如果我在同一个片段上使用两个回收器,我得到了错误的数据。日志说我打开了正确的数据,但事实并非如此。 如果你需要我的其他代码来解决问题,请告诉我,我有很多屏幕不知道我需要分享哪一个来解决它。

我解决了我的问题,但我不知道我在后台更改了什么 我只是在 MovieListesiViewmodel 中将我的一个函数分成两个函数并提供了一个参数,它的工作就像奇迹一样

 private fun verileriInternettenAl(denemeInt: Int){
    filmYukleniyor.value = true
    disposable.add(
       filmApiServis.getData(denemeInt)
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeWith(object: DisposableSingleObserver<GetMoviesResponse>(){
                override fun onSuccess(t: GetMoviesResponse) {
                    filmler.value= t.results
                    filmHataMesaji.value=false
                    filmYukleniyor.value=false
                    sqliteSakla(t.results)
            //        Toast.makeText(getApplication(),"Filmler internetten yüklendi",Toast.LENGTH_LONG).show()
                }
                override fun onError(e: Throwable) {
                    filmHataMesaji.value=true
                    filmYukleniyor.value=false
                    e.printStackTrace()
                }
            })
    )
}
fun verileriInternettenAl2(){
    disposable2.add(
        filmApiServis.getVizyondakiler()
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeWith(object: DisposableSingleObserver<NowPlaying>(){
                override fun onSuccess(t: NowPlaying) {
                    dizi.value= t.results
                    filmHataMesaji.value=false
                    filmYukleniyor.value=false
                    diziSqLiteSakla(t.results)
                }
                override fun onError(e: Throwable) {
                    filmHataMesaji.value=true
                    filmYukleniyor.value=false
                    e.printStackTrace()
                }
            })
    )
}