I having problem showing the last item when I update my recyclerview. The data is correct but I have to scroll down to show the last item because is out of screen. It's not a problem about constraint, nor margins, I've double checked it.I've read several posts here about how to fix it but none has worked for my code so far. Any suggestions?
This is my adapter:
class ComentarioAdaptador(private var context: Context, private var publicacionLista: ArrayList<Comentario>): RecyclerView.Adapter<ComentarioAdaptador.ViewHolder>()
{
private var tipoUsuario=""
class ViewHolder( itemView: View):RecyclerView.ViewHolder(itemView) {
var ivPerfil : ImageView = itemView.findViewById(R.id.iv_perfil)
var tvNombreUsuario: TextView = itemView.findViewById(R.id.tv_propietario)
var tvComentario: TextView = itemView.findViewById(R.id.tv_comentario)
var tvFecha: TextView = itemView.findViewById(R.id.tv_fecha)
var btnBorrar: Button =itemView.findViewById(R.id.brn_borrar_comentario)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view =LayoutInflater.from(context).inflate(R.layout.comentario,parent,false)
determinarTipoUsuario()
return ViewHolder(view)
}
override fun getItemCount(): Int {
return publicacionLista.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val comentario = publicacionLista[position]
holder.tvComentario.text =comentario.contenido
holder.tvFecha.text= comentario.fecha
buscarUsuario(holder.ivPerfil, holder.tvNombreUsuario, comentario.creadoPor,holder.btnBorrar)
holder.btnBorrar.setOnClickListener{
}
}
private fun buscarUsuario(ivPerfil: ImageView, tvNombreUsuario: TextView, propietario: String, btnBorrar:Button) {
val usuarioRef = FirebaseDatabase.getInstance().reference.child("Usuarios").child(propietario)
usuarioRef.addValueEventListener(object: ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.exists()){
val usuario=snapshot.getValue(Usuario::class.java)
tvNombreUsuario.text=usuario!!.usuario
Glide.with(context).load(usuario.perfil).circleCrop().into(ivPerfil)
if (tipoUsuario=="usuario")
btnBorrar.isGone=true
else
btnBorrar.isVisible=true
}
}
override fun onCancelled(error: DatabaseError) {
}
})
}
private fun determinarTipoUsuario(){
val usuarioActual = FirebaseAuth.getInstance().currentUser!!
val userID = usuarioActual.uid
//LUEGO HAGO UNA INSTANCIA DE ESA UID
val busqueda = FirebaseDatabase.getInstance().getReference("Usuarios").child(userID)
//FINALMENTE LE PONGO UN LISTENER PARA GUARDAR DATOS
busqueda.addValueEventListener(object : ValueEventListener
{
override fun onDataChange(snapshot: DataSnapshot)
{
tipoUsuario = snapshot.getValue(Usuario::class.java)!!.tipo
Toast.makeText(context, tipoUsuario, Toast.LENGTH_SHORT).show()
}
override fun onCancelled(error: DatabaseError)
{}
})
}
}
This is how I call the the recyclerview on my fragment:
private fun mostrarComentarios(uidPostRecibido:String){
val comentariosRef= FirebaseDatabase.getInstance().reference.child("Comentarios").child(uidPostRecibido)
listaComentarios!!.clear()
comentariosRef.addValueEventListener(object : ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.exists()){
for (snapshot in snapshot.children)
{
val comentario = snapshot.getValue(Comentario::class.java)
listaComentarios!!.add(comentario!!)
}
comentarioAdaptador!!.notifyDataSetChanged()
}
}
override fun onCancelled(error: DatabaseError) {
}
}
)
}
Related
I am implementing a recycler view with diff util, but the first time I send the list to the adapter, the recycler view is not notified about the new list. Only the second time I update the list does the recycler receive the notification. I tried several solutions I found in similar questions but none worked. If anyone can help, thanks in advance.
Here is my code:
Adapter:
class UserListAdapter : Adapter<UserListItemViewHolder>() {
private var mUsers = mutableListOf<User>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserListItemViewHolder =
UserListItemViewHolder.create(parent)
override fun onBindViewHolder(holder: UserListItemViewHolder, position: Int) {
holder.bind(mUsers[position])
}
override fun getItemCount(): Int = mUsers.size
fun updateUsersList(users: List<User>) {
val diffCallback = UserListDiffCallback(this.mUsers, users)
val diffResult = DiffUtil.calculateDiff(diffCallback)
this.mUsers.clear()
this.mUsers.addAll(users)
diffResult.dispatchUpdatesTo(this)
}
}
UsersListDiffCallback:
class UserListDiffCallback(
private val oldList: List<User>,
private val newList: List<User>
) : DiffUtil.Callback() {
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition].username == newList[newItemPosition].username
}
override fun getOldListSize(): Int {
return oldList.size
}
override fun getNewListSize(): Int {
return newList.size
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return true
}
}
ViewModel:
#HiltViewModel
class MainViewModel #Inject constructor(
private val getUsersUseCase: GetUsersUseCase
) : ViewModel() {
private val _usersResultStatus = MutableLiveData<ResultStatus>(NotLoading)
val usersResultStatus: LiveData<ResultStatus>
get() = _usersResultStatus
private val _users = MutableLiveData<MutableList<User>?>()
val users: LiveData<MutableList<User>?>
get() = _users
fun getUsers() {
viewModelScope.launch {
try {
_usersResultStatus.value = Loading
_users.value = getUsersUseCase()
} catch (error: Throwable) {
_usersResultStatus.value = Error(error)
} finally {
_usersResultStatus.value = NotLoading
}
}
}
}
And where I update the list in the activity:
#AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private var _binding: ActivityMainBinding? = null
private val binding: ActivityMainBinding get() = _binding!!
private val viewModel: MainViewModel by viewModels()
private val usersAdapter = UserListAdapter()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
_binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initUsersAdapter()
observeStates()
viewModel.getUsers()
}
private fun initUsersAdapter() {
with(binding.recyclerView) {
setHasFixedSize(true)
adapter = usersAdapter
}
}
private fun observeStates() {
viewModel.usersResultStatus.observe(this) { resultStatus ->
setProgressbarVisibility(resultStatus is Loading)
if (resultStatus is Error) {
Toast.makeText(
this#MainActivity,
getString(R.string.error),
Toast.LENGTH_SHORT
).show()
}
}
viewModel.users.observe(this) { users ->
users?.let {
usersAdapter.updateUsersList(users.toMutableList())
}
}
}
private fun setProgressbarVisibility(show: Boolean) {
binding.progressBar.visibility = if (show) View.VISIBLE else View.GONE
}
}
Trying to add item range changed to your code works like this for me
fun updateUsersList(users: List<User>) {
val diffCallback = UserListDiffCallback(this.mUsers, users)
val diffResult = DiffUtil.calculateDiff(diffCallback)
this.mUsers.clear()
this.mUsers.addAll(users)
diffResult.dispatchUpdatesTo(this)
notifyItemRangeChanged(0, users.size)
}
How can I change the background color of the selected item in RecyclerView Kotlin
Thank you from now
How to change the background color of only selected view in my recycle view example?only the background color of clicked itemview needs to be changed
OutTimeActiviyt
val linearLayoutManager = LinearLayoutManager(this)
layoutBnd.outRecylerView.layoutManager = linearLayoutManager
layoutBnd.outRecylerView.setHasFixedSize(false)
//IN RECYCLERVIEW
out_TimeList.clear()
val out_DataBase = this.openOrCreateDatabase("Park", Context.MODE_PRIVATE, null)
val recyclerCursor = out_DataBase.rawQuery("SELECT * FROM Money", null)
val listTimeIndex = recyclerCursor.getColumnIndex("MoneyListName")
while (recyclerCursor.moveToNext()) {
out_TimeList.add(recyclerCursor.getString(listTimeIndex))
}
recyclerCursor.close()
val recyclerMoneyListName = Out_Recyler_Adapter(out_TimeList)
layoutBnd.outRecylerView.adapter = recyclerMoneyListName
recyclerMoneyListName.setOnItemClickListener(object : Out_Recyler_Adapter.onItemClickListener{
override fun onItemClick(position: Int) {
Toast.makeText(this#OutTimeActivity, "Selected item:${position}", Toast.LENGTH_SHORT).show()
}
})
Out_TimeAdapter
class Out_Recyler_Adapter(private val out_TimeList: ArrayList<String>) :
RecyclerView.Adapter<Out_Recyler_Adapter.ViewHolder>() {
private lateinit var out_ClickListener: onItemClickListener
interface onItemClickListener {
fun onItemClick(position: Int)
}
fun setOnItemClickListener(listener: onItemClickListener) {
out_ClickListener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.recyler_style, parent, false)
return ViewHolder(view, out_ClickListener)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val ItemsViewModel = out_TimeList[position]
holder.textView.text = ItemsViewModel
}
override fun getItemCount(): Int {
return out_TimeList.size
}
class ViewHolder(ItemView: View, listener: onItemClickListener) : RecyclerView.ViewHolder(ItemView) {
val textView: TextView = itemView.findViewById(R.id.style_txtParkingInfo)
init {
itemView.setOnClickListener {
listener.onItemClick(adapterPosition)
}
}
}
}
class SummonerInfoActivity: AppCompatActivity() {
private lateinit var participantAdapter: ParticipantAdapter
private val recycler: RecyclerView by lazy {
findViewById(R.id.RecyclerView)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val Summoner = intent.getParcelableExtra<SummonerDTO>("SummonerDTO")
Log.e("Info","${Summoner}")
val retrofit2 = Retrofit.Builder()
.baseUrl("https://asia.api.riotgames.com")
.addConverterFactory(GsonConverterFactory.create())
.build()
lolAPIForMatch = retrofit2.create(lolAPIService::class.java)
setContentView(R.layout.activity_summoner_info)
participantAdapter = ParticipantAdapter()
recycler.adapter = participantAdapter
recycler.layoutManager = LinearLayoutManager(this#SummonerInfoActivity)
getMatchIdBypuuid(Summoner?.puuId.orEmpty(),Summoner?.summonerName.orEmpty())
}
private fun getMatchIdBypuuid(puuid: String,summonerName: String){
lolAPIForMatch.getMatchIdBypuuid(puuid, 0,20, API_KEY)
.enqueue(object : Callback<List<String>> {
override fun onResponse(
call: Call<List<String>>,
response: Response<List<String>>
) {
if(response.isSuccessful.not()){
return
}
response.body()?.let {
it.forEach {
searchMatchInfoByMatchID(it,summonerName)
}
}
}
override fun onFailure(call: Call<List<String>>, t: Throwable) {
}
})
}
private fun searchMatchInfoByMatchID(matchId: String,summonerName: String){
lolAPIForMatch.getMatchInfoByMatchID(matchId, API_KEY)
.enqueue(object : Callback<MatchDTO>{
override fun onResponse(call: Call<MatchDTO>, response: Response<MatchDTO>) {
if(response.isSuccessful.not()){
return
}
response.body()?.let {
it.info.participants.filter {
it.summonerName == "${summonerName}"
}.forEach {
participantAdapter.participants.add(it)
}
}
}
override fun onFailure(call: Call<MatchDTO>, t: Throwable) {
}
})
}
}
class ParticipantAdapter: RecyclerView.Adapter<ParticipantAdapter.ViewHolder>() {
var participants = mutableListOf<ParticipantDTO>()
inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
fun bind(participant: ParticipantDTO){
itemView.findViewById<TextView>(R.id.kill).text = participant.kills.toString()
itemView.findViewById<TextView>(R.id.death).text = participant.deaths.toString()
itemView.findViewById<TextView>(R.id.assist).text = participant.assists.toString()
}
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ParticipantAdapter.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
return ViewHolder(inflater.inflate(R.layout.item_match, parent, false))
}
override fun onBindViewHolder(holder: ParticipantAdapter.ViewHolder, position: Int) {
holder.bind(participants[position])
}
override fun getItemCount(): Int {
return participants.size
}
}
participantAdapter.participants.add(it)
The command is searchMatchInfoByMatchID
In the function, you can check that the value is entered correctly, but
If you check in the onCreate function, the value is not assigned.
I want to use the recycler view by properly assigning a value
I tried to solve this problem, but my skills were not enough.
I desperately need the advice of seniors.
I would really appreciate it if you could show me a code sample if possible
I am using kotlin language with android studio. I want to get the properties of the element I clicked in the RecyclerView.
Ben bu kod ile saderc id alabiliyorum
Ex: date
ListAdapter.kt
class ListAdapter(
private val context: Context
) : RecyclerView.Adapter<ListAdapter.ListViewHolder>() {
private var dataList = mutableListOf<Any>()
private lateinit var mListener: onItemClickListener
interface onItemClickListener {
fun onItemClick(position: Int)
}
fun setOnItemClickListener(listener: onItemClickListener) {
mListener = listener
}
fun setListData(data: MutableList<Any>) {
dataList = data
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.item_row, parent, false)
return ListViewHolder(view)
}
override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
val question: Questionio = dataList[position] as Questionio
holder.bindView(question)
}
override fun getItemCount(): Int {
return if (dataList.size > 0) {
dataList.size
} else {
return 0
}
}
inner class ListViewHolder(itemView: View, listener: onItemClickListener) :
RecyclerView.ViewHolder(itemView) {
fun bindView(questionio: Questionio) {
itemView.findViewById<TextView>(R.id.txt_policlinic).text = questionio.policlinic
itemView.findViewById<TextView>(R.id.txt_title).text = questionio.title
itemView.findViewById<TextView>(R.id.txt_description).text = questionio.description
itemView.findViewById<TextView>(R.id.txt_date).text = questionio.date
itemView.findViewById<TextView>(R.id.txt_time).text = questionio.time
}
init {
itemView.setOnClickListener {
listener.onItemClick(adapterPosition)
}
}
}
}
My code in onCreateView inside list fragment.Edit
ListFragment
recyclerView.layoutManager = LinearLayoutManager(requireContext())
recyclerView.adapter = adapter
observeData()
adapter.setOnItemClickListener(object : ListAdapter.onItemClickListener {
override fun onItemClick(position: Int) {
showShortToast(position.toString())
}
})
this function is also my observationData(),
I made new edits
private fun observeData() {
binding.shimmerViewContainer.startShimmer()
listViewModel.fetchQuestinData("questions",
requireContext())
.observe(viewLifecycleOwner, {
binding.shimmerViewContainer.startShimmer()
binding.shimmerViewContainer.hideShimmer()
binding.shimmerViewContainer.hide()
adapter.setListData(it)
adapter.notifyDataSetChanged()
})
}
You can pass highOrderFuction into the adapter then setonclickListener for any view you want. Like this:
class ListAdapter(
private val context: Context,
private val onItemClick:(questionio: Questionio)->Unit
) : RecyclerView.Adapter<ListAdapter.ListViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.item_row, parent, false)
return ListViewHolder(view,onItemClick)
}
...
inner class ListViewHolder(itemView: View,private val onItemClick:(questionio: Questionio)->Unit) : RecyclerView.ViewHolder(itemView) {
fun bindView(questionio: Questionio) {
//set on any view you want
itemView.findViewById<TextView>(R.id.root_view_id).
setOnClickListener{onItemClick(questionio)}
itemView.findViewById<TextView>(R.id.txt_policlinic).text =
questionio.policlinic
itemView.findViewById<TextView>(R.id.txt_title).text = questionio.title
itemView.findViewById<TextView>(R.id.txt_description).text =
questionio.description
itemView.findViewById<TextView>(R.id.txt_date).text = questionio.date
itemView.findViewById<TextView>(R.id.txt_time).text = questionio.time
}
}
}
Like title I can't get correct item data, now imagine I have 2 recycler view list on my main fragment, one recycler view is vertical, other horizontal. If I use only one recycler everything is working fine. But when I add other one it's opening items randomly, but that random data openings only random both recyclers positions. Like my first recycler have [a,b,c,d] , other recycler have [e,f,g,h]. When I click first item of first recycler its go to other fragment which shows detail, its opening e instead of a, if I go back and retry it, its opening e again, retry and its a !! so its opening randomly, why this is happening why can't I open correct data? I put Log.d on my adapters and when I click recycler items, adapters log says u clicked "a" but my detail fragment shows me data of "e". What I am doing wrong? Here is my codes:(I have lots of codes so I share what we need)
my databases 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(
)
}
Tv Database:
#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
}
}
}
}
movie Dao:
#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(
)
}
movie database:
#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()
}
}
my adapters:
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()
}
}
other adapter:
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()
}
}
my base 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()
}
}
detail ViewModel:
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())
}
}
and this is my detail page fragment codes:
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")
}
}
})
}
Like I said if I delete my one of recycler view its working perfect but if I use two recycler on same fragment I got wrong datas. Logs says I open correct data but it's not.
If u need my other codes to solve problem say it please I have lots of screens don't know which one I need to share to solve it.
i solved my problem but i don't know what i changed on background
i just seperate my one function to two function in MovieListesiViewmodel and gave a parameter and its worked like a miracle
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()
}
})
)
}