onClickListenner from RecyclerView not working - android

I'm using a RecyclerView to show some info from Firebase, with kotlin in Android Studio.
But when I click on the RecyclerView, it return the position as -1, so the page that opens that item is always empty...
This is my code from setOnClickListener on the ViewHolder:
class CustomViewHolder(view: View): RecyclerView.ViewHolder(view){
val titulo = view.findViewById<TextView>(R.id.txtTitle)
val localizacao = view.findViewById<TextView>(R.id.txtDescription)
//val urlPag = view.findViewById<TextView>(R.id.record_amount)
//val descricao = view.findViewById<TextView>(R.id.record_date)
val img = view.findViewById<ImageView>(R.id.imageItem)
init {
view.setOnClickListener{
val position: String = CustomViewHolder(it).bindingAdapterPosition.toString()
val intent = Intent(view.context, NotificationActivity::class.java).apply {
putExtra("id", position)
println(position)
}
view.context.startActivity(intent)
}
}
}
This is the fragment were the recyclerView is:
class InboxFragment : Fragment() {
private var listData: List<Notifications>? = null
private var adapter: MainAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_inbox, container, false)
val rv = view.findViewById<RecyclerView>(R.id.recyclerView)
rv.setHasFixedSize(true)
rv.layoutManager = LinearLayoutManager(context)
listData = ArrayList()
val nm = FirebaseDatabase.getInstance().getReference("notifications")
nm.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
if (dataSnapshot.exists()) {
for (npsnapshot in dataSnapshot.children) {
val l: Notifications? = npsnapshot.getValue(Notifications::class.java)
if (l != null) {
(listData as ArrayList<Notifications>).add(l)
}
}
adapter = MainAdapter(listData)
rv.adapter = adapter
}
}
override fun onCancelled(databaseError: DatabaseError) {}
})
return view
}
}
This is the adapter:
class MainAdapter(var listData: List<Notifications>?) : RecyclerView.Adapter<CustomViewHolder>(){
override fun getItemCount(): Int {
return listData!!.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
//create view
val layoutInflater = LayoutInflater.from(parent.context)
val cellForRow = layoutInflater.inflate(R.layout.inforow, parent, false)
return CustomViewHolder(cellForRow)
}
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
val ld: Notifications = listData!![position]
holder.titulo.text = ld.titulo
holder.localizacao.text = ld.localizacao
Picasso.get().load(ld.img).into(holder.img)
}
}
Can someone please help?

Related

can't call the bottomsheet from the recyclerview adapter

