problems with sending data - recyclerview - android-studio

good, I'm learning kotlin
I am wanting to send the data from one recyclerview to another recyclerview. By pressing a button, the name, price and photo, I want it to be sent to the other recyclerview and then another one and thus fill the list, what is the error?
this is my code from my first recyclerview, which sends data, I am using bundle in the adapter to send it to the other recyclerview
class Adaptador_Caras(private var caras: ArrayList<Caras>,private var context: Context):RecyclerView.Adapter<Adaptador_Caras.ViewHolder>() {
class ViewHolder(var vista:View,var contexto:Context):RecyclerView.ViewHolder(vista){
fun bind(caras:Caras){
vista.ivFoto.setImageResource(caras.foto)
vista.tvNombre.text=caras.nombre
vista.tvPrecio.text=caras.precio.toString()
vista.btnIngresar.setOnClickListener {
val intent=Intent(contexto,RecyclerView::class.java)
intent.putExtra("FOTO", caras.foto)
intent.putExtra("NOMBRE",caras.nombre)
intent.putExtra("PRECIO",caras.precio)
contexto.startActivity(intent)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.lista_caras,parent,false),context)
}
override fun getItemCount(): Int {
return caras.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(caras[position])
}
}
this is the main activity, where the images are loaded
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
rvCaras.layoutManager=LinearLayoutManager(this)
rvCaras.adapter=Adaptador_Caras(misCaras(),this)
}
private fun misCaras():ArrayList<Caras>{
var caras=ArrayList<Caras>()
caras.add(Caras("lucas",10,R.drawable.foto_01))
caras.add(Caras("toluca",10,R.drawable.foto_02))
caras.add(Caras("jiana",10,R.drawable.foto_03))
caras.add(Caras("joina",10,R.drawable.foto_04))
caras.add(Caras("toto",10,R.drawable.foto_05))
return caras
}
}
this is the adapter of the activity that receives the data
class AdaptadorRecibir(private var recibir:ArrayList<Recibir>,private var context:Context):RecyclerView.Adapter<AdaptadorRecibir.ViewHolder>() {
class ViewHolder(var vista: View, var contexto:Context):RecyclerView.ViewHolder(vista){
fun bind(recibir: Recibir){
vista.ivFotoR.setImageResource(recibir.fotoR)
vista.tvNombreR.text=recibir.nombreR
vista.tvPrecioR.text=recibir.precioR.toString()
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.lista_recibir,parent,false),context)
}
override fun getItemCount(): Int {
return recibir.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(recibir[position])
}
}
this is the activity receive data , here I receive the data
class RecibirRecycler : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_recibir_recycler)
val parametros=this.intent.extras
if (parametros!=null){
val valor1=parametros.getInt("FOTO")
val valor2=parametros.getString("NOMBRE")
val valor3=parametros.getString("PRECIO")
tvNombreR.text=valor2
tvPrecioR.text=valor3
ivFotoR.setImageResource(valor1)
}
}
thanks for your help

