I need to remove child from Firebase after onClick from RecyclerView Adapter.
I have something like this:
Firebase database is
recyclerview is
My biggest problem is not sure how to get the "key" of the child node from the recyclerview.
I have been stuck on this supposedly simple thing for about 3 days so hopefully any help is appreciated.
package com.cpg12.findingfresh.adapters
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.cpg12.findingfresh.R
import com.cpg12.findingfresh.database.ShoppingList
import com.google.firebase.database.FirebaseDatabase
class ShoppingListAdapter : RecyclerView.Adapter<ShoppingListAdapter.ShoppingListViewHolder>() {
private val shoppingList = ArrayList<ShoppingList>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ShoppingListViewHolder {
val itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.shopping_list_item, parent, false)
/** References the node to which market data is stored**/
val databaseReference = FirebaseDatabase.getInstance().getReference("Users")
return ShoppingListViewHolder(itemView)
}
override fun onBindViewHolder(holder: ShoppingListAdapter.ShoppingListViewHolder, position: Int) {
val currentItem = shoppingList[position]
holder.sListItem.text = currentItem.shoppingItem
}
override fun getItemCount(): Int {
return shoppingList.size
}
fun updateShoppinglist(shoppingList: List<ShoppingList>){
this.shoppingList.clear()
this.shoppingList.addAll(shoppingList)
notifyDataSetChanged()
}
class ShoppingListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
val sListItem : TextView = itemView.findViewById(R.id.ShoppingItemTV)
override fun onClick(v: View?) {
databaseReference.child(marketName).setValue(markets).child(key).setValue("")
}
}
}
Related
I just started learning Kotlin
i would like to start a new activitys from a RecyclerView with Kotlin.
for example :
if user tap on first item go to activity1
if user tap on secend item go to activity2
and...
i did make adaptor and adaptor will show in a feragment and there isnt any issue with start adaptor
my adaptor code:
package com.mysfk.android
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class ReviewAdaptor() :RecyclerView.Adapter<ReviewAdaptor.ViewHolder>() {
private var titles = arrayOf("بخاری","دریچه","فن و پد","آبیاری","فن چرخشی","مه پاش","پرده")
private var details = arrayOf("جزیئات تست","جزیئات تست","جزیئات تست","جزیئات تست","جزیئات تست","جزیئات تست","جزیئات تست")
private var images = intArrayOf(R.drawable.icon,R.drawable.icon,R.drawable.icon,R.drawable.icon,R.drawable.icon,R.drawable.icon,R.drawable.icon)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ReviewAdaptor.ViewHolder {
val v =LayoutInflater.from(parent.context).inflate(R.layout.card_review,parent,false)
return ViewHolder(v)
}
override fun onBindViewHolder(holder: ReviewAdaptor.ViewHolder, position: Int) {
holder.tittleItem.text = titles[position]
holder.ditealItem.text = details[position]
holder.imageItem.setImageResource(images[position])
}
override fun getItemCount(): Int {
return titles.size
}
inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var imageItem : ImageView
var tittleItem : TextView
var ditealItem :TextView
init {
imageItem = itemView.findViewById(R.id.imageReview)
tittleItem = itemView.findViewById(R.id.titleReview)
ditealItem = itemView.findViewById(R.id.detReview)
itemView.setOnClickListener{
}
}
}
}
and this is my items:
In ReviewAdaptor declare a listener:
private lateinit var itemClickListener: View.OnClickListener
public fun setItemClickListener(listener: View.OnClickListener) {
itemClickListener = listener
}
In your ViewHolder:
itemView.tag = this
itemView.setOnClickListener(itemClickListener)
And in your fragment:
reviewAdaptor.setItemClickListener{
val viewHolder: RecyclerView.ViewHolder = it.tag as RecyclerView.ViewHolder
val position = viewHolder.adapterPosition
// Open activity by postion
}
I can't manage to uset setImageResource on my holder (which is a part of a CardView).
I've already tried to add a image asset but it didn't seem to work.
I would like to know how can I change an image properly in this case.
This is the code of the entire page:
package com.example.revenuer.adapter
import android.R
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.revenuer.entity.Operation
import com.example.revenuer.listener.OperationListener
class HistoryAdapter(val list: List<Operation>): RecyclerView.Adapter<HistoryAdapter.OperationViewHolder>() {
private var listener: OperationListener? = null
fun setOnOperationListener(listener: OperationListener){
this.listener = listener;
}
class OperationViewHolder(view: View, private val listener: OperationListener?): RecyclerView.ViewHolder(view){
val nameView: TextView
val valueView: TextView
val dateView: TextView
val imageView: ImageView
init {
view.setOnClickListener{
listener?.onListItemClick(view, adapterPosition)
}
nameView = view.findViewById(com.example.revenuer.R.id.item_cardview_name)
valueView = view.findViewById(com.example.revenuer.R.id.item_cardview_value)
dateView = view.findViewById(com.example.revenuer.R.id.item_cardview_date)
imageView = view.findViewById(com.example.revenuer.R.id.operation_image)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OperationViewHolder{
val view = LayoutInflater.from(parent.context).inflate(com.example.revenuer.R.layout.operation_item, parent,false)
return OperationViewHolder(view, listener)
}
override fun onBindViewHolder(holder: OperationViewHolder, position: Int) {
val operation = list[position]
holder.nameView.text = operation.name
holder.valueView.text = operation.value
holder.dateView.text = operation.date
if (operation.type) {
holder.imageView.setImageResource(R.drawable.custom_arrow_up)
}
}
override fun getItemCount(): Int {
return list.size
}
}
You have import android.R, so in the rest of your code you need to write com.example.revenuer.R to refer to your own package's R, just like you did elsewhere.
Solution:
Replace import android.R with import com.example.revenuer.R and you can replace all com.example.revenuer.R with R. Explicitly write android.R when you need to.
I am not able to figure out how to change the value of alpha when clicked on the item of the RecyclerView . I want to change the value of alpha from 1 to 0.5 .
Below is the Adapter Class for the same .
package GiftClass
import LeaderboardClass.LeaderboardAdapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.gearsrun.www.R
import kotlinx.android.synthetic.main.item_gift.view.*
class GiftAdapter(private val giftList: List<Gift>) : RecyclerView.Adapter<GiftAdapter.GiftViewHolder>() {
private lateinit var mlistener : onItemClickListener
interface onItemClickListener{
fun onItemClick(position: Int)
}
fun setOnItemClickListener(listener: onItemClickListener){
mlistener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GiftViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_gift,parent,false)
return GiftViewHolder(itemView,mlistener)
}
override fun onBindViewHolder(holder: GiftViewHolder, position: Int) {
val currentItem = giftList[position]
holder.item_img.setImageResource(currentItem.imageResource)
holder.item_price.text = currentItem.price
holder.item_soldNum.text = currentItem.sold_num
holder.item_medal.text = currentItem.medal_num
}
override fun getItemCount() = giftList.size
class GiftViewHolder(itemView: View,listener:onItemClickListener) : RecyclerView.ViewHolder(itemView){
val item_img:ImageView = itemView.item_img
val item_price : TextView = itemView.price
val item_soldNum : TextView = itemView.sold_num
val item_medal : TextView = itemView.medal_num
init {
itemView.setOnClickListener {
listener.onItemClick(absoluteAdapterPosition)
itemView.alpha = 0.5f
}
}
}
}
Added References / Suggestion are appreciated
In the onClickListener , you can get the property itemView.alpha and adjust the alpha values as per your needs
Here is my code :-
Favourite Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat.startActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import java.security.AccessController.getContext
//this is my calling activity
class FavouriteActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.favourite_activity)
val mToolbar: Toolbar = findViewById(R.id.toolbar_favourite)
setSupportActionBar(mToolbar)
getSupportActionBar()?.setDisplayHomeAsUpEnabled(true);
getSupportActionBar()?.setDisplayShowHomeEnabled(true);
setTitle("Favourite Activity");
//getting recyclerview from xml
val recyclerView = findViewById(R.id.recyclerView) as RecyclerView
//adding a layoutmanager
recyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
//it can be staggered and grid
//creating our adapter
val adapter = CustomAdapter(star) //here I am calling the adapter activity
//now adding the adapter to recyclerview
recyclerView.adapter = adapter
}
override fun onSupportNavigateUp(): Boolean {
onBackPressed()
return true
}
}
CustomAdapter class
class CustomAdapter(val userList: ArrayList<User>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
//this method is returning the view for each item in the list
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomAdapter.ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.list_layout_favourite, parent, false)
return ViewHolder(v)
}
//this method is binding the data on the list
override fun onBindViewHolder(holder: CustomAdapter.ViewHolder, position: Int) {
holder.bindItems(userList[position])
holder.imgCopy.setOnClickListener(View.OnClickListener {
holder.shareString(userList[position])
Toast.makeText(holder.itemView.getContext(),"Copy Button Clicked", Toast.LENGTH_SHORT).show()
})
}
//this method is giving the size of the list
override fun getItemCount(): Int {
return userList.size
}
//the class is holding the list view
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val imgCopy: ImageView = itemView.findViewById(R.id.img_copy) as ImageView
val textViewName = itemView.findViewById(R.id.tvTitle) as TextView
fun bindItems(user: User) {
textViewName.text = user.name
}
fun shareString(user: User)
{
val message : String = user.name
val intent = Intent()
intent.action = Intent.ACTION_SEND
intent.putExtra(Intent.EXTRA_TEXT,message)
intent.type = "text/plain"
startActivity(Intent.createChooser(intent,"Share to :")) ///Issue occur right here
}}}
Getting error : Required context , found Intent.
it is working fine in other FragmentActivity.
I have tried various methods to called the context. but anything is not working.
I have also passed the context from Fragment activity, but that also not worked.
Please let me know is there any way to start Intent.
As I am always getting error and stuck due to this.
The startActivity available in the ViewHolder class is different from the one available in activites. So in this method (available in viewholder), the first parameter should be a context. So pass the context as follows:
startActivity(itemView.context, Intent.createChooser(intent,"Share to :"))
I have heard it is good practice to implement the onClickListener inside of the ViewHolder. However, I am not sure how to access the item that is associated with the ViewHolder inside of the onClickListener.
For example:
import android.content.Context
import androidx.recyclerview.widget.RecyclerView
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import kotlinx.android.synthetic.main.post.view.*
import rstudio.vedantroy.swarm.MainActivity.Companion.TAG
class PostAdapter(private val items : List<Post>, private val contex: Context) : RecyclerView.Adapter<MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(LayoutInflater.from(contex).inflate(R.layout.post, parent, false))
}
override fun getItemCount(): Int {
return items.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.bodyContent.text = items[position].content
}
}
class MyViewHolder(view: View): RecyclerView.ViewHolder(view), View.OnClickListener {
override fun onClick(v: View?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
val bodyContent : TextView = view.bodyContent
}
How do I access items, and how do I find out the current index of the ViewHolder?
I looked at this example: Recyclerview(Getting item on Recyclerview), but there was no explanation of where mDataSource comes from.
Personally what I find is a good solution is to set the OnClickListener within the onBindViewHolder.
For example,
// ... adapter class ...
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.view.apply {
bodyContent.text = items[position].content
setOnClickListener {
// TODO Handle onClick
}
}
}
class ViewHolder(val view: View) : RecyclerView.ViewHolder(view)
Also I find just storing the view within the ViewHolder makes it very easy to access any elements within the layout.
I managed to implement this behavior by moving the location of PostViewHolder. However, I am not sure if inner class will break something.
package rstudio.vedantroy.swarm
import android.content.Context
import androidx.recyclerview.widget.RecyclerView
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.cardview.widget.CardView
import kotlinx.android.synthetic.main.post.view.*
import rstudio.vedantroy.swarm.MainActivity.Companion.TAG
class PostAdapter(private val items : List<Post>, private val contex: Context) : RecyclerView.Adapter<PostAdapter.PostViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PostViewHolder {
return PostViewHolder(LayoutInflater.from(contex).inflate(R.layout.post, parent, false))
}
override fun getItemCount() = items.size
override fun onBindViewHolder(holder: PostViewHolder, position: Int) {
holder.bodyContent.text = items[position].content
}
inner class PostViewHolder(view: View): RecyclerView.ViewHolder(view) {
val bodyContent : TextView = view.bodyContent
init {
view.apply {
setOnClickListener {
isClickable = false
Log.d(TAG, "Clicked!")
}
}
}
}
}