i am doing movies app so i am using recycler view to list all the movies list and i need to show the details of the movie in bottomsheetdialog when user click on the movie list the bottom sheet crash the app please help me what is the error here i post my code this is my code with nested recyclerview and bottomsheet with it please help me
this is recycleradapter
class ListMoviesAdapter(
private val movies: MutableList<Item>,
) :
RecyclerView.Adapter<ViewHolder>() {
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var contentImage: ImageView? = itemView.findViewById(R.id.contentImage)
var contentTitle: TextView? = itemView.findViewById(R.id.contentTitle)
var contentSubTitle1: TextView? = itemView.findViewById(R.id.contentSubtitle1)
}
interface onItemClickListener {
fun onItemCLick(position: Int)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val view = inflater.inflate(R.layout.item_6, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val MoviesData: Item = movies.get(position)
holder.contentImage?.let {
Glide.with(it)
.load(MoviesData.media.thumbnail)
.fitCenter()
.into(holder.contentImage!!)
}
holder.contentImage?.setOnClickListener {
val moviesFragment = MoviesFragment()
val bottomsheet = DetailsFragment()
bottomsheet.show(moviesFragment.requireActivity().supportFragmentManager,"Bottomsheet")
Toast.makeText(holder.itemView.context, MoviesData.text.title, Toast.LENGTH_LONG).show()
}
holder.contentTitle?.text = MoviesData.text.title
holder.contentSubTitle1?.text = MoviesData.text.subtitle1
}
override fun getItemCount(): Int {
return movies.size
}
}
this is bottom sheet
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
// override fun onAttach(context: Context) {
// adapter = ImageSliderAdapter(context)
// super.onAttach(context)
// }
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_movies, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val imageslider = view.findViewById<SliderView>(R.id.image_slider)
val slider: MutableList<Item> = mutableListOf()
adapter = ImageSliderAdapter(requireContext())
movie_recycle = view.findViewById(R.id.movie_recycle)
imageslider.setSliderAdapter(adapter)
partner_recycle = view.findViewById(R.id.partnets_scroll)
imageslider.setIndicatorAnimation(IndicatorAnimationType.WORM) //set indicator animation by using SliderLayout.IndicatorAnimations. :WORM or THIN_WORM or COLOR or DROP or FILL or NONE or SCALE or SCALE_DOWN or SLIDE and SWAP!!
imageslider.setSliderTransformAnimation(SliderAnimations.SIMPLETRANSFORMATION)
imageslider.autoCycleDirection = SliderView.AUTO_CYCLE_DIRECTION_BACK_AND_FORTH
imageslider.scrollTimeInSec = 3
imageslider.isAutoCycle = true
imageslider.startAutoCycle()
setupView()
getMovieList()
adapter.addImageslider(slider)
super.onViewCreated(view, savedInstanceState)
}
fun addmovielist(movies: MutableList<Item>) {
adapter.addImageslider(movies)
}
private fun getMovieList() {
val apicall = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.build()
.create(Api::class.java)
val moviedata = apicall.GetMovieList()
moviedata.enqueue(object : Callback<ImageSLider> {
override fun onResponse(call: Call<ImageSLider>, response: Response<ImageSLider>) {
val responeBody = response.body()!!
val page = responeBody.page.body.rows[0].items
addmovielist(page)
partner_list(responeBody.page.body.rows[1].items)
val size = responeBody.page.body.rows.size - 1
for (data in 3..size) {
list_movies.add(responeBody.page.body.rows[data])
}
movies_list(list_movies)
}
override fun onFailure(call: Call<ImageSLider>, t: Throwable) {
Toast.makeText(requireActivity(), t.toString(), Toast.LENGTH_LONG).show()
}
})
}
#SuppressLint("NotifyDataSetChanged")
fun partner_list(part_list: MutableList<Item>) {
all_partner.addAll(part_list)
partner_adapter = PartnerAdapter(all_partner)
partner_recycle.adapter?.notifyDataSetChanged()
}
#SuppressLint("NotifyDataSetChanged")
fun movies_list(movie_lst: MutableList<Rows>) {
all_movies.addAll(movie_lst)
ContentAdapter(all_movies)
movie_recycle.adapter?.notifyDataSetChanged()
}
fun setupView() {
partner_recycle.adapter = PartnerAdapter(all_partner)
partner_recycle.layoutManager =
LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
movie_recycle.adapter = ContentAdapter(all_movies)
movie_recycle.layoutManager =
LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
}
}
this is nested recyclerview
class ContentAdapter(val item: MutableList<Rows>) :
RecyclerView.Adapter<ContentAdapter.ContentAdapterVH>() {
var itemlist: MutableList<Item> = mutableListOf()
class ContentAdapterVH(itemView: View?) : RecyclerView.ViewHolder(itemView!!) {
val recycleMovie: RecyclerView? = itemView?.findViewById(R.id.movie_scroll)
val categoryText: TextView? = itemView?.findViewById(R.id.title_movie_txt)
val dashboardScreen = DashboardScreen()
val moviesFragment = MoviesFragment()
fun bind(data: Rows) {
recycleMovie?.apply {
recycleMovie.adapter = ListMoviesAdapter(data.items, moviesFragment)
layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ContentAdapterVH {
val inflater = LayoutInflater.from(parent.context)
val view = inflater.inflate(R.layout.item_6_list, parent, false)
return ContentAdapterVH(view)
}
override fun onBindViewHolder(holder: ContentAdapterVH, position: Int) {
val contentData: Rows = item.get(position)
holder.categoryText?.text = contentData.text.title
holder.bind(contentData)
}
override fun getItemCount(): Int {
return item.size
}
}
please help to solve this or give any link to refer this thank you
Just create a object class and create a method for bottom sheet and pass the context to this method. And from adapter, call this method on click on the item or where you want to display the bottom sheet
Simple way is that you have to set click listener on onBindViewHolder method in adapter and directly call this showBottomSheet method. And pass the required data to it for displaying is in bottom sheet
object BottomSheetUtils {
fun showBottomSheet(
context:Context
) {
val bottomSheetDialog = BottomSheetDialog(context)
bottomSheetDialog.setContentView(R.layout.your_custom_bottom_sheet_layout)
// Just update UI and set click listeners etc...
bottomSheetDialog.textviewName.text = "Example"
bottomSheetDialog.show()
}
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val MoviesData: Item = movies.get(position)
holder.contentImage?.let {
Glide.with(it)
.load(MoviesData.media.thumbnail)
.fitCenter()
.into(holder.contentImage!!)
}
holder.contentImage?.setOnClickListener {
val moviesFragment = MoviesFragment()
val bottomsheet = DetailsFragment()
bottomsheet.show(appcompActivity.supportFragmentManager,"Bottomsheet")
Toast.makeText(holder.itemView.context, MoviesData.text.title, Toast.LENGTH_LONG).show()
}
holder.contentTitle?.text = MoviesData.text.title
holder.contentSubTitle1?.text = MoviesData.text.subtitle1
}
I Pass appcompactivity to the bottom adapter and trigger the bottom sheet using support fragment manager thank you all

android kotlin property does not change with passed method to adapter

i have defined a val in my fragment like so
private var selectionMode: Boolean = false
and a property to change it
fun enableSelectionMode() {
selectionMode = true
}
and i passed both to Adapter and want to call enableSelectionMode after clicking on each recycler item but nothing happen
here is my fragment:
class PostsFragment : Fragment() {
private val model: PostsViewModel by activityViewModels()
private var selectionMode: Boolean = false
fun enableSelectionMode() {
selectionMode = true
}
private lateinit var recyclerView: RecyclerView
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_posts, container, false)
recyclerView = view.findViewById(R.id.posts_recycler)
recyclerView.layoutManager = LinearLayoutManager(view.context)
model.posts.observe(viewLifecycleOwner, { items ->
recyclerView.adapter = PostsAdapter(items, model, selectionMode,
::enableSelectionMode)
})
return view
}
}
and my adapter
class PostsAdapter(
private val posts: List<Post>,
private val model: PostsViewModel,
private val selectionMode: Boolean,
private val enableIt: () -> Unit
) :
RecyclerView.Adapter<PostsAdapter.ViewHolder>() {
companion object {
private const val TYPE_FROM = 0
private const val TYPE_TO = 1
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var postContent: TextView = itemView.findViewById(R.id.post_content)
var selectPostCheckBox: ImageView = itemView.findViewById(R.id.post_select_checkbox)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(
if (viewType == TYPE_TO) R.layout.to_post else R.layout.from_post,
parent,
false
)
return ViewHolder(view)
}
#SuppressLint("CheckResult")
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.selectPostCheckBox.visibility = if (selectionMode) View.VISIBLE else View.GONE
holder.postContent.text = selectionMode.toString()
holder.selectPostCheckBox.setImageResource(R.drawable.cursor_color)
holder.itemView.setOnClickListener() {
enableIt()
notifyDataSetChanged()
}
}
override fun getItemCount() = posts.size
override fun getItemViewType(position: Int): Int {
return posts[position].selfPost
}
}