Send data with bundle
Inside ViewHolder class:
vista.btnIngresar.setOnClickListener {
startActivity(
Intent(contexto, RecibirRecycler::class.java).putExtras(
bundleOf(
"FOTO" to (caras.foto?: 0),
"NOMBRE" to (caras.nombre?:""),
"PRECIO" to (caras.precio?:"))
))
}

Related

Confused about inheriting RecyclerView.Adapter and RecyclerView.ViewHolder abstract classes (Kotlin/Android Studio)

I am confused about the inheritance of the RecyclerView.Adapter and RecyclerView.ViewHolder abstract classes. In the code below I inherited the abstract class RecyclerView.Adapter, hence I had to override the fun onCreateViewHolder, fun onBindViewHolder and fun getItemCount. I understand that part, however, why am I not required to override the abstract class RecyclerView.ViewHolder(view) as well?
I don't fully understand the explanation from the android studio docs.
class ItemAdapter(
private val context: Context,
private val dataset: List<Affirmation>
) : RecyclerView.Adapter<ItemAdapter.ItemViewHolder>() {
class ItemViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
val textView: TextView = view.findViewById(R.id.item_title)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
// create a new view
val adapterLayout = LayoutInflater.from(parent.context)
.inflate(R.layout.list_item, parent, false)
return ItemViewHolder(adapterLayout)
}
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
val item = dataset[position]
holder.textView.text = context.resources.getString(item.stringResourceId)
}
override fun getItemCount() = dataset.size

Kotlin RecyclerView - Update item to DB

I have a category item in my recyclerView.
There is a TextView and two ImageView as button (Edit button and Delete button).
When I click edit button I want to change TextView to EditText and editbutton change for agreebutton. When I write new text just update my old one.
I show you what I have and almost everything working but don't update my new text and I know code don't look nice and maybe someone can show me how to do it better :)
class CategoryAdapter(private val categoryList: List<Category>, val listener: ClickListener) : RecyclerView.Adapter<CategoryAdapter.MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(CategoryItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.binding.categoryName.text = categoryList[position].name
holder.binding.categoryEditIv.setOnClickListener {
holder.binding.categoryName.visibility = View.GONE
holder.binding.categoryEditName.visibility = View.VISIBLE
holder.binding.categoryEditName.setText(categoryList[position].name)
holder.binding.categoryEditIv.visibility = View.GONE
holder.binding.categoryAgreeIv.visibility = View.VISIBLE
}
val editTxt = holder.binding.categoryEditName
holder.binding.categoryAgreeIv.setOnClickListener {
val edit = editTxt.text.toString()
listener.editAgreeClickItem(edit)
holder.binding.categoryName.visibility = View.VISIBLE
holder.binding.categoryEditName.visibility = View.GONE
holder.binding.categoryAgreeIv.visibility = View.GONE
holder.binding.categoryEditIv.visibility = View.VISIBLE
}
holder.binding.categoryDeleteIv.setOnClickListener {
listener.deleteClickItem(categoryList[position])
}
}
override fun getItemCount(): Int {
return categoryList.size
}
class MyViewHolder(val binding: CategoryItemBinding) : RecyclerView.ViewHolder(binding.root)
interface ClickListener {
fun editAgreeClickItem(text: String)
fun deleteClickItem(category: Category)
}
}
class MainFragment : Fragment(), NewCategory.NewCategoryCreateListener, CategoryAdapter.ClickListener {
private var _binding: FragmentMainBinding? = null
private val binding
get() = _binding!!
private lateinit var shoppingListViewModel: ShoppingListViewModel
private lateinit var categoryAdapter: CategoryAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
shoppingListViewModel = ViewModelProvider(requireActivity())[ShoppingListViewModel::class.java]
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentMainBinding.inflate(layoutInflater,container,false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.categoryRV.layoutManager = LinearLayoutManager(requireContext())
shoppingListViewModel.allCategories.observe(viewLifecycleOwner, {
updateCategories(it)
})
binding.addCategory.setOnClickListener {
val newCategory = NewCategory(this)
newCategory.show(childFragmentManager, "NewCategory")
}
}
private fun updateCategories(list: List<Category>) {
if(list.size == 0){
binding.noResult.visibility = View.VISIBLE
binding.categoryRV.visibility = View.GONE
}else{
binding.noResult.visibility = View.GONE
binding.categoryRV.visibility = View.VISIBLE
categoryAdapter = CategoryAdapter(list, this)
binding.categoryRV.adapter = categoryAdapter
}
}
override fun newCategoryCreate(text: String) {
val newCat = Category(text)
shoppingListViewModel.insertCategory(newCat)
}
override fun editAgreeClickItem(text: String) {
val newText = Category(text)
shoppingListViewModel.updateCategory(newText)
}
override fun deleteClickItem(category: Category) {
shoppingListViewModel.deleteCategory(category)
}
}

How To Show Interstitial Ads in The getView Function in Kotlin?

