I am trying to use an intent in an onClick method,the intent does work...but it doesn't want to change to the other activity
im looking everywhere but nothing seems wrong.
note:i dont know why FragmentPagerAdapter is deprecated
code:
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var viewModel: MainViewModel
private lateinit var adapter: UserAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
adapter = UserAdapter()
adapter.notifyDataSetChanged()
adapter.setOnItemClickCallback(object : UserAdapter.OnItemClickCallback{
override fun onItemClicked(data: User) {
Intent(this#MainActivity, DetailUserActivity::class.java).also{
intent.putExtra(DetailUserActivity.EXTRA_USERNAME, data.login)
startActivity(intent)
}
}
})
viewModel= ViewModelProvider(this, ViewModelProvider.NewInstanceFactory())[MainViewModel::class.java]
binding.apply {
rvUser.layoutManager = LinearLayoutManager ( this#MainActivity)
rvUser.setHasFixedSize(true)
rvUser.adapter = adapter
btnSearch.setOnClickListener{
searchUser()
}
etQuery.setOnKeyListener { _, KeyCode, event ->
if (event.action == KeyEvent.ACTION_DOWN && KeyCode == KeyEvent.KEYCODE_ENTER){
searchUser()
return#setOnKeyListener true
}
return#setOnKeyListener false
}
}
viewModel.getSearchUsers().observe(this) {
if (it != null) {
adapter.setList(it)
showLoading(false)
}
}
}
private fun searchUser(){
binding.apply {
val query = etQuery.text.toString()
if (query.isEmpty()) return
showLoading(true)
viewModel.setSearchUsers(query)
}
}
private fun showLoading(state: Boolean){
if (state){
binding.progressBar.visibility = View.VISIBLE
}else{
binding.progressBar.visibility = View.GONE
}
}
}
UserAdapter.kt
class UserAdapter : RecyclerView.Adapter<UserAdapter.UserViewHolder>() {
private val list = ArrayList<User>()
private var onItemClickCallback: OnItemClickCallback? = null
fun setOnItemClickCallback (onItemClickCallback: OnItemClickCallback){
this.onItemClickCallback = onItemClickCallback
}
fun setList(users: ArrayList<User>){
list.clear()
list.addAll(users)
notifyDataSetChanged()
}
inner class UserViewHolder(private val binding: ItemUserBinding) : RecyclerView.ViewHolder(binding.root){
fun bind(user: User){
binding.root.setOnClickListener{
onItemClickCallback?.onItemClicked(list[adapterPosition])
}
binding.apply {
Glide.with(itemView)
.load(user.avatar_url)
.transition(DrawableTransitionOptions.withCrossFade())
.centerCrop()
.into(tvUser)
tvUsername.text = user.login
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
val view = ItemUserBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return UserViewHolder((view))
}
override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
holder.bind(list[position])
}
override fun getItemCount(): Int = list.size
interface OnItemClickCallback{
fun onItemClicked(data: User)
}
}
DetailUserAdapter.kt
class DetailUserViewModel: ViewModel() {
val user= MutableLiveData<DetailUserResponse>()
fun setUserDetail(username: String){
RetrofitClient.apiInstance
.getUserDetail(username)
.enqueue(object : Callback<DetailUserResponse>{
override fun onResponse(
call: Call<DetailUserResponse>,
response: Response<DetailUserResponse>
) {
if (response.isSuccessful){
user.postValue(response.body())
}
}
override fun onFailure(call: Call<DetailUserResponse>, t: Throwable) {
t.message?.let { Log.d("Failure", it) }
}
})
}
fun getUserDetail(): LiveData<DetailUserResponse>{
return user
}
}
SectionPagerAdapter.kt
class SectionPagerAdapter(private val mCtx: Context, fm: FragmentManager) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
#StringRes
private val TAB_TITLES = IntArray(R.string.tab_1)
override fun getCount(): Int = 2
override fun getItem(position: Int): Fragment {
var fragment: Fragment? = null
when(position){
0 -> fragment = FollowerFragment()
1 -> fragment = FollowingFragment()
}
return fragment as Fragment
}
override fun getPageTitle(position: Int): CharSequence? {
return mCtx.resources.getString(TAB_TITLES[position])
}
}
The code here has a minor issue:
Intent(this#MainActivity, DetailUserActivity::class.java).also{
intent.putExtra(DetailUserActivity.EXTRA_USERNAME, data.login)
startActivity(intent)
}
Here you are using .also, which passes the Intent you are creating as it however you are using intent for launching Activity which is the intent you get in your activity, the same you can get using getIntent(), this is causing this issue here.
Please change this to something similar to this and try:
Intent(this#MainActivity, DetailUserActivity::class.java).also{
it.putExtra(DetailUserActivity.EXTRA_USERNAME, data.login)
startActivity(it)
}
or may be similar to this:
Intent(this#MainActivity, DetailUserActivity::class.java).also{ launchIntent ->
launchIntent.putExtra(DetailUserActivity.EXTRA_USERNAME, data.login)
startActivity(launchIntent)
}
Thanks!
Related
im trying to make an apps that use GitHub search user API with Retrofit.i want to make that when i type some username,it will show any github username related with it will be displayed on RecyclerView.is there something that i've missed or write wrongly?
since the apps run just fine,but when i try to search the username,it just show the 1 username type instead every username related to it.
here's my example to search username:
https://api.github.com/search/users?q=sidiqpermana
and heres some of my coding
RetrofitClient.kt
object RetrofitClient {
private const val BASE_URL = "https://api.github.com/"
private val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
val apiInstance = retrofit.create(Api::class.java)
}
Api.kt
interface Api {
#GET("search/users")
#Headers("Authorization: token N7QNdhhICaLmxSTzAWr70V7nqf6yaK4B6Z15")
fun getSearchUsers(
#Query("q") query: String
):Call<UserResponse>
}
UserResponse.kt
data class UserResponse(
val items : ArrayList<User>
)
UserAdapter.kt
class UserAdapter : RecyclerView.Adapter<UserAdapter.UserViewHolder>() {
private val list = ArrayList<User>()
fun setList(users: ArrayList<User>){
list.clear()
list.addAll(users)
notifyDataSetChanged()
}
inner class UserViewHolder(val binding: ItemUserBinding) : RecyclerView.ViewHolder(binding.root){
fun bind(user: User){
binding.apply {
Glide.with(itemView)
.load(user.avatar_url)
.transition(DrawableTransitionOptions.withCrossFade())
.centerCrop()
.into(tvUser)
tvUsername.text = user.login
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
val view = ItemUserBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return UserViewHolder((view))
}
override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
holder.bind(list[position])
}
override fun getItemCount(): Int = list.size
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var viewModel: MainViewModel
private lateinit var adapter: UserAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
adapter = UserAdapter()
adapter.notifyDataSetChanged()
viewModel= ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MainViewModel::class.java)
binding.apply {
rvUser.layoutManager = LinearLayoutManager ( this#MainActivity)
rvUser.setHasFixedSize(true)
rvUser.adapter = adapter
btnSearch.setOnClickListener{
searchUser()
}
etQuery.setOnKeyListener { _, KeyCode, event ->
if (event.action == KeyEvent.ACTION_DOWN && KeyCode == KeyEvent.KEYCODE_ENTER){
searchUser()
return#setOnKeyListener true
}
return#setOnKeyListener false
}
}
viewModel.getSearchUsers().observe(this,{
if (it!=null){
adapter.setList(it)
showLoading(false)
}
})
}
private fun searchUser(){
binding.apply {
val query = etQuery.text.toString()
if (query.isEmpty()) return
showLoading(true)
viewModel.setSearchUsers(query)
}
}
private fun showLoading(state: Boolean){
if (state){
binding.progressBar.visibility = View.VISIBLE
}else{
binding.progressBar.visibility = View.GONE
}
}
}
MainViewModel.kt
class MainViewModel : ViewModel() {
val listUsers = MutableLiveData<ArrayList<User>>()
fun setSearchUsers(query: String){
RetrofitClient.apiInstance
.getSearchUsers(query)
.enqueue(object : Callback<UserResponse>{
override fun onResponse(
call: Call<UserResponse>,
response: Response<UserResponse>
) {
if (response.isSuccessful){
listUsers.postValue(response.body()?.items)
}
}
override fun onFailure(call: Call<UserResponse>, t: Throwable) {
t.message?.let { Log.d("Failure", it) }
}
})
}
fun getSearchUsers(): LiveData<ArrayList<User>>{
return listUsers
}
}
In my scenario, I have two fragments. In my first Fragment I have a RecyclerView with SelectionTracker. After selecting an item in my first fragment I can navigate to the second fragment. But from my second fragment if I navigate back to the first fragment using back button all my previous selection is lost. How can I prevent this?
I am using Jetpack Navigation Component to handle Fragment navigation.
Here is my fragment
class SelectVideoForCourseFragment : Fragment(R.layout.fragment_select_video_for_course) {
.....
..
private val adapter by lazy { MediaListAdapter() }
private lateinit var selectionTracker: SelectionTracker<String>
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initializeListeners()
initializeRecyclerView(savedInstanceState)
fetchMedias()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
selectionTracker.onSaveInstanceState(outState)
}
private fun fetchMedias() {
val mediaRepo = MediaRepo()
mediaRepo.getVideos(contentResolver).observe(viewLifecycleOwner) {
adapter.submitItems(it)
}
}
private fun initializeRecyclerView(savedInstanceState: Bundle?) {
binding.mediaList.layoutManager = GridLayoutManager(requireContext(), 3)
binding.mediaList.addItemDecoration(GridSpacingItemDecoration(3, 5.dp, false))
binding.mediaList.adapter = adapter
selectionTracker = SelectionTracker.Builder(
"tracker-select-video-for-course",
binding.mediaList,
MediaItemKeyProvider(adapter),
MediaItemDetailsLookup(binding.mediaList),
StorageStrategy.createStringStorage()
).withSelectionPredicate(
SelectionPredicates.createSelectSingleAnything()
).build()
if (savedInstanceState != null) {
selectionTracker.onRestoreInstanceState(savedInstanceState)
}
adapter.tracker = selectionTracker
}
......
...
}
My RecyclerView Adapter:
class MediaListAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>() {
val differ = AsyncListDiffer(this, DIFF_CALLBACK_MEDIA)
var tracker: SelectionTracker<String>? = null
fun submitItems(updatedItems: List<Any>) {
differ.submitList(updatedItems)
}
fun getSelections(): List<MediaEntity> {
....
..
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == 1) {
val binding = ListItemImageBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
ViewHolderImage(binding)
} else {
val binding = ListItemVideoBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
ViewHolderVideo(binding)
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is ViewHolderImage) {
tracker?.let {
val item = differ.currentList[position] as ImageEntity
holder.bind(item , it.isSelected(item.uri.toString()))
}
} else {
holder as ViewHolderVideo
val item = differ.currentList[position] as VideoEntity
tracker?.let {
holder.bind(item, it.isSelected(item.uri.toString()))
}
}
}
override fun getItemCount(): Int = differ.currentList.size
override fun getItemViewType(position: Int): Int {
return if (differ.currentList[position] is ImageEntity) {
1
} else {
2
}
}
inner class ViewHolderImage(
private val binding: ListItemImageBinding): RecyclerView.ViewHolder(binding.root
) {
fun bind(item: ImageEntity, isSelected: Boolean) {
.....
...
}
fun getItemDetails(): ItemDetailsLookup.ItemDetails<String> =
object : ItemDetailsLookup.ItemDetails<String>() {
override fun getPosition(): Int = absoluteAdapterPosition
override fun getSelectionKey(): String {
val item = differ.currentList[absoluteAdapterPosition] as ImageEntity
return item.uri.toString()
}
override fun inSelectionHotspot(e: MotionEvent): Boolean = true
}
}
inner class ViewHolderVideo(
private val binding: ListItemVideoBinding,
): RecyclerView.ViewHolder(binding.root) {
fun bind(item: VideoEntity, isSelected: Boolean) {
.....
...
}
fun getItemDetails(): ItemDetailsLookup.ItemDetails<String> =
object : ItemDetailsLookup.ItemDetails<String>() {
override fun getPosition(): Int = absoluteAdapterPosition
override fun getSelectionKey(): String {
val item = differ.currentList[absoluteAdapterPosition] as VideoEntity
return item.uri.toString()
}
override fun inSelectionHotspot(e: MotionEvent): Boolean = true
}
}
companion object {
val DIFF_CALLBACK_MEDIA = object: DiffUtil.ItemCallback<Any>() {
.....
...
}
}
}
As below Gif.
Why images in Works tag of BottomNavigationView's Profile will disappear after switch between BottomNavigationView. But those images will appear after I enter to Home's category item of BottomNavigationView ??
MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
navController = nav_host_fragment.findNavController()
bottom_nav_view.setupWithNavController(navController)
}
WorksFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
uid = FirebaseAuth.getInstance().currentUser?.uid
val worksFragmentViewModel= ViewModelProvider(this).get(WorksFragmentViewModel::class.java)
worksFragmentViewModel.getSelfThumbnailPhoto().observe(viewLifecycleOwner, Observer {
works_fragment_recycyler_view.apply {
setHasFixedSize(true)
layoutManager = GridLayoutManager(context, 3)
adapter = ThumbnailWorksAdapter(it).apply {
notifyDataSetChanged()
}
}
})
}
WorksFragmentViewModel.kt
class WorksFragmentViewModel : ViewModel() {
private var worksFragmentReposity = WorksFragmentReposity()
fun getSelfThumbnailPhoto() = worksFragmentReposity.getSelfThumbnailPhoto()
}
WorksFragmentReposity.kt
class WorksFragmentReposity {
private var selfThumbnailLiveData = SelfThumbnailLiveData()
fun getSelfThumbnailPhoto():LiveData<List<UploadedImages>> = selfThumbnailLiveData
}
SelfThumbnailLiveData.kt
class SelfThumbnailLiveData : LiveData<List<UploadedImages>>(), EventListener<QuerySnapshot> {
private val TAG= SelfThumbnailLiveData::class.java.simpleName
private lateinit var listenerRegistration: ListenerRegistration
private var isRegistered :Boolean = false
private val uid = FirebaseAuth.getInstance().currentUser?.uid
private val query = Firebase.firestore.collection("uploadedImages")
.whereEqualTo("uid", uid)
.orderBy("timestamp", Query.Direction.DESCENDING)
override fun onActive() {
super.onActive()
listenerRegistration = query.addSnapshotListener(this)
isRegistered = true
}
override fun onInactive() {
super.onInactive()
if (isRegistered) {
listenerRegistration.remove()
}
}
override fun onEvent(querySnapshot: QuerySnapshot?, firebaseFirestoreException: FirebaseFirestoreException?) {
Log.d(TAG, ": ${firebaseFirestoreException?.message}");
querySnapshot?.let {
val uploadedImagesList = mutableListOf<UploadedImages>()
it.documents.forEach { documentSnapshot ->
val uploadedImages = documentSnapshot.toObject(UploadedImages::class.java)
?: UploadedImages()
uploadedImagesList.add(uploadedImages)
}
Log.d(TAG, "uploadedImagesList: $uploadedImagesList");
value = uploadedImagesList
}
}
}
TabFragmentPagerAdapter.kt
class TabFragmentPagerAdapter(context: Context,fm: FragmentManager) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
private val TAB_TITLES = arrayOf("Works","User Info")
private val fragments:List<Fragment> = listOf(
WorksFragment(),
UserInfoFragment()
)
override fun getItem(position: Int): Fragment {
return fragments[position]
}
override fun getCount(): Int {
return fragments.count()
}
override fun getPageTitle(position: Int): CharSequence? {
return TAB_TITLES[position]
}
}
ThumbnailWorksAdapter.kt
class ThumbnailWorksAdapter(private val uploadImagesList: List<UploadedImages>) : RecyclerView.Adapter<ThumbnailWorksAdapter.ThumbnailWorksHolder>() {
inner class ThumbnailWorksHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ThumbnailWorksHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.thumbnail_works_holder_images, parent, false)
return ThumbnailWorksHolder(view)
}
override fun getItemCount(): Int {
return uploadImagesList.size
}
override fun onBindViewHolder(holder: ThumbnailWorksHolder, position: Int) {
val uploadedImages = uploadImagesList[position]
holder.itemView.apply {
Picasso.get()
.load(uploadedImages.downloadImagesUriList[0])
.centerCrop(Gravity.CENTER_HORIZONTAL)
.resize(100,100)
.into(thumbnail_works_images)
}
}
}
ProfileFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//Bind tabLayout with viewPager
val tabFragmentPagerAdapter = TabFragmentPagerAdapter(requireContext(), parentFragmentManager).apply {
notifyDataSetChanged()
}
profileViewPager.adapter = tabFragmentPagerAdapter
tabLayout.setupWithViewPager(profileViewPager)
}
Someone had helped me solve the problem.
ProfileFragment.kt
val tabFragmentPagerAdapter = TabFragmentPagerAdapter(requireContext(), childFragmentManager).apply {
notifyDataSetChanged()
}
I have a recyclerView with 10 names and in this activity is possible search for name. With a click in a name the activity moves to another(with help Intents to move for DetailsActivity). It possible make this because in adapter, i have a function that give the position that the user have clicked. But when put a word in menu search this functional gives the position 1 (the real position of name, in exactally moment).
I can send in function in adpter for example, the id of name? What is the correct way to make this?
MainActivity.kt
class MainActivity : AppCompatActivity(), PeopleInStarWarsAdapter.OnNoteListener {
private lateinit var mainViewModel: MainViewModel
private var listDataPeople = ArrayList<DataPeople>()
private lateinit var dataPeopleAdapter: PeopleInStarWarsAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mainViewModel = ViewModelProvider
.AndroidViewModelFactory
.getInstance(application)
.create(MainViewModel::class.java)
//iniciar ViewModel
mainViewModel.init(this)
mainViewModel.getList().observe(this, Observer{ it ->
if(it != null){
listDataPeople = it
dataPeopleAdapter.submitList(listDataPeople)
}
else{
Toast.makeText(this, "Something is wrong!", Toast.LENGTH_SHORT).show()
}
})
initRecyclerView(listDataPeople)
}
private fun initRecyclerView(listDataPeople : ArrayList<DataPeople>) {
recycler_view.layoutManager = LinearLayoutManager(this)
dataPeopleAdapter = PeopleInStarWarsAdapter(listDataPeople, this)
recycler_view.adapter = dataPeopleAdapter
}
override fun onNoteClick(position: Int){
val intent = Intent(this, DetailsActivity::class.java)
intent.putExtra(BuildConfig.POSITION, position)
startActivity(intent)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.main_menu, menu)
val manager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
val searchItem = menu?.findItem(R.id.search)
val searchView = searchItem?.actionView as SearchView
searchView.setSearchableInfo(manager.getSearchableInfo(componentName))
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener{
override fun onQueryTextSubmit(query: String): Boolean {
searchView.clearFocus()
searchView.setQuery("", false)
searchItem.collapseActionView()
Log.v("Information", "Looking for $query")
mainViewModel.checkMatch(query, this#MainActivity)
return true
}
override fun onQueryTextChange(newText: String): Boolean {
Log.v("Information", "$newText")
return false
}
})
return true
}
}
PeopleInStarWarsAdapter.kt
class PeopleInStarWarsAdapter(listDataPeople: ArrayList<DataPeople>, onNoteListener: OnNoteListener) : RecyclerView.Adapter<RecyclerView.ViewHolder>(){
var listDataPeople = ArrayList<DataPeople>()
private var mOnNoteListener : OnNoteListener
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return ViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.layout_list_item, parent,
false)
)
}
override fun getItemCount(): Int {
return listDataPeople.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is ViewHolder -> {
holder.ViewHolder(listDataPeople[position], mOnNoteListener)
}
}
}
fun submitList(dataPeopleList: ArrayList<DataPeople>) {
this.listDataPeople = dataPeopleList
notifyDataSetChanged()
}
class ViewHolder constructor(itemView: View): RecyclerView.ViewHolder(itemView), View.OnClickListener {
private val textViewName : TextView = itemView.textView_name
var onNoteListener: OnNoteListener? = null
fun ViewHolder(dataPeople: DataPeople, onNoteListener: OnNoteListener) {
val name = dataPeople.name
this.textViewName.text = name
this.onNoteListener = onNoteListener
itemView.setOnClickListener(this)
}
override fun onClick(v: View?) {
onNoteListener?.onNoteClick(adapterPosition)
}
}
interface OnNoteListener {
fun onNoteClick(position: Int)
}
init {
this.listDataPeople = listDataPeople
mOnNoteListener = onNoteListener
}
}
You should send position to ViewHolder .
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is ViewHolder -> {
holder.ViewHolder(listDataPeople[position], mOnNoteListener,position)
}
}
}
Then pass this value into onNoteClick()
fun ViewHolder(dataPeople: DataPeople, onNoteListener: OnNoteListener,position: Int) {
val name = dataPeople.name
this.textViewName.text = name
this.onNoteListener = onNoteListener
itemView.setOnClickListener(this)
}
override fun onClick(v: View?) {
onNoteListener?.onNoteClick(position)
}
I am getting started for using Mvvm architecture, but I am facing problem with my adapter -> It never called
I have an adapter here :
class LocationResultAdapter: RecyclerView.Adapter<LocationResultAdapter.ViewHolder>() {
private lateinit var resultList:List<ResultSearchBean>
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding: ItemPostBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.item_post, parent, false)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(resultList[position])
}
override fun getItemCount(): Int {
return if (resultList.isNotEmpty()) {
resultList.size
} else {
0
}
}
fun updateList(list: List<ResultSearchBean>) {
resultList = list
notifyDataSetChanged()
}
class ViewHolder(private val binding: ItemPostBinding):RecyclerView.ViewHolder(binding.root){
private val viewModel = LocationViewModel()
fun bind(resultSearchBean: ResultSearchBean){
viewModel.bind(resultSearchBean)
binding.viewModel = viewModel
}
}
}
this adapter is called in my ViewModel
class LocationResultViewModel(private val resultSearchDao: ResultSearchDao): BaseViewModel() {
#Inject
lateinit var mFi9Api: Fi9Api
private lateinit var mSubscription: Disposable
var mSearchText: String = ""
val adapter: LocationResultAdapter = LocationResultAdapter()
override fun onCleared() {
super.onCleared()
mSubscription.dispose()
}
fun search(searchText: String) {
resultLocations(searchText)
}
private fun resultLocations(searchText: String) {
mSearchText = searchText
mSubscription = mFi9Api.getLocation(mSearchText)
.flatMap { resource ->
return#flatMap Observable.fromCallable {
resultSearchDao.deleteAll()
resultSearchDao.insertAll(resource.distinctBy { r -> r.label })
}
}
.concatMap {
return#concatMap resultSearchDao.all()
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(GetLocationListSubscriber())
}
inner class GetLocationListSubscriber : ResourceObserver<List<ResultSearchBean>>() {
override fun onNext(#NonNull t: List<ResultSearchBean>) {
adapter.updateList(t)
}
override fun onError(#NonNull e: Throwable) {
}
override fun onComplete() {
// Nothing to do
}
}
In my activity I have this following code :
class LocationResultActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var viewModel: LocationResultViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.resultList.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
viewModel = ViewModelProviders.of(this, ViewModelFactory(this)).get(LocationResultViewModel::class.java)
binding.viewModel = viewModel
search_btn.setOnClickListener {
viewModel.search(search_et.text.toString())
}
}
}
Only the method: adapter.updateList(t) is called.
I put some break point on onCreateViewHolder, OnBindViewHolder, getItemCount but it never called
What did I do that does not work?
Thank you for your help
I think you need to assign your adapter to your RecyclerView.
Try this:
binding.resultList.adapter = viewModel.adapter