Firebase Recyclerview(Vertical Scroll) always scroll to beginning on click of back button from another activity

Not sure why is this behaviour, but almost tried everything, please let me know in case you are aware of the fix for the issue
When I return from SellerAddNewProductActivity by clicking back button then RecyclerView always scroll to beginning
class SellerHomeFragment : Fragment() {
private var searchInputText:String = ""
private var sellerProductsViewListRecyclerView: RecyclerView? = null
private var layoutManager: RecyclerView.LayoutManager? = null
private var scroll_state: Parcelable? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val root = inflater.inflate(R.layout.fragment_seller_home, container, false)
sellerProductsViewListRecyclerView = root.findViewById(R.id.seller_products_view_list)
layoutManager = LinearLayoutManager(this.context)
sellerProductsViewListRecyclerView?.layoutManager = layoutManager
val searchText: EditText = root.findViewById(R.id.seller_search_product_name)
val searchProductsBtn: Button = root.findViewById(R.id.seller_search_products_btn)
val sellerViewByProductState: Spinner = root.findViewById(R.id.seller_view_by_product_state)
sellerViewByProductState.setSelection(0)
searchProductsBtn.setOnClickListener {
searchInputText = searchText.text.toString()
createProductRecyclerView()
}
sellerViewByProductState?.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{
override fun onNothingSelected(parent: AdapterView<*>?) {
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
createProductRecyclerView()
}
}
return root
}
override fun onResume() {
super.onResume()
if(scroll_state!=null){
sellerProductsViewListRecyclerView!!.layoutManager!!.onRestoreInstanceState(scroll_state)
}
}
override fun onPause() {
super.onPause()
scroll_state = sellerProductsViewListRecyclerView!!.layoutManager!!.onSaveInstanceState()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
createProductRecyclerView()
}
private fun createProductRecyclerView() {
var productRef: DatabaseReference = FirebaseDatabase.getInstance().reference.child(
PRODUCTS_DB_NAME
)
var options: FirebaseRecyclerOptions<Products>? = null
val sellerViewByProductState: Spinner =
requireView().findViewById(R.id.seller_view_by_product_state)
val selectedProductState = sellerViewByProductState.selectedItem.toString()
options = FirebaseRecyclerOptions.Builder<Products>().setQuery(
productRef.child(selectedProductState).orderByChild(SID_PROPERTY)
.equalTo(FirebaseAuth.getInstance().currentUser!!.uid), Products::class.java
).setLifecycleOwner(this).build()
val adapter = object : FirebaseRecyclerAdapter<Products, ProductViewHolder>(options) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductViewHolder {
return ProductViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.product_items_layout, parent, false)
)
}
protected override fun onBindViewHolder(
holder: ProductViewHolder,
position: Int,
model: Products
) {
holder.txtProductName.text = model.pname
holder.txtProductDescription.text = model.description
holder.txtProductPrice.text = "Price = ₹ " + model.price.toString()
val context = holder.itemView.context
Picasso.with(this#SellerHomeFragment.context).load(model.image).networkPolicy(
NetworkPolicy.OFFLINE
).tag(context).into(holder.imageView,
object : Callback {
override fun onSuccess() {
}
override fun onError() {
Picasso.with(this#SellerHomeFragment.context).load(model.image)
.into(holder.imageView)
}
})
holder.itemView.setOnClickListener {
val intent: Intent = Intent(
this#SellerHomeFragment.context,
SellerAddNewProductActivity::class.java
)
intent.putExtra("category", model.category)
intent.putExtra("pid", model.pid)
val sellerViewByProductState: Spinner =
requireView().findViewById(R.id.seller_view_by_product_state)
val existingProductState = sellerViewByProductState.selectedItem.toString()
intent.putExtra("existingProductState", existingProductState)
startActivity(intent)
}
}
}
sellerProductsViewListRecyclerView?.setAdapter(adapter)
adapter.startListening()
}
}
I'm not sure I understand your code, but I think if you call function setAdapter(adapter) after added product you reload adapter.
When you add item to adapter use function notifyItemInserted() or notifyItemRangeInserted(position, range) on adapter.