I'm a Beginner in Kotlin and I want a way to display Interstitial Ad every time I click on the button tvName, but on the contrary, the app crashes whenever I click on the button. I searched for the solution for a long time.
Here's MainActivity
import ...
#Suppress("UNREACHABLE_CODE")
class MainActivity : AppCompatActivity() {
lateinit var mAdView : AdView
var adapter:ChaptersAdapter?=null
var listOfChapters= ArrayList<Chapters>()
#SuppressLint("WrongViewCast")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
MobileAds.initialize(this) {}
mAdView = findViewById(R.id.adView)
val adRequest = AdRequest.Builder().build()
mAdView.loadAd(adRequest)
loadChapters()
adapter = ChaptersAdapter(listOfChapters, this)
lvchapters.adapter = adapter
MobileAds.initialize(this,
"ca-app-pub-3940256099942544~3347511713")
mInterstitialAd = InterstitialAd(this)
mInterstitialAd.adUnitId = "ca-app-pub-3940256099942544/1033173712"
mInterstitialAd.loadAd(AdRequest.Builder().build())
}
fun loadChapters(){
listOfChapters.add(Chapters(" Chapter 1 ", applicationContext.assets.open("Chapter0.txt").bufferedReader().use {
it.readText()
}
))
listOfChapters.add(Chapters(" Chapter 2 ", applicationContext.assets.open("Chapter1.txt").bufferedReader().use {
it.readText()
}
))
}
class ChaptersAdapter: BaseAdapter {
var context:Context?=null
var listOfChaptersLocal= ArrayList<Chapters>()
constructor(listOfChapters:ArrayList<Chapters>,context:Context){
listOfChaptersLocal=listOfChapters
this.context=context
}
override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {
val chapters= listOfChaptersLocal[p0]
var inflator= context!!.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val chaptersView=inflator.inflate(R.layout.list_chapters,null)
chaptersView.tvName.text= chapters.name!!
chaptersView.**tvName.setOnClickListener** {
// **i want to show the Ads in this time frame** but like this example it didn't work
if (mInterstitialAd.isLoaded) {
mInterstitialAd.show()
} else {
Log.d("TAG", "The interstitial wasn't loaded yet.")
}
val intent =Intent(context,ChapterDetails::class.java)
intent.putExtra("name",chapters.name!!)
intent.putExtra("des",chapters.des!!)
context!!.startActivity(intent)
}
return chaptersView
}
override fun getItem(p0: Int): Any {
return listOfChaptersLocal[p0]
}
override fun getItemId(p0: Int): Long {
return p0.toLong()
}
override fun getCount(): Int {
return listOfChaptersLocal.size
}
}
}

Error "None of the following functions can be called with the arguments supplied:" with Toast

