I am trying to add a code from a book I am following to an existing code I am writing - android-recyclerview

Open PodcastActivity.kt and add the following lines to the top of the class. This is the question
this is the code I am adding
private val searchViewModel by viewModels()
private lateinit var podcastListAdapter: PodcastListAdapter
This is where I am adding it to
class PodcastActivity : AppCompatActivity() {
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// 1
val inflater = menuInflater
inflater.inflate(R.menu.menu_search, menu)
// 2
val searchMenuItem = menu.findItem(R.id.search_item)
val searchView = searchMenuItem?.actionView as SearchView
// 3
val searchManager = getSystemService(Context.SEARCH_SERVICE)
as SearchManager
// 4
searchView.setSearchableInfo(
searchManager.getSearchableInfo(componentName)
)
return true
setupToolbar()
}
private fun performSearch(term: String) {
val itunesService = ItunesService.instance
val itunesRepo = ItunesRepo(itunesService)
itunesRepo.searchByTerm(term) {
Log.i(Companion.TAG, "Results = $it")
}
}
private fun handleIntent(intent: Intent) {
if (Intent.ACTION_SEARCH == intent.action) {
val query = intent.getStringExtra(SearchManager.QUERY) ?: return
performSearch(query)
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
handleIntent(intent)
}
companion object {
private const val TAG = "PodcastActivity"
}
private fun setupToolbar() {
setSupportActionBar(toolbar)
}
}

Related

DiffUtil (dispatchUpdatesTo) not updating Recycler View

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)
}

Show item info on selected item in RecyclerView using Kotlin

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
}
}
}

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

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()
}
})
)
}

Unresolved reference: myViewHolder after switching to View Binding

