Problem with Picasso while binding image to recyclerview - android-recyclerview

I am not able to bind my image from firebase to recyclerview using Picasso.
Is it incorrect to bind this way?
Picasso.get().load(img).fit().centerCrop()
.into(imgViewUser)
Hope someone with experience with Picasso can give me some guidance. Thank you so much in advance.
#SuppressLint("ResourceType")
override fun onBindViewHolder(holder: UserViewHolder, position: Int, model: Game) {
val tvGameName: TextView = holder.itemView.findViewById(R.id.tvHeading)
val imgViewUser: View? = holder.itemView.findViewById(R.id.titleImage)
tvGameName.text = model.documentId
val img: URI = model.images?.get(0)
Picasso.get().load(img).fit().centerCrop()
.into(imgViewUser)
//val tvCounter: TextView = holder.itemView.findViewById(android.R.id.text1)
//val tvLang: TextView = holder.itemView.findViewById(android.R.id.text2)
//tvCounter.text = model.counter.toString()
//tvLang.text = model.documentId
Toast.makeText(applicationContext, "image is $img", Toast.LENGTH_LONG).show()
}
}
rvUsers.adapter = adapter
rvUsers.layoutManager = LinearLayoutManager(this)
}

The mistake is the wrongly assigned imgViewUser as View, which should have been ImageView. Now it is all good. Tks!

Related

I have a problem trying to use a getContent to replace the onActivityResult

The problem arises when using the registerForActivityResult, then it gives me an error when trying to make the contract (ActivityResultContacts), although I suppose that this last error derives from the previous error so I will focus on the first problem, that of the registerForActivityResult, I really don't know how to explain the problem itself, so I better leave my code below in case someone wants to take a look and try to help me with the problem, if so, thank you very much in advance.
Have a good day.
private val getContent = registerForActivityResult(ActivityResultContracts.TakePicturePreview()){
bitmap ->
heroBitmap = bitmap
heroImage.setImageBitmap(heroBitmap!!)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.saveButton.setOnClickListener{
val superheroName = binding.heroNameEdit.text.toString()
val alterEgo = binding.alterEgoEdit.text.toString()
val bio = binding.bioEdit.text.toString()
val power = binding.powerBar.rating
val hero = Superhero(superheroName, alterEgo, bio, power)
openDetailActivity(hero)
}
heroImage = binding.heroImage
heroImage.setOnClickListener{
openCamera()
}
}
private fun openCamera() {
getContent.launch(null)
}
private fun openDetailActivity(hero: Superhero){
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra(DetailActivity.HERO_KEY, hero)
intent.putExtra(DetailActivity.BITMAP_KEY, heroBitmap)
startActivity(intent)
}
}

How can I change recyclerview item background color permanent and transact new Fragment?

I want to change the color of recyclervView item that I clicked(so user can understand that already checked the detail of the item) and go detail fragment page. However this background color change must be permanent should I store it in livedata of recycler view items. I share my codes at the end I am new to android programming so please explain your solution for beginner and my english level is not good. Thanks for everything.
class AdapterRecycler() :
RecyclerView.Adapter<AdapterRecycler.ViewHolder>()
class ViewHolder(view: View, listener: onItemClickListener) : RecyclerView.ViewHolder(view) {
val name: TextView = view.findViewById(R.id.gameId)
val score: TextView = view.findViewById(R.id.scoreId)
val genre: TextView = view.findViewById(R.id.genres)
val layout1: RelativeLayout = view.findViewById(R.id.rowlayout)
init {
// Define click listener for the ViewHolder's View.
//val textView : TextView = view.findViewById(R.id.gameId)
itemView.setOnClickListener {
layout1.setBackgroundColor(Color.rgb(224,224,224))
listener.onItemClick(adapterPosition)
}
}
}
// Create new views (invoked by the layout manager)
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
// Create a new view, which defines the UI of the list item
val view = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.text_row_item, viewGroup, false)
return ViewHolder(view, listenerItems)
}
class Games : Fragment() {
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
adapter.setOnItemClickListener(object : AdapterRecycler.onItemClickListener {
override fun onItemClick(position: Int) {
// Fragment transaction to detail page
requireActivity().supportFragmentManager.beginTransaction()
.replace(R.id.fragmentContainerView2, Details()).commit()
}
})
}
Should I store a boolean value in here to save item checked status?
data class Game(val name : String, val score : Int, val genres : Array<String>)
I tried solution at my codes and I get transaction but not the color changes of item layout.
I think it will be good if you'll update your Game model, after it became checked. Something like this:
data class Game(.., var isChecked: Boolean = false)
And inside your AdapterRecycler.onItemClickListener realization call ViewModel function to update isChecked value:
fun onItemChecked(position: Int) {
val item = TODO("get item by position from your live data")
item.isChecked = !item.isChecked
}
In addition, you should override your ViewHolder to setup a background rely on your isCheked value (it will be the same as must be after ViewHolder notify calls):
class ViewHolder(view: View, listener: onItemClickListener) : RecyclerView.ViewHolder(view) {
...
fun bind(item: Game) {
val backColor = if (item.isChecked) Color.GREEN else Color.BLUE
layout1.setBackgroundColor(Color.rgb(224,224,224))
}
}
Call bind function from your AdapterRecycler.onBindViewHolder this way:
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(getItem(position), callback)
}
Don't forget to notify your adapter.
Guys thanks to your replies I reviewed my code and got solution.
Here is my edit at the code:
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
...
val color = if (_data[position].isChecked) Color.rgb(224,224,224) else Color.WHITE
viewHolder.layout1.setBackgroundColor(color)
...
}
That way I change the color of recyclerview item color since I change the fragments make the viewmodel at activity based and used it shared viewModel between fragments
class MainActivity : AppCompatActivity() {
private lateinit var viewModel: GamesViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
...
viewModel = ViewModelProvider(this)[GamesViewModel::class.java]
...
}
Then I added the boolean variable to my model.
data class Game(val name : String, val score : Int, val genres : Array<String>, var isChecked : Boolean = false)
Then I change the liveData's attribute of isChecked at the click listener.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
adapter.setOnItemClickListener(object : AdapterRecycler.onItemClickListener {
override fun onItemClick(position: Int) {
viewModel= ViewModelProvider(requireActivity()).get(GamesViewModel::class.java)
val item = viewModel.liveData.value!!.get(position)
item.isChecked = true
// toGo next fragment
requireActivity().supportFragmentManager.beginTransaction()
.replace(R.id.fragmentContainerView2, Details()).commit()
}
})
Voilà we got the perfect result thanks for helping me, have a great day.