I want to create a code to click on items of RecyclerView. I found one from Internet, however it keep getting this error:
None of the following functions can be called with the arguments supplied:
public open fun makeText(p0: Context!, p1: CharSequence!, p2: Int): Toast! defined in android.widget.Toast
public open fun makeText(p0: Context!, p1: Int, p2: Int): Toast! defined in android.widget.Toast
Here's my code:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
val users = ArrayList<User>()
val adapter = CustomAdapter(users)
recyclerView.adapter = adapter
recyclerView.addOnItemClickListener(object : OnItemClickListener {
override fun onItemClicked(position: Int, view: View) {
Toast.makeText(this, "Clicked on " + users.get(position).name, Toast.LENGTH_LONG).show()
}
})
}
interface OnItemClickListener {
fun onItemClicked(position: Int, view: View)
}
fun RecyclerView.addOnItemClickListener(onClickListener: OnItemClickListener) {
this.addOnChildAttachStateChangeListener(object : RecyclerView.OnChildAttachStateChangeListener {
override fun onChildViewDetachedFromWindow(view: View) {
view.setOnClickListener(null)
}
override fun onChildViewAttachedToWindow(view: View) {
view.setOnClickListener {
val holder = getChildViewHolder(view)
onClickListener.onItemClicked(holder.adapterPosition, view)
}
}
})
}
How can I fix that error message?
Toast.makeText(this#YOUR_ACTIVITY_NAME, "Clicked on " + users.get(position).name, Toast.LENGTH_LONG).show()
//In Activity use:
Toast.makeText(this#YOUR_ACTIVITY_NAME, "your message", Toast.LENGTH_LONG).show()
//In Fragments use:
Toast.makeText(requireActivity(), "your message", Toast.LENGTH_LONG).show()
Your problem will be solved...

how to fix error lkotlin.UninitializedPropertyAccessException: lateinit property adapters has not been initialized in my code?

does not set adapter and work it in Kotlin
I take data from retrofit and i test it ,it work.
but when pass array list to adapter,it cant set list
and have error:
kotlin.UninitializedPropertyAccessException: lateinit property adapters has not been initialized
myadapter:
class RecyclerSaleAdapter(var sale_list: ArrayList<sale_agahi>): RecyclerView.Adapter<RecyclerSaleAdapter.ViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.recycler_sale_item, parent, false)
return ViewHolder(v)
}
override fun getItemCount(): Int {
return sale_list.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.cost_view.text=sale_list[position].cost.toString()
holder.area.text=sale_list[position].area
holder.info_view.text=sale_list[position].info
holder.metr_view.text=sale_list[position].metr.toString()
}
class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
val ImageView=itemView.findViewById<ImageView>(R.id.image_sale_view)
val cost_view=itemView.findViewById<TextView>(R.id.cost_text_rec_view)
val area=itemView.findViewById<TextView>(R.id.area_text_rec_view)
val info_view=itemView.findViewById<TextView>(R.id.info_text_rec_view)
val metr_view=itemView.findViewById<TextView>(R.id.metr_text_rec_view)
val btn_rec_item=itemView.findViewById<Button>(R.id.btn_item_rec)
}
}
myactivity on create:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_profile)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
val fab: FloatingActionButton = findViewById(R.id.fab)
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
val toggle = ActionBarDrawerToggle(
this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close
)
drawerLayout.addDrawerListener(toggle)
toggle.syncState()
//var intent=Intent(this,Profile::class.java)
var us= User_info()
us.name=intent.getStringExtra("username")
us.image_url=intent.getStringExtra("image")
user= User_info()
this.user =us
get_sales_list()
var rec=findViewById<RecyclerView>(R.id.rec_sale)
rec.layoutManager = LinearLayoutManager(this, LinearLayout.VERTICAL, false)
rec.adapter=adapters
navView.setNavigationItemSelectedListener(this)
}
and get data fun:
fun get_sales_list()
{
var retrofit = Retrofit.Builder()
.baseUrl("http://sobosha.ir/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val services=retrofit.create(Apiservices::class.java)
val call =services.sale_agahi(user.name.toString())
call.enqueue(object : Callback<sales_list> {
override fun onResponse(call: Call<sales_list>, response: retrofit2.Response<sales_list>) {
var temp:sales_list= response.body()!!
arr_sale= temp
Log.d("arr_sale",arr_sale.list[0].phone.toString())
adapters=RecyclerSaleAdapter(arr_sale.list)
}
override fun onFailure(call: Call<sales_list>, t: Throwable) {
Toast.makeText(applicationContext,t.message,Toast.LENGTH_LONG).show()
}
})
}
I have an error on rec.adapter=adapters
You only set adapters in the line
adapters=RecyclerSaleAdapter(arr_sale.list)
when Retrofit receives a response. The lines
var rec=findViewById<RecyclerView>(R.id.rec_sale)
rec.layoutManager = LinearLayoutManager(this, LinearLayout.VERTICAL, false)
rec.adapter=adapters
are executed after get_sales_list returns but the request is still likely enqueued or sent and the response is not received yet, so adapters isn't initialized.
One workaround would be to pass rec to get_sales_list and make it set rec.adapter instead of adapters. I'd prefer to e.g. make get_sales_list return Future<sales_list> or to make it suspend and return sales_list, but these would be more work.

Resources