RecyclerView doesn`t get elements from firestore KOTLIN firebase

i want to get recyclerview in my homefragment end set into elements from firestore firebase
my problem with get elements from firestore! maybe whos know how to search a problem because elements doesnt come frome firestore!
HomeFragment
class HomeFragment : Fragment() {
private val TAG = "HomeFragment"
private val firebaseRepository: FirebaseNoteRepo = FirebaseNoteRepo()
private var noteList: List<NotesModel> = ArrayList()
private val notesListAdapter: NotesListAdapterClass = NotesListAdapterClass(noteList)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
init(view)
}
private fun init(view: View) {
if(firebaseRepository.getUser() == null){
Log.d(TAG,"Error log user")
}else{ loadNotesData()}
note_list_recycler_view.layoutManager = LinearLayoutManager(context)
note_list_recycler_view.adapter = notesListAdapter
add_note_fab.setOnClickListener {
noteCreateDialog(view)
}
}
private fun loadNotesData() {
firebaseRepository.getNoteList().addOnCompleteListener {
if (it.isSuccessful){
noteList = it.result!!.toObjects(NotesModel::class.java)
notesListAdapter.notesListItem = noteList
notesListAdapter.notifyDataSetChanged()
}else{
Log.d(TAG,"Error: ${it.exception!!.message}")
}
}
}
my NotesModel
data class NotesModel(
val title: String = "",
val date: com.google.firebase.Timestamp? = null,
val post_type: Long = 0
)
my repository
FirebaseNoreRepo
class FirebaseNoteRepo {
private val firebaseAuth: FirebaseAuth = FirebaseAuth.getInstance()
private val firebaseFirestore: FirebaseFirestore = FirebaseFirestore.getInstance()
fun getUser(): FirebaseUser? {
return firebaseAuth.currentUser
}
fun getNoteList(): Task<QuerySnapshot> {
Log.d("HomeFragment"," ad "+ firebaseFirestore.collection("Notes").get().toString())
return firebaseFirestore
.collection("Notes")
.orderBy("title", Query.Direction.ASCENDING)
.get()
}
and my adapter
class NotesListAdapterClass (var notesListItem: List<NotesModel>):
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.note_layout,parent,false)
return ViewHolderNotes(view)
}
override fun getItemViewType(position: Int): Int {
return if (notesListItem[position].post_type == 1L){
POST_TYPE1
}else{
POST_TYPE1
}
}
override fun getItemCount(): Int {
Log.d("HomeFragment","notesListAdapter size : "+notesListItem.size)
return notesListItem.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (getItemViewType(position) == POST_TYPE1){
(holder as ViewHolderNotes).bind(notesListItem[position])
}
}
class ViewHolderNotes(itemView: View):RecyclerView.ViewHolder(itemView){
fun bind(notesModel: NotesModel){
itemView.note_title.text = notesModel.title
}
}
}
in my adapter i have Log.d he say me size of list of item ( is always equal 0), in firestore i have 2 elements. i dont understand why in log i have 0!
Database sceenshot

My RecyclerView is not showing the Anything

I am using MVVM with Room persistence and livedata. I am fetching the data from local database and want to show in the form of list in the recyclerView and my recyclerView is not showing anything.
My adapter is like any other regular adapter
RecyclerView Code
class MyInformationAdapter : RecyclerView.Adapter<MyInformationAdapter.ViewHolder>() {
private var myList: List<PersonInformation> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val view = layoutInflater.inflate(R.layout.my_adapter_data, parent, false)
return ViewHolder(view)
}
override fun getItemCount(): Int = myList.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
var myDataClass: PersonInformation = myList[position]
holder.name.text = myDataClass.name
holder.fName.text = myDataClass.fatherName
holder.email.text = myDataClass.email
holder.contact.text = myDataClass.contactNo.toString()
}
fun updateTheState(myList: List<PersonInformation>){
this.myList = myList
notifyDataSetChanged()
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var name: TextView = itemView.findViewById(R.id.yourName)
var fName: TextView = itemView.findViewById(R.id.yourFatherName)
var email: TextView = itemView.findViewById(R.id.yourEmail)
var contact: TextView = itemView.findViewById(R.id.yourContact)
}
}
RecyclerView Activity Code
class FinalActivity : AppCompatActivity() {
private var myDataList : List<PersonInformation> = ArrayList()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_final)
setAdapter()
}
private fun setAdapter() {
val adapter = MyInformationAdapter()
val layoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = layoutManager
recyclerView.adapter = adapter
adapter.updateTheState(myDataList)
}
}
*Fragment as a View of MVVM *
class PersonalInformationFragment : Fragment() {
private var viewModel: PersonInformationViewModel? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_personal_information, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
btn.setOnClickListener {
viewModel = ViewModelProviders.of(this)[PersonInformationViewModel::class.java]
viewModel?.getAllData()?.observe(this, Observer {
this.setAllData(it)
})
val intent = Intent(activity, FinalActivity::class.java)
startActivity(intent)
}
}
private fun setAllData(personInformation: List<PersonInformation>) {
val setData = PersonInformation(
name.text.toString(),
fName.text.toString(),
email.text.toString(),
contact.text.toString().toInt()
)
viewModel?.setTheData(setData)
}
}

Categories

Resources