How to open different acitivies when click any recyclerView Items in Kotlin? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 months ago.
Improve this question
I got crazy ı am not able find solution. Please help me. 2 days ı am looking for solution. I clearly watn that if I click any recylerView Item starting a new activity. Each item has to own its activity.How to implement codes?. Thanks in advance.
My adapter code:
class CustomAdapter(private val mList: List<ItemsViewModel>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
// create new views
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
// inflates the card_view_design view
// that is used to hold list item
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.card_view_design, parent, false)
return ViewHolder(view)
}
// binds the list items to a view
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val ItemsViewModel = mList[position]
// sets the image to the imageview from our itemHolder class
holder.imageView.setImageResource(ItemsViewModel.image)
// sets the text to the textview from our itemHolder class
holder.textView.text = ItemsViewModel.text
holder.itemView.setOnClickListener {
}
}
// return the number of the items in the list
override fun getItemCount(): Int {
return mList.size
}
// Holds the views for adding it to image and text
class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
val imageView: ImageView = itemView.findViewById(R.id.imageview)
val textView: TextView = itemView.findViewById(R.id.textView)
}
}
My recyclerview.kt :
class recyclerView : AppCompatActivity() {
private lateinit var binding: ActivityRecyclerViewBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityRecyclerViewBinding.inflate(layoutInflater)
setContentView(binding.root)
supportActionBar?.hide()
// getting the recyclerview by its id
val recyclerview = findViewById<RecyclerView>(R.id.recyclerview)
// this creates a vertical layout Manager
binding.recyclerview.layoutManager = LinearLayoutManager(this)
// ArrayList of class ItemsViewModel
val data = ArrayList<ItemsViewModel>()
data.add(ItemsViewModel(R.drawable.jumping_jack, "Jumping Jack"))
data.add(ItemsViewModel(R.drawable.jumping_aquats, "Jumping Squat"))
// This will pass the ArrayList to our Adapter
val adapter = CustomAdapter(data)
// Setting the Adapter with the recyclerview
recyclerview.adapter = adapter
}
}
If you put a list object to adapter like param, you can get position of item, and use this position to start activity you want.
something like this:
add listener in your adapter
class CustomAdapter(
private val mList: List<ItemsViewModel>,
val clickListener: RecycleViewOnClickListener
) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
...
}
in your bindViewHolder:
override fun onBindViewHolder(holder:
RecyclerView.ViewHolder,position: Int) {
holder.itemView.setOnClickListener {
clickListener.onItemClick(position)
}
}
and add simple interface:
interface RecycleViewOnClickListener {
fun onItemCLick(position: Int)
}
in your activity, get model from list with your position:
class recyclerView : AppCompatActivity(), RecycleViewOnClickListener {
override fun onItemClick(pos: Int) {
val model = yourList[pos]
//start new activity
}
}
then when you init adapter:
// This will pass the ArrayList to our Adapter
val adapter = CustomAdapter(data, this)
You can do this by using high order function it will be easy
In you adapter class (pass list and high order function as callback)
class YourAdapter(private val itemList: List<Model>, private val onItemClicked: (item) -> Unit) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
// your code
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
onItemClicked(itemList[position])
}
In your activity/Fragment where you are assigning adapter assign in this way.
whenever item is clicked it will land here, and you can start your activity, you will get item also from adapter on which user clicked
YourAdapter(list) { item ->
//start activity
}
Note: Always write some code with question, it will be easy for us to answer you and guide you what is wrong in your code.
Happy Coding!

How to pass Firebase Realtime database images from reyclerview to image view in another activity. KOTLIN

I have Firebase Realtime Database images displayed in a reyclerview. When users click that image, I want it to send the image to another activity's IMAGEVIEW and open that activity at the same time.
These are pictures of an example I saw on Youtube
As you can see in the second picture. It sent the data from the recyclerview to the imageview in the activity and opened that activity.
My adapter class
class AbstractAdapter(private val mContext: Context, private val abstractList: ArrayList<Abstract>) :
RecyclerView.Adapter<AbstractAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.abstract_image_view, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.imageView.setOnClickListener {
val intent = Intent(mContext, PreviewActivity::class.java)
intent.putExtra("abstract", abstractList[position].abstract.toString())
mContext.startActivity(intent)
}
holder.download_btn.setOnClickListener { }
Glide.with(mContext)
.load(abstractList[position].abstract)
.into(holder.imageView)
}
override fun getItemCount(): Int {
return abstractList.size
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val imageView: ImageView = itemView.findViewById(R.id.abstractImageView)
val download_btn: Button = itemView.findViewById(R.id.abstractDownloadBtn)
}
companion object {
private const val Tag = "RecyclerView"
}
Activity to receive image
class PreviewActivity : AppCompatActivity() {
private lateinit var previewImage: ImageView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_preview)
previewImage = findViewById(R.id.preview_image)
val previewImage: ImageView = findViewById(R.id.preview_image)
val bundle :Bundle? = intent.extras
val preview = bundle!!.getString("abstract")
}
Data model
class Abstract(var abstract: String? = null) {
}
I've tried running this code, but it doesn't show my image in the next activity. The Logcat doesn't give me any error, because according to it my code is running perfectly except that it's not showing the image in the next activity. I must be missing something, but I don't know what it is.
You have to set the image url to ImageView using Glide in second activity like this:
class PreviewActivity : AppCompatActivity() {
private lateinit var previewImage: ImageView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_preview)
previewImage = findViewById(R.id.preview_image)
val previewImage: ImageView = findViewById(R.id.preview_image)
val bundle :Bundle? = intent.extras
val preview = bundle!!.getString("abstract")
Glide.with(this)
.load(preview)
.into(previewImage)
}

RecyclerView doesn't display data but onBindViewHolder never called

I'm using recyclerView to display my data but anything is displaying. The onBindViewHolder is never called and the onCreateViewHolder also.
I initialize the adapter in the viewModel with the data which I got from room but anything is displaying. The data in the viewModel is there when I want give it to the adaptater.
There's the adaptater,
class CountryInfoAdapter : RecyclerView.Adapter<TextItemViewHolder>() {
var data = listOf<DevByteCountryProperty>()
set(value) {
field = value
notifyDataSetChanged()
}
override fun getItemCount() = data.size
override fun onBindViewHolder(holder: TextItemViewHolder, position: Int) {
val item = data[position]
holder.textView.text = item.name.toString()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TextItemViewHolder {
//The inflater knows how to create views from XML layout. The context is the context of the RecyclerView.
val layoutInflater = LayoutInflater.from(parent.context)
val view = layoutInflater.inflate(R.layout.text_item_view, parent, false) as TextView
Timber.i("Data from adaptater : ${data.toString()}")
return TextItemViewHolder(view)
}
}
There is the Fragment,
class CountryInfoFragment : Fragment() {
private lateinit var viewModel: CountryInfoViewModel
private lateinit var viewModelFactory: CountryInfoViewModelFactory
private lateinit var binding: FragmentCountryInfoBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
binding = DataBindingUtil.inflate(inflater,
R.layout.fragment_country_info,container,false)
val application = requireNotNull(this.activity).application
viewModelFactory = CountryInfoViewModelFactory(application)
viewModel = ViewModelProvider(this,viewModelFactory).get(CountryInfoViewModel::class.java)
binding.viewModel = viewModel
val adapter = CountryInfoAdapter()
viewModel.countriesProperty.observe(viewLifecycleOwner, Observer {
it?.let {
adapter.data = it
}
})
binding.countryList.adapter = adapter
binding.lifecycleOwner = viewLifecycleOwner
setHasOptionsMenu(true)
return binding.root
}
}
Please try below code, setting up layout manager before assigning adapter to recyclerView
binding.countryList.layoutManager = LinearLayoutManager(this)
binding.countryList.adapter = adapter