After switching from removing kotlin_extensions and switching to view binding, I received a "Unresolved reference: myViewHolder" in my onBindViewHolder method and when I replace "myViewHolder" with "holder", it then gives me a "Unresolved reference: bind". How do I resolve this.
MyAdapter
class MyAdapter(private val context: Context, private val mHelper : TaskDbHelper) : RecyclerView.Adapter<MyAdapter.MyViewHolder>(),
SwipeAndDragHelper.ActionCompletionContract {
class MyViewHolder(val binding: CellCardsBinding): RecyclerView.ViewHolder(binding.root ) {
fun binding() {
}
}
private var touchHelper: ItemTouchHelper? = null
private var list = mutableListOf<MyObject>()
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
initList()
super.onAttachedToRecyclerView(recyclerView)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(CellCardsBinding.inflate(LayoutInflater.from(parent.context), parent, false))
}
#RequiresApi(Build.VERSION_CODES.P)
#SuppressLint("ClickableViewAccessibility")
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val myObject = list[position]
myViewHolder.bind(myObject)
val activity: Activity = context as Activity
holder.binding.text.setOnClickListener{
activity.launchActivity<AddNoteActivity>(42) {
putExtra("PositionInList", position.toString())
putExtra("TaskTitle", myObject.title)
putExtra("TaskText", myObject.text)
}
}
activity.findViewById<RecyclerView>(R.id.recyclerView).setOnTouchListener { _, event ->
when (event.actionMasked) {
MotionEvent.ACTION_UP -> {
updateNotesPositionInDb()
false
}
else -> {
false
}
}
}
holder.binding.title.setOnTouchListener { _, event ->
when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
touchHelper!!.startDrag(holder)
false
}
else -> {
false
}
}
}
}
private fun initList() {
list.clear()
val db = mHelper.readableDatabase
val cursor = db.query(
TaskContract.TaskEntry.TABLE,
arrayOf(
TaskContract.TaskEntry.ID,
TaskContract.TaskEntry.COL_TASK_TITLE,
TaskContract.TaskEntry.COL_TASK_TEXT,
TaskContract.TaskEntry.COL_TASK_DATE),null, null, null, null, TaskContract.TaskEntry.ID)
while (cursor.moveToNext()) {
val id = cursor.getColumnIndex(TaskContract.TaskEntry.ID)
val idTitle = cursor.getColumnIndex(TaskContract.TaskEntry.COL_TASK_TITLE)
val idText = cursor.getColumnIndex(TaskContract.TaskEntry.COL_TASK_TEXT)
val idDate = cursor.getColumnIndex(TaskContract.TaskEntry.COL_TASK_DATE)
list.add(MyObject(cursor.getString(id), cursor.getString(idTitle), cursor.getString(idText), cursor.getString(idDate)))
}
notifyDataSetChanged()
cursor.close()
db.close()
}
override fun getItemCount(): Int {
return list.size
}
override fun onViewMoved(oldPosition: Int, newPosition: Int) {
val target = list[oldPosition]
list.removeAt(oldPosition)
list.add(newPosition, target)
notifyItemMoved(oldPosition, newPosition)
}
override fun onViewSwiped(position: Int) {
deleteTask(list[position].ID)
list.removeAt(position)
notifyItemRemoved(position)
updateNotesPositionInDb()
}
fun setTouchHelper(touchHelper: ItemTouchHelper) {
this.touchHelper = touchHelper
}
fun addTask(taskTitle : String, taskText: String) {
val values = ContentValues()
val sdf = SimpleDateFormat("dd/MM/yyyy/", Locale.US)
val date = sdf.format(Date())
values.put(TaskContract.TaskEntry.ID, list.size)
values.put(TaskContract.TaskEntry.COL_TASK_TITLE, taskTitle)
values.put(TaskContract.TaskEntry.COL_TASK_TEXT, taskText)
values.put(TaskContract.TaskEntry.COL_TASK_DATE, date)
val db = mHelper.readableDatabase
db.insertWithOnConflict(TaskContract.TaskEntry.TABLE,
null,
values,
SQLiteDatabase.CONFLICT_REPLACE)
db.close()
list.add(MyObject(list.size.toString(), taskTitle, taskText, date))
notifyItemInserted(list.size)
}
fun addTask() {
val test: Activity = context as Activity
test.launchActivity<AddNoteActivity>(42) {
/* putExtra("user", "854")
p utExtra("user2", "46850") */
}
}
private fun deleteTask(taskId: String) {
val db = mHelper.readableDatabase
db.delete(TaskContract.TaskEntry.TABLE,
"id=$taskId", null)
db.close()
}
fun modifyTask(taskPosition: String, taskTitle: String, taskText: String) {
val target = list[taskPosition.toInt()]
target.title = taskTitle
target.text = taskText
val values = ContentValues()
val sdf = SimpleDateFormat("dd/MM/yyyy/", Locale.US)
val date = sdf.format(Date())
values.put(TaskContract.TaskEntry.ID, taskPosition)
values.put(TaskContract.TaskEntry.COL_TASK_TITLE, taskTitle)
values.put(TaskContract.TaskEntry.COL_TASK_TEXT, taskText)
values.put(TaskContract.TaskEntry.COL_TASK_DATE, date)
val db = mHelper.readableDatabase
db.update(TaskContract.TaskEntry.TABLE,
values, TaskContract.TaskEntry.ID + "=" + target.ID, null)
db.close()
notifyItemChanged(taskPosition.toInt())
}
private fun updateNotesPositionInDb() {
val db = mHelper.readableDatabase
var i = 0
while (i < list.size) {
val values = ContentValues()
values.put(TaskContract.TaskEntry.ID, i)
db.update(TaskContract.TaskEntry.TABLE,
values, TaskContract.TaskEntry.ID + "=? AND " + TaskContract.TaskEntry.COL_TASK_TITLE + "=?", arrayOf(list[i].ID, list[i].title))
i++
}
db.close()
}
I've tried reading Android Studio's official documentation, but it cannot solve my specific problem.
in your class MyViewHolder you have method called binding and you need also to implement it and add paramter
shoud be
class MyViewHolder(private val binding: CellCardsBinding): RecyclerView.ViewHolder(binding.root ) {
fun bind(data:MyObject) {
binding.yourView=data.title ...
}
}
in onBindViewHolder
..
holder.bind(myObject)
After switching from removing kotlin_extensions and switching to view binding, I received a "Unresolved reference: myViewHolder" in my onBindViewHolder method
Well, your onBindViewHolder method is passing a variable called holder and you're trying to use a variable called myViewHolder, so that seems like a problem.
// --------------------this-----v
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val myObject = list[position]
// v--- doesn't match this
myViewHolder.bind(myObject)
and when I replace "myViewHolder" with "holder", it then gives me a "Unresolved reference: bind". How do I resolve this.
Your MyViewHolder class has a method called binding that takes no arguments. There is no bind method that takes a "myObject".
class MyViewHolder(val binding: CellCardsBinding): RecyclerView.ViewHolder(binding.root ) {
fun binding() {
}
}
Edit
You should pass an instance of the data class
class MyViewHolder(val binding: CellCardsBinding): RecyclerView.ViewHolder(binding.root ) {
fun bind(object: MyObject) {
// Set variables on binding
}
}
Then pass an instance from your list via onBindViewHolder:
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val myObject = list[position]
holder.bind(myObject)
Please check this blog post for more.
I got my answer.
class MyAdapter(private val context: Context, private val mHelper : TaskDbHelper) : RecyclerView.Adapter<MyAdapter.MyViewHolder>(),
SwipeAndDragHelper.ActionCompletionContract {
class MyViewHolder(val binding: CellCardsBinding): RecyclerView.ViewHolder(binding.root ) {
private val titleView: TextView = itemView.findViewById<View>(R.id.title) as TextView
val textView: TextView = itemView.findViewById<View>(R.id.text) as TextView
private val dateTextView: TextView = itemView.findViewById<View>(R.id.date) as TextView
fun binding (myObject: MyObject) {
titleView.text = myObject.title
textView.text = myObject.text
dateTextView.text = myObject.date
}
}
I simply initialised the view I wanted to reference in my layout and called them in the binding() function.

Item on recycler-view disappear after changing to a different activity and back again

A very newbie programmer here and not a good English typer. Im trying to create a checker for purchase that already made previous using the PurchaseHistoryResponseListener. And When a checker found something, it will add to a list and then feed the recyclerview_MYBook with that data. The issue is that when launching the app, the data is flow through the recyclerview_MYBook perfectly, but when moving to different activity and going back to the previous activity through a different method (button click) the data on the recyclerview_MYBook doesn't show up, only through a conventional back button, the data on the recyclerview show up. Below here is my noob code
class MainActivity : AppCompatActivity(), PurchasesUpdatedListener {
private lateinit var billingClient: BillingClient
private lateinit var blogadapternew: BlogRecyclerAdapterNew
private lateinit var blogadapterpremium: BlogRecyclerAdapterPremium
private lateinit var blogadapterfree: BlogRecyclerAdapterFree
private lateinit var blogadaptermybook: BlogRecyclerAdapterMyBook
private lateinit var auth: FirebaseAuth
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
auth = FirebaseAuth.getInstance()
//FirebaseAuth.getInstance().signOut()
window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
setContentView(R.layout.activity_main)
recycler_viewNew.layoutManager = LinearLayoutManager(this, RecyclerView.HORIZONTAL,false)
recycler_viewNew.adapter= BlogRecyclerAdapterNew()
recycler_viewPremium.layoutManager = LinearLayoutManager(this,RecyclerView.HORIZONTAL,false)
recycler_viewPremium.adapter= BlogRecyclerAdapterPremium()
recycler_viewFree.layoutManager = LinearLayoutManager(this,RecyclerView.HORIZONTAL,false)
recycler_viewFree.adapter= BlogRecyclerAdapterFree()
recycler_viewMyBook.layoutManager = LinearLayoutManager(this,RecyclerView.HORIZONTAL,false)
recycler_viewMyBook.adapter= BlogRecyclerAdapterMyBook()
if (supportActionBar != null)
supportActionBar?.hide()
setupBillingClient()
initrecyclerView()
initrecyclerViewPremium()
initrecyclerViewFree()
initrecyclerViewMyBook()
addDataSetNew()
addDataSetPremium()
addDataSetFree()
Logo.setOnClickListener{
val intent = Intent(MonstaLogo.context, MainActivity::class.java)
MonstaLogo.context.startActivity(intent)
}
MainFeaturedButton.setOnClickListener {
val intent = Intent(MainFeaturedButton.context, MainActivity::class.java)
MainFeaturedButton.context.startActivity(intent)
}
MainNewButton.setOnClickListener {
val intent = Intent(MainNewButton.context, NewActivity::class.java)
MainNewButton.context.startActivity(intent)
}
NewMore.setOnClickListener{
val intent = Intent(NewMore.context, NewActivity::class.java)
NewMore.context.startActivity(intent)
}
MainPremiumButton.setOnClickListener {
val intent = Intent(MainPremiumButton.context, PremiumActivity::class.java)
MainPremiumButton.context.startActivity(intent)
}
PremiumMore.setOnClickListener{
val intent = Intent(PremiumMore.context, PremiumActivity::class.java)
PremiumMore.context.startActivity(intent)
}
MainFreeButton.setOnClickListener {
val intent = Intent(MainFreeButton.context, FreeActivity::class.java)
MainFreeButton.context.startActivity(intent)
}
FreeMore.setOnClickListener {
val intent = Intent(FreeMore.context, FreeActivity::class.java)
FreeMore.context.startActivity(intent)
}
MainMyBookButton.setOnClickListener {
val intent = Intent(MainMyBookButton.context, MyBookActivity::class.java)
MainMyBookButton.context.startActivity(intent)
}
MyBookMore.setOnClickListener {
val intent = Intent(MyBookMore.context, MyBookActivity::class.java)
MyBookMore.context.startActivity(intent)
}
}
private fun setupBillingClient() {
billingClient = BillingClient.newBuilder(this)
.enablePendingPurchases()
.setListener(this)
.build()
billingClient.startConnection(object : BillingClientStateListener {
override fun onBillingSetupFinished(billingResult: BillingResult) {
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
// The BillingClient is ready. You can query purchases here.
println("Setup Billing Done")
PurchaseHistoryResponseListener()
}
}
override fun onBillingServiceDisconnected() {
// Try to restart the connection on the next request to
// Google Play by calling the startConnection() method.
println("Failed")
setupBillingClient()
println("Restart Connection")
}
})
}
override fun onPurchasesUpdated(
billingResult: BillingResult?,
purchases: MutableList<Purchase>?
) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
private fun PurchaseHistoryResponseListener (){
billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP) {
responseCode, result ->
// println("queryPurchasesAsync INAPP results: ${result?.size}")
// println("Getting Purchase History")
println("$result")
val dataMyBook1 = DataSourceMyBook.createDataSet()
if ("testcode1" in result.toString()) {
println("found it 1")
dataMyBook1.add((BlogPost( "BookName","Link","No")))
}
if ("testcode2" in result.toString()) {
println("found it 2")
dataMyBook1.add((BlogPost( "BookName","Link","No")))
}
if ("testcode3" in result.toString()) {
println("found it 3")
dataMyBook1.add((BlogPost( "BookName","Link","No")))
}
blogadaptermybook.submitList(dataMyBook1)
println(dataMyBook1)
}
}
private fun addDataSetNew(){
val dataNew = DataSourceNew.createDataSet()
blogadapternew.submitList(dataNew)
}
private fun addDataSetPremium(){
val dataPremium = DataSourcePremium.createDataSet()
blogadapterpremium.submitList(dataPremium)
}
private fun addDataSetFree(){
val dataFree = DataSourceFree.createDataSet()
blogadapterfree.submitList(dataFree)
}
/*private fun addDataSetMyBook(){
val dataMyBook1 = DataSourceMyBook.createDataSet()
blogadaptermybook.submitList(dataMyBook1)
}*/
/*private fun addDataSetMyBook(){
val dataMyBook1 = DataSourceMyBook.createDataSet()
billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP) {
responseCode, result ->
println("$result")
if ("bbbg_s2_c1_testcode1" in result.toString()){
dataMyBook1.add((BlogPost( "Mini Comic 1","Link","No")))
}
if ("bbbg_s2_c1_testcode2" in result.toString()){
dataMyBook1.add((BlogPost( "Mini Comic 2","Link","No")))
}
if ("bbbg_s2_c1_testcode3" in result.toString()){
dataMyBook1.add((BlogPost( "Mini Comic 3","Link","No")))
}
blogadaptermybook.submitList(dataMyBook1)
}}*/
/*dataMyBook.add((BlogPost( "Mini Comic 1","Link","No")))
dataMyBook.add((BlogPost( "Mini Comic 1","Link","No")))
dataMyBook.add((BlogPost( "Mini Comic 1","Link","No")))*/
private fun initrecyclerView(){
recycler_viewNew.apply {
layoutManager = LinearLayoutManager(this#MainActivity,RecyclerView.HORIZONTAL,false)
val topSpacingItemDecoration = TopSpacingItemDecoration(padding = 30)
addItemDecoration(topSpacingItemDecoration)
blogadapternew = BlogRecyclerAdapterNew()
adapter = blogadapternew
}
}
private fun initrecyclerViewPremium(){
recycler_viewPremium.apply {
layoutManager = LinearLayoutManager(this#MainActivity,RecyclerView.HORIZONTAL,false)
val topSpacingItemDecoration = TopSpacingItemDecoration(padding = 30)
addItemDecoration(topSpacingItemDecoration)
blogadapterpremium = BlogRecyclerAdapterPremium()
adapter = blogadapterpremium
}
}
private fun initrecyclerViewFree(){
recycler_viewFree.apply {
layoutManager = LinearLayoutManager(this#MainActivity,RecyclerView.HORIZONTAL,false)
val topSpacingItemDecoration = TopSpacingItemDecoration(padding = 30)
addItemDecoration(topSpacingItemDecoration)
blogadapterfree = BlogRecyclerAdapterFree()
adapter = blogadapterfree
}
}
private fun initrecyclerViewMyBook(){
recycler_viewMyBook.apply {
layoutManager =
LinearLayoutManager(this#MainActivity, RecyclerView.HORIZONTAL, false)
val topSpacingItemDecoration = TopSpacingItemDecoration(padding = 30)
addItemDecoration(topSpacingItemDecoration)
blogadaptermybook = BlogRecyclerAdapterMyBook()
adapter = blogadaptermybook
}
}
public override fun onStart() {
super.onStart()
val currentUser = auth.currentUser
updateUI(currentUser)
}
private fun updateUI(currentUser: FirebaseUser?) {
if (currentUser != null) {
AccountSettingButton.setImageResource(R.drawable.profileicon)
}
}
}
Here is adapter
class BlogRecyclerAdapterMyBook : RecyclerView.Adapter() {
private var items: List<BlogPost> = ArrayList()
private var items2: List<BlogPost> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return BlogViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.layout_blog_list_item_mybook,
parent,
false
)
)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is BlogViewHolder -> {
holder.bind(items.get(position))
holder.bind(items2.get(position))
}
}
}
override fun getItemCount(): Int {
return items.size
}
fun submitList(bloglist: List<BlogPost>) {
items = bloglist
items2 = bloglist
}
class BlogViewHolder constructor(itemView: View) : RecyclerView.ViewHolder(itemView) {
val blogImage: ImageButton = itemView.blog_imagemybook
val blogTitle: TextView = itemView.blog_titlemybook
val premiumImage: ImageView = itemView.premiumicon
fun bind(blogPost: BlogPost) {
blogTitle.setText(blogPost.title)
val requestOptions = RequestOptions()
.placeholder(R.drawable.mocksplash)
.error(R.drawable.disconnect)
Glide.with(itemView.blog_imagemybook)
.applyDefaultRequestOptions(requestOptions)
.load(blogPost.image)
.into(blogImage)
blogImage.setOnClickListener {
Toast.makeText(blogImage.context, "<<Swipe left<<", Toast.LENGTH_SHORT).show()
val intent = Intent(blogTitle.context, ComicReadingActivity::class.java)
var KomikName = blogTitle.text.toString()
intent.putExtra("KomikName",Name)
blogImage.context.startActivity(intent)
}
}
}
}
and here the data source file where that will store the data for the adapter
class DataSourceMyBook{
companion object{
fun createDataSet(): ArrayList<BlogPost> {
val dataMyBook1 = ArrayList<BlogPost>()
return dataMyBook1
}
}
}