I'm trying to build an email client app via javaMail with Kotlin. I used doAsync for multiThreading. But I have some problem. Getting data through the IMAP protocol is okay. When I put data into cardView, it has a problem. I used doAsync again in OnBindViewHolder to get data from javax.Message type. That was slow and not show full data into card View. -> Help me <--
This is adapter
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.View.*
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import g2sysnet.smart_gw.R
import g2sysnet.smart_gw.inters.EventChanger
import kotlinx.android.synthetic.main.mail_reciever_row.view.*
import org.jetbrains.anko.custom.async
import org.jetbrains.anko.doAsync
import java.text.SimpleDateFormat
import javax.mail.Message
import javax.mail.internet.InternetAddress
class testAdapter (val context : Context, val receiveMessage : Array<Message> ,val eventChange : EventChanger):
RecyclerView.Adapter<testAdapter.ViewHolder>(){
#SuppressLint("SimpleDateFormat")
override fun onBindViewHolder(holder : ViewHolder, position: Int) {
val message = receiveMessage[position]
/** visibility **/
holder.itemView.d3p.visibility = INVISIBLE
holder.itemView.imV_attach.visibility = INVISIBLE
doAsync{
val from = message.from[0].toString().split("<")[0]
val subject = message.subject
val receivedDate = SimpleDateFormat("MMM dd").format(message.receivedDate)
val content = message.content.toString()
val seen = message.flags.toString()
/** unchangeable **/
holder.itemView.dateTime.text = receivedDate
holder.itemView.mailSender.text = from
holder.itemView.subjectTxt.text = subject
holder.itemView.bodyTxt.text = content
when (seen) {
"\\Seen" -> {
holder.itemView.d3p.visibility = View.INVISIBLE
}
"\\Flagged" -> {
holder.itemView.star.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.ic_star_border
)
)
holder.itemView.star.setColorFilter(
ContextCompat.getColor(
context,
R.color.icon_tint_selected
)
)
}
"\\Flagged \\Seen" -> {
holder.itemView.star.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.ic_star_border
)
)
holder.itemView.star.setColorFilter(
ContextCompat.getColor(
context,
R.color.icon_tint_selected
)
)
holder.itemView.d3p.visibility = View.INVISIBLE
}
"" -> {
holder.itemView.d3p.visibility = View.VISIBLE
holder.itemView.star.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.ic_star_border
)
)
holder.itemView.star.setColorFilter(
ContextCompat.getColor(
context,
R.color.icon_tint_normal
)
)
}
}
}
holder.itemView.setOnClickListener {
notifyItemChanged(position)
eventChange.change(position)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.mail_reciever_row, parent, false)
return ViewHolder(view)
}
class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView)
override fun getItemCount(): Int {
return receiveMessage.size
}
}
this is main page
class MailBox : AppCompatActivity(),EventChanger, NavigationView.OnNavigationItemSelectedListener {
var adapter : mailReceiveAdapter? = null
override fun change(id: Int) {
H.curRow = id
startActivity(Intent(this#MailBox,ViewerActivity::class.java))
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_mailbox)
val toolbar: Toolbar = findViewById(R.id.mailBoxToolbar)
setSupportActionBar(toolbar)
supportActionBar?.title = "Mail List"
allMail_recycler.layoutManager = LinearLayoutManager(this#MailBox)
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()
navView.setNavigationItemSelectedListener(this#MailBox)
test()
}
fun test(){
val dialog = ProgressDialog(this#MailBox)
dialog.setCancelable(false)
dialog.setMessage("Loading...")
dialog.show()
doAsync {
val props = Properties()
props.setProperty("mail.debug", "true")
props.setProperty("mail.imap.port", "143")
props.setProperty("mail.imap.ssl.enable", "true")
props.setProperty("mail.imap.socketFactory.port", "993")
val session =
Session.getDefaultInstance(props, authenticator(H.currentUser!!.DC_EMAIL, H.currentUser!!.NO_MAILPWD))
val store = session.getStore("imaps")
store.connect(H.currentUser!!.DC_MAILSERVER, H.currentUser!!.DC_EMAIL, H.currentUser!!.NO_MAILPWD)
val emailFolder = store.getFolder("Inbox")
emailFolder.open(Folder.READ_ONLY)
val messages: Array<Message> = emailFolder.messages
activityUiThread {
val adapter = testAdapter(this#MailBox,messages,this#MailBox)
allMail_recycler.adapter = adapter
dialog.dismiss()
}
}
}
override fun onBackPressed() {
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
}
}
I face this
cardView with multiThreading (doAsync)
Related
I have been trying to call a function from fragment to adapter, but I can't approach it right.
I want to invisible the button present in the fragment from adapter.
**My Adapter Code:**
package com.littleboo.brandlogo.Adapters
import android.R
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Build
import android.os.VibrationEffect
import android.os.Vibrator
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat.getSystemService
import androidx.recyclerview.widget.RecyclerView
import com.littleboo.brandlogo.Fragments.QuizFragment
import com.littleboo.brandlogo.MainActivity
import com.littleboo.brandlogo.Models.Question
import com.littleboo.brandlogo.databinding.ActivityMainBinding.inflate
import com.littleboo.brandlogo.databinding.FragmentQuizBinding
import kotlinx.coroutines.NonDisposableHandle.parent
class QuestionAdap(val context: Context, val question: Question) :
RecyclerView.Adapter<QuestionAdap.OptionViewHolder>() {
var index = 1
var score = 0
val animShake: Animation = AnimationUtils.loadAnimation(context, com.littleboo.brandlogo.R.anim.shake)
private var options: List<String> = listOf(question.option1, question.option2, question.option3, question.option4)
inner class OptionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
var optionView = itemView.findViewById<TextView>(com.littleboo.brandlogo.R.id.quiz_option)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OptionViewHolder {
val view = LayoutInflater.from(context).inflate(com.littleboo.brandlogo.R.layout.quizoptions, parent, false)
return OptionViewHolder(view)
}
override fun onBindViewHolder(holder: OptionViewHolder, position: Int) {
holder.optionView.text = options[position]
holder.itemView.setOnClickListener {
question.userAnswer = options[position]
notifyDataSetChanged()
}
if(question.userAnswer == options[position] && question.userAnswer == question.answer){
holder.itemView.setBackgroundResource(com.littleboo.brandlogo.R.drawable.option_item_selected_bg)
score += 10
Toast.makeText(context,"Score is $score", Toast.LENGTH_SHORT).show()
}
else if(question.userAnswer == options[position] && question.userAnswer != question.answer){
holder.itemView.setBackgroundResource(com.littleboo.brandlogo.R.drawable.wrong_option_item_selected_bg)
holder.itemView.startAnimation(animShake)
}
else{
holder.itemView.setBackgroundResource(com.littleboo.brandlogo.R.drawable.non_option_item_selected_bg)
}
}
override fun getItemCount(): Int {
return options.size
}
}
My Quiz Fragment Code:
package com.littleboo.brandlogo.Fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.CircularProgressDrawable
import com.bumptech.glide.Glide
import com.google.firebase.firestore.FirebaseFirestore
import com.littleboo.brandlogo.Adapters.QuestionAdap
import com.littleboo.brandlogo.Models.Question
import com.littleboo.brandlogo.Models.quizmodel
import com.littleboo.brandlogo.R
import com.littleboo.brandlogo.databinding.FragmentQuizBinding
class QuizFragment : Fragment(){
lateinit var binding: FragmentQuizBinding
var quizzes: MutableList<quizmodel>? = null
private var questions = mutableMapOf<String, Question>()
private lateinit var mArraylist: ArrayList<Question>
var index = 1
private lateinit var mfirestore: FirebaseFirestore
private lateinit var mrecycler: RecyclerView
lateinit var myadapter: QuestionAdap
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentQuizBinding.inflate(layoutInflater)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mrecycler = binding.optionList
mrecycler.layoutManager
myadapter = QuestionAdap(requireContext(),Question())
mArraylist = arrayListOf()
questions.map { it.key to it.value }.shuffled().toMap()
setUpFirestore()
setUpEventListener()
}
override fun onDestroy() {
super.onDestroy()
mfirestore.terminate()
// finish()
}
private fun setUpEventListener() {
binding.nextbtn.setOnClickListener {
index++
bindViews()
}
// binding.btnSubmit.setOnClickListener {
// Log.d("FINALQUIZ", questions.toString())
// val intent = Intent(this, ResultActivity::class.java)
// val json = Gson().toJson(quizzes!![0])
// intent.putExtra("QUIZ", json)
// startActivity(intent)
// finish()
// }
}
private fun setUpFirestore() {
mfirestore = FirebaseFirestore.getInstance()
val quizTitle = activity?.intent?.getStringExtra("title")
if (quizTitle != null) {
mfirestore.collection("Quizes").whereEqualTo("title", quizTitle)
.get()
.addOnSuccessListener {
if (it != null && !it.isEmpty) {
quizzes = it.toObjects(quizmodel::class.java)
questions = quizzes!![0].questions
shuffle()
bindViews()
}
}
}
}
private fun bindViews() {
// btnPrevious.visibility = View.GONE
// binding.btnSubmit.visibility = View.GONE
// binding.btnNext.visibility = View.GONE
// if (index == 1) { //first question
// binding.btnNext.visibility = View.VISIBLE
// } else if (index == questions!!.size) { // last question
// binding.btnSubmit.visibility = View.VISIBLE
//// btnPrevious.visibility = View.VISIBLE
// } else { // Middle
//// btnPrevious.visibility = View.VISIBLE
// binding.btnNext.visibility = View.VISIBLE
// }
val circularProgressDrawable = CircularProgressDrawable(requireContext())
circularProgressDrawable.strokeWidth = 8f
// circularProgressDrawable.colorFilter = ("#ac5fe1")
circularProgressDrawable.centerRadius = 30f
circularProgressDrawable.start()
val question = questions!!["question$index"]
question?.let {
Glide.with(this).load(it.imagequiz).placeholder(circularProgressDrawable).into(binding.imagequiz)
val optionAdapter = QuestionAdap(requireContext(), it)
mrecycler.layoutManager = LinearLayoutManager(requireContext())
mrecycler.adapter = optionAdapter
mrecycler.setHasFixedSize(true)
}
}
private fun shuffle() {
val keys = questions.keys.toMutableList().shuffled()
val values = questions.values.toMutableList().shuffled()
keys.forEachIndexed { index, key ->
questions[key] = values[index]
}
}
}
I tried calling fragment in adapter like:
QuizFragment().binding.btnxt.visibility = View.Visible
in BindViewHolder function.
Thank You
You can use kotlin lambda function to achieve it. Like this
class QuestionAdap(val context: Context, val question: Question, var onItemClicked: ((boolean) -> Unit))
call onItemClicked in your adapter where you want it
and in fragment
myadapter = QuestionAdap(requireContext(),Question()) { boolean ->
if (boolean) {
//hide/show
} else {
//hide/show
}
}
You can use the Callback functions of kotlin in your fragment, which will be passed into your adapter. So whenever you invoke that callback from your adapter, it will be triggered in your fragment.
Step 1: Create a method like the one below in your fragment.
private fun showHideButtonFromAdapter (
isButtonVisible: Boolean
) {
// set your button visibility according to isButtonVisible value.
}
Step 2: pass a method from your fragment to adapter as argument
val adapter = YourAdapter(::showHideButtonFromAdapter)
// set above adapter in your recycler view.
Step 3: In your adapter invoke that callback function like the one below.
class ColorPickerAdapter constructor(
private val onItemClicked: (Boolean) -> Unit
) : RecyclerView.Adapter<YourAdapter.ViewHolder>() {
// your other adapter methods here
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
onItemClicked.invoke(pass true or false as per your requirement)
// above invocation will trigger an event in the fragment.
}
}
In your adapter there need to be instance of your fragment, so change it like:
class QuestionAdap(val context: Context, val question: Question, fragment: Fragment) :
RecyclerView.Adapter<QuestionAdap.OptionViewHolder>() {
Then you can call your fragment by simply writing fragment in your adapter like:
override fun onBindViewHolder(holder: OptionViewHolder, position: Int) {
holder.optionView.text = options[position]
holder.itemView.setOnClickListener {
question.userAnswer = options[position]
notifyDataSetChanged()
}
//Example
fragment.shuffle()
And you need to send this fragment instance when you create it's adapter, so in your fragment use this:
myadapter = QuestionAdap(requireContext(),Question(), this)
I am making a quiz app. My main activity has blocks. Each block has a date written over it. the date act as title while fetching information from firebase. These blocks are working perfectly fine, (fetching questions).I also have a floating action button, on clicking displays a calender and we can select date from there and access quiz for that particular day, but it is not working .
Home screen : home screen
Interface while accessing question from block : image
Interface while accessing through floating action bar :image
Main Activity:
package com.example.quiz.activities
import android.annotation.SuppressLint
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.recyclerview.widget.GridLayoutManager
import com.example.quiz.R
import com.example.quiz.adapters.QuizAdapter
import com.example.quiz.databinding.ActivityMainBinding
import com.example.quiz.models.Quiz
import com.google.android.material.datepicker.MaterialDatePicker
import com.google.firebase.firestore.DocumentSnapshot
import com.google.firebase.firestore.FirebaseFirestore
import java.text.SimpleDateFormat
import java.util.*
class MainActivity() : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
lateinit var actionBarDrawerToggle: ActionBarDrawerToggle
lateinit var adapter: QuizAdapter
private var quizList = mutableListOf<Quiz>()
lateinit var firestore : FirebaseFirestore
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setUpViews()
}
fun setUpViews(){
setUpFirestore()
setUpDrawerLayout()
setUpRecyclerView()
setUpDatePicker()
}
#SuppressLint("SimpleDateFormat")
private fun setUpDatePicker() {
// val btnDatePicker = binding.btnDatePicker
binding.btnDatePicker.setOnClickListener{
val datePicker = MaterialDatePicker.Builder.datePicker().build()
datePicker.show(supportFragmentManager,"DatePicker")
datePicker.addOnPositiveButtonClickListener {
Log.d("DATEPICKER",datePicker.headerText)
val dateFormatter = SimpleDateFormat("dd-mm-yyyy")
val date = dateFormatter.format(Date(it))
val intent = Intent(this,QuestionActivity::class.java)
intent.putExtra("DATE",date)
startActivity(intent)
}
datePicker.addOnNegativeButtonClickListener {
Log.d("DATEPICKER",datePicker.headerText)
}
datePicker.addOnCancelListener {
Log.d("DATEPICKER","Date Picker was cancelled")
}
}
}
private fun setUpFirestore() {
firestore = FirebaseFirestore.getInstance()
val collectionReference = firestore.collection("quizzes")
collectionReference.addSnapshotListener{ value, error ->
if(value == null || error != null){
Toast.makeText(this,"Error fetching data",Toast.LENGTH_SHORT).show()
return#addSnapshotListener
}
Log.d("DATA", value.toObjects(Quiz::class.java).toString())
quizList.clear()
quizList.addAll(value.toObjects(Quiz::class.java))
adapter.notifyDataSetChanged()
}
}
private fun setUpRecyclerView(){
val quizRecyclerView = binding.quizRecyclerView
adapter = QuizAdapter(this,quizList)
quizRecyclerView.layoutManager = GridLayoutManager(this,2)
quizRecyclerView.adapter = adapter
}
private fun setUpDrawerLayout(){
val appBar = binding.appBar
val mainDrawer = binding.mainDrawer
val navigationView = binding.navigationView
setSupportActionBar(appBar)
actionBarDrawerToggle = ActionBarDrawerToggle(this,mainDrawer,
R.string.app_name,
R.string.app_name
)
actionBarDrawerToggle.syncState()
navigationView.setNavigationItemSelectedListener {
val intent = Intent(this,ProfileActivity::class.java)
startActivity(intent)
mainDrawer.closeDrawers()
true
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (actionBarDrawerToggle.onOptionsItemSelected(item)){
return true
}
return super.onOptionsItemSelected(item)
}
}
Quiz adapter
package com.example.quiz.adapters
import android.content.Context
import android.content.Intent
import android.graphics.Color
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.cardview.widget.CardView
import androidx.recyclerview.widget.RecyclerView
import com.example.quiz.R
import com.example.quiz.activities.QuestionActivity
import com.example.quiz.models.Quiz
import com.example.quiz.utils.ColorPicker
import com.example.quiz.utils.IconPicker
class QuizAdapter(val context: Context, val quizzes: List<Quiz>) :
RecyclerView.Adapter<QuizAdapter.QuizViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QuizViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.quiz_item,parent,false)
return QuizViewHolder(view)
}
override fun onBindViewHolder(holder: QuizViewHolder, position: Int) {
holder.textViewTitle.text = quizzes[position].title
holder.cardContainer.setCardBackgroundColor(Color.parseColor(ColorPicker.getColor()))
holder.iconView.setImageResource(IconPicker.getIcon())
holder.itemView.setOnClickListener{
Toast.makeText(context,quizzes[position].title,Toast.LENGTH_SHORT).show()
val intent = Intent(context , QuestionActivity::class.java)
intent.putExtra("DATE",quizzes[position].title)
context.startActivity(intent)
}
}
override fun getItemCount(): Int {
return quizzes.size
}
inner class QuizViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var textViewTitle: TextView = itemView.findViewById(R.id.quizTitle)
var iconView: ImageView = itemView.findViewById(R.id.quizIcon)
var cardContainer: CardView = itemView.findViewById(R.id.cardContainer)
}
}
Question Activity
package com.example.quiz.activities
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.widget.Toast
import androidx.core.view.allViews
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.quiz.R
import com.example.quiz.adapters.OptionAdapter
import com.example.quiz.databinding.ActivityQuestionBinding
import com.example.quiz.models.Question
import com.google.firebase.firestore.FirebaseFirestore
import com.example.quiz.models.Quiz
import com.google.gson.Gson
class QuestionActivity : AppCompatActivity() {
var quizzes : MutableList<Quiz>? = null
var questions : MutableMap<String,Question>? = null
var index = 1
lateinit var firestore : FirebaseFirestore
private lateinit var binding: ActivityQuestionBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityQuestionBinding.inflate(layoutInflater)
setContentView(binding.root)
setUpFireStore()
setUpEventListener()
}
private fun setUpEventListener() {
val btnPrevious = binding.btnPrevious
val btnSubmit = binding.btnSubmit
val btnNext = binding.btnNext
btnPrevious.setOnClickListener{
index--
bindViews()
}
btnNext.setOnClickListener{
index++
bindViews()
}
btnSubmit.setOnClickListener{
Log.d("FINAL QUIZ",questions.toString())
val intent = Intent(this,ResultActivity::class.java)
val json = Gson().toJson(quizzes!![0])
intent.putExtra("QUIZ",json)
startActivity(intent)
}
}
private fun setUpFireStore() {
val firestore = FirebaseFirestore.getInstance()
var date = intent.getStringExtra("DATE")
if (date!= null){
firestore.collection("quizzes").whereEqualTo("title",date)
.get()
.addOnSuccessListener {
if (it != null && !it.isEmpty){
Log.d("DATA",it.toObjects(Quiz::class.java).toString())
quizzes = it.toObjects(Quiz::class.java)
questions = quizzes!![0].questions
bindViews()
}
else{
Toast.makeText(this,"Error Fetching data",Toast.LENGTH_SHORT).show()
}
}
}
}
private fun bindViews() {
val btnPrevious = binding.btnPrevious
val btnSubmit = binding.btnSubmit
val btnNext = binding.btnNext
val description = binding.description
val optionList = binding.optionList
btnPrevious.visibility = View.GONE
btnSubmit.visibility = View.GONE
btnNext.visibility = View.GONE
if (index == 1) {
btnNext.visibility = View.VISIBLE
}
else if(index == questions!!.size){
btnSubmit.visibility = View.VISIBLE
btnPrevious.visibility = View.VISIBLE
}
else{
btnNext.visibility = View.VISIBLE
btnPrevious.visibility = View.VISIBLE
}
val question = questions!!["question$index"]
question?.let {
description.text = it.description
val optionAdapter = OptionAdapter(this,it)
optionList.layoutManager = LinearLayoutManager(this)
optionList.adapter = optionAdapter
optionList.setHasFixedSize(true)
}
}
}
No logcat error is shown but this error is shown in run section : E/RecyclerView: No adapter attached; skipping layout
Hello guy i am new to Kotlin android and working on a demo in this demo i am trying to get an image from the gallery and set it in my recyclerview but i am getting the solution requesting you to please find me a solution Thanks in Advance!!
This is my CustomAdapter.kt:-
package com.example.itemgetset
import android.app.Activity
import android.app.AlertDialog
import android.content.ContentValues.TAG
import android.content.Intent
import android.os.Build
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.PopupMenu
import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.snackbar.Snackbar
#Suppress("UNREACHABLE_CODE")
class CustomAdapter(
private var activity: Activity,
private val userList: ArrayList<ProductInfoGetSet>,
private var isforlist: Boolean,
) :
RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val itemview=
LayoutInflater.from(parent.context).inflate(R.layout.list_layout, parent, false)
return ViewHolder(itemview)
}
#RequiresApi(Build.VERSION_CODES.N)
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val productInfoGetSet: ProductInfoGetSet = userList[position]
holder.image = productInfoGetSet.image
holder.txtId.text = productInfoGetSet.id
holder.txtName.text = productInfoGetSet.name
holder.txtQuantity.text = productInfoGetSet.quantity
holder.txtPrice.text = productInfoGetSet.price
val id = userList[position].id
Log.e(TAG, "List item ID: $id")
holder.buttonViewOption.setOnClickListener {
val popup = PopupMenu(activity, holder.buttonViewOption)
popup.inflate(R.menu.pop_menu)
popup.setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.edit -> {
val intent = Intent(activity, AddDetails::class.java)
intent.putExtra("isFor", "Update")
intent.putExtra("id", productInfoGetSet.id)
intent.putExtra("image",productInfoGetSet.image)
intent.putExtra("name", productInfoGetSet.name)
intent.putExtra("quantity", productInfoGetSet.quantity)
intent.putExtra("price", productInfoGetSet.price)
activity.startActivity(intent)
}
R.id.delete -> {
val builder = AlertDialog.Builder(activity)
builder.setTitle("Delete")
builder.setMessage("Do you want to delete the item?")
builder.setPositiveButton("Yes") { _, _ ->
userList.removeAt(position)
notifyItemRemoved(position)
val snack = Snackbar
.make(
holder.linearly,
"Item was removed from the list.",
Snackbar.LENGTH_SHORT
)
snack.show()
}
builder.setNegativeButton("No") { _, _ ->
}
val dialog: AlertDialog = builder.create()
dialog.show()
}
}
false
}
popup.show()
}
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getItemCount(): Int {
return userList.size
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val txtName = itemView.findViewById(R.id.txt_name) as TextView
val txtId = itemView.findViewById(R.id.txt_id) as TextView
var image = itemView.findViewById(R.id.imageView2) as ImageView
val txtQuantity = itemView.findViewById(R.id.txt_quantity) as TextView
val txtPrice = itemView.findViewById(R.id.txt_price) as TextView
val linearly: LinearLayout = itemView.findViewById(R.id.linearlayout)
val buttonViewOption = itemView.findViewById<View>(R.id.txt_Options) as TextView
}
}
in this adapter i gent and error on holder.image = productInfoGetSet.image this line and not get solved.
This is my AddDeatils.kt:-
package com.example.itemgetset
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.os.Build
import android.os.Bundle
import android.os.Message
import android.provider.MediaStore
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import kotlinx.android.synthetic.main.add_item.*
import kotlinx.android.synthetic.main.list_layout.*
class AddDetails : AppCompatActivity() {
private lateinit var btnSubmit: Button
private lateinit var edtName: EditText
private lateinit var edtQuantity: EditText
private lateinit var edtPrice: EditText
private lateinit var imageview: ImageView
companion object {
private const val IMAGE_PICK_CODE = 1000
private const val PERMISSION_CODE = 1001
}
#SuppressLint("SetTextI18n", "ResourceType")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.add_item)
supportActionBar?.hide()
findViewById()
onclick()
if (intent.getStringExtra("isFor").equals("Update")) {
intent.getStringExtra("image")?.toInt()?.let { imageview.setImageResource(it) }
edtName.setText(intent.getStringExtra("name"))
edtQuantity.setText(intent.getStringExtra("quantity"))
edtPrice.setText(intent.getStringExtra("price"))
}
}
private fun findViewById() {
btnSubmit = findViewById(R.id.btn_submit)
edtName = findViewById(R.id.edt_name)
edtQuantity = findViewById(R.id.edt_quantity)
edtPrice = findViewById(R.id.edt_price)
imageview = findViewById(R.id.image_view)
}
#SuppressLint("ResourceType")
private fun onclick() {
btnSubmit.setOnClickListener {
when {
edtName.text.trim().isEmpty() -> {
edtName.error = "Please Enter Product Name"
Toast.makeText(
applicationContext,
"Please Enter Product Name",
Toast.LENGTH_SHORT
)
.show()
}
edtQuantity.text.trim().isEmpty() -> {
edtQuantity.error = "Please Enter Product Quantity"
Toast.makeText(
applicationContext,
"Please Enter Product Quantity",
Toast.LENGTH_SHORT
).show()
}
edtPrice.text.trim().isEmpty() -> {
edtPrice.error = "Please Enter Product Price"
Toast.makeText(
applicationContext,
"Please Enter Product Price",
Toast.LENGTH_SHORT
)
.show()
}
else -> {
Toast.makeText(
applicationContext,
"Product Added Successfully ",
Toast.LENGTH_SHORT
).show()
val temp = Temp()
temp.image = imageview.toString()
temp.name = edtName.text.toString()
temp.quantity = edtQuantity.text.toString()
temp.price = edtPrice.text.toString()
if (intent.getStringExtra("isFor").equals("Update")) {
temp.id = intent.getStringExtra("id").toString()
}
val message: Message = Message.obtain()
message.what = 111
message.obj = temp
MainActivity.handler.sendMessage(message)
finish()
}
}
}
imageview.setOnClickListener {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_DENIED
) {
val permissions = arrayOf(android.Manifest.permission.READ_EXTERNAL_STORAGE)
requestPermissions(permissions, PERMISSION_CODE)
} else {
pickImageFromGallery()
}
} else {
pickImageFromGallery()
}
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
when (requestCode) {
PERMISSION_CODE -> {
if (grantResults.isNotEmpty() && grantResults[0] ==
PackageManager.PERMISSION_GRANTED
) {
pickImageFromGallery()
} else {
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show()
}
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
private fun pickImageFromGallery() {
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
startActivityForResult(intent, IMAGE_PICK_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK && requestCode == IMAGE_PICK_CODE) {
imageview.setImageURI(data?.data)
super.onActivityResult(requestCode, resultCode, data)
}
}
}
And this is my MainActivity.kt:-
package com.example.itemgetset
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Button
import android.widget.GridView
import android.widget.LinearLayout
import android.widget.ListView
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
#Suppress("DEPRECATION")
class MainActivity : AppCompatActivity() {
lateinit var activity: Activity
val userList = ArrayList<ProductInfoGetSet>()
private lateinit var btnProductAdd: Button
lateinit var llEmptyView: LinearLayout
lateinit var llMain: LinearLayout
private var listView: ListView? = null
private var gridView: GridView? = null
lateinit var recyclerView: RecyclerView
private lateinit var llFab: LinearLayout
private lateinit var linearLayoutManager: LinearLayoutManager
private lateinit var gridLayoutManager: GridLayoutManager
private lateinit var adapter: CustomAdapter
private var isforlist = true
companion object {
var handler: Handler = Handler()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
activity = this
initView()
onClicks()
setUpData()
handler = #SuppressLint("HandlerLeak")
object : Handler() {
override fun handleMessage(msg: Message) {
if (msg.what == 111) {
val temp: Temp = msg.obj as Temp
if (temp.id == "") {
userList.add(
ProductInfoGetSet(
(userList.size + 1).toString(),
temp.image,
temp.name,
temp.quantity,
temp.price,
)
)
adapter = CustomAdapter(activity, userList, isforlist)
recyclerView.adapter = adapter
} else {
for (i in userList.indices) {
if (userList[i].id == temp.id) {
userList[i].id = temp.id
userList[i].image = temp.image
userList[i].name = temp.name
userList[i].quantity = temp.quantity
userList[i].price = temp.price
}
}
adapter.notifyDataSetChanged()
}
}
if (userList.size > 0) {
llEmptyView.visibility = View.GONE
llMain.visibility = View.VISIBLE
} else {
llEmptyView.visibility = View.VISIBLE
llMain.visibility = View.GONE
}
}
}
}
private fun changeLayoutManager() {
if (recyclerView.layoutManager == linearLayoutManager) {
recyclerView.layoutManager = gridLayoutManager
} else {
recyclerView.layoutManager = linearLayoutManager
}
}
private fun initView() {
btnProductAdd = findViewById(R.id.btn_product_add)
llFab = findViewById(R.id.ll_fab)
llEmptyView = findViewById(R.id.llEmptyView)
listView = findViewById(R.id.list_product)
gridView = findViewById(R.id.list_productGV)
llMain = findViewById(R.id.llMain)
recyclerView = findViewById(R.id.recycler_view)
recyclerView.layoutManager = LinearLayoutManager(this)
linearLayoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
gridLayoutManager = GridLayoutManager(this, 2)
}
private fun onClicks() {
btnProductAdd.setOnClickListener {
val intent = Intent(this#MainActivity, AddDetails::class.java)
intent.putExtra("isFor", "Add")
startActivity(intent)
}
llFab.setOnClickListener {
val intent = Intent(this#MainActivity, AddDetails::class.java)
intent.putExtra("isFor", "Add")
startActivity(intent)
}
}
private fun setUpData() {
if (userList.size > 0) {
llEmptyView.visibility = View.GONE
llMain.visibility = View.VISIBLE
} else {
llEmptyView.visibility = View.VISIBLE
llMain.visibility = View.GONE
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.menu_view) {
if (userList.size > 0) {
changeLayoutManager()
}
return true
}
return super.onOptionsItemSelected(item)
}
}
My ProductInfoGetSet.kt:-
package com.example.itemgetset
import android.widget.ImageView
class ProductInfoGetSet(
var id: String,
var image: ImageView,
var name: String,
var quantity: String,
var price: String
)
Temp.kt:-
package com.example.itemgetset
import android.widget.ImageView
class Temp {
var id: String = ""
var image: ImageView =
var name: String = ""
var quantity: String = ""
var price: String = ""
}
Thanks in advance!!
I understand you are new to Android. I will list down points below for you to understand clearly.
As a standard practice you must not use ImageView in any model as Model can only hold data.
Use databinding for views.
As suggested by Rupam Saini, you can use Glide or Picasso for image loading.
You can't pass imageView in bundle as it will create different object when you read it again. There is a chance of leaking context also.
Regarding your question
in this adapter i gent and error on holder.image = productInfoGetSet.image this line and not get solved.
You are trying to set an ImageView to another ImageView which is not correct. Temp file is incorrect, there is no value after = . So Temp file must also have error.
It'll be better if you show your ProductInfoGetSet class and the error logs.
You should not set the image directly
holder.image = productInfoGetSet.image
Instead you can get the image's URI and then set it like this
holder.image.setImageUri(imageUri)
If you are still getting issues then you can use the Glide library
I'm trying to build an app with Android Architecture Components. I'm using TMDB API in my app. In my app, a user searches for a movie or series and gets the result. I've achieved this but I want to get all the pages from API with Paging library. (Endless Recyclerview) I've looked at several tutorials but I didn't get what I wanted. Please help me, I'm new with this Android Architecture Components. Thank you in advance.
The API result:
RecyclerViewMovieAdapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.martiandeveloper.muuvi.R
import com.martiandeveloper.muuvi.model.Movie
import kotlinx.android.synthetic.main.recyclerview_movie_item.view.*
class RecyclerViewMovieAdapter(private val movieList: ArrayList<Movie>) :
RecyclerView.Adapter<RecyclerViewMovieAdapter.RecyclerViewMovieViewHolder>() {
lateinit var context: Context
class RecyclerViewMovieViewHolder(var view: View) : RecyclerView.ViewHolder(view)
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): RecyclerViewMovieViewHolder {
context = parent.context
val view = LayoutInflater.from(context)
.inflate(R.layout.recyclerview_movie_item, parent, false)
return RecyclerViewMovieViewHolder(view)
}
override fun getItemCount(): Int {
return movieList.size
}
override fun onBindViewHolder(holder: RecyclerViewMovieViewHolder, position: Int) {
if (movieList[position].mediaType != "person") {
if (movieList[position].mediaType == "tv") {
val title =
movieList[position].originalName + " (" + movieList[position].firstAirDate?.split(
"-"
)?.get(0) + ")"
holder.view.recyclerview_movie_item_titleMTV.text = title
} else {
val title =
movieList[position].title + " (" + movieList[position].releaseDate?.split("-")
?.get(0) + ")"
holder.view.recyclerview_movie_item_titleMTV.text = title
}
holder.view.recyclerview_movie_item_voteAverageMTV.text =
movieList[position].voteAverage.toString()
Glide.with(context)
.load("https://image.tmdb.org/t/p/w300${movieList[position].posterPath}")
.placeholder(R.drawable.logo1)
.centerCrop()
.into(holder.view.recyclerview_movie_item_posterIV)
}
}
fun updateMovieList(newMovieList: List<Movie>) {
movieList.clear()
movieList.addAll(newMovieList)
notifyDataSetChanged()
}
}
Movie.kt
import com.google.gson.annotations.SerializedName
data class Movie(
#SerializedName("original_name")
val originalName: String?,
#SerializedName("genre_ids")
val genreIds: List<Int>?,
#SerializedName("media_type")
val mediaType: String?,
#SerializedName("name")
val name: String?,
#SerializedName("origin_country")
val originCountry: List<String>?,
#SerializedName("first_air_date")
val firstAirDate: String?,
#SerializedName("original_language")
val originalLanguage: String?,
#SerializedName("id")
val id: Int?,
#SerializedName("vote_average")
val voteAverage: Float?,
#SerializedName("overview")
val overview: String?,
#SerializedName("poster_path")
val posterPath: String?,
#SerializedName("title")
val title: String?,
#SerializedName("release_date")
val releaseDate: String?,
#SerializedName("original_title")
val originalTitle: String?)
MovieResult.kt
import com.google.gson.annotations.SerializedName
data class MovieResult(
#SerializedName("page")
val page: Int?,
#SerializedName("total_results")
val totalResults: Int?,
#SerializedName("total_pages")
val totalPages: Int?,
#SerializedName("results")
val results: ArrayList<Movie>?
)
MovieApi.kt
import com.martiandeveloper.muuvi.model.MovieResult
import io.reactivex.Single
import retrofit2.http.GET
import retrofit2.http.Query
interface MovieApi {
#GET("search/multi")
fun getMovie(
#Query("api_key") apiKey: String,
#Query("query") movie: String,
#Query("page") page: Int
): Single<MovieResult>
}
MovieService.kt
import com.martiandeveloper.muuvi.model.MovieResult
import io.reactivex.Single
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
const val API_KEY = "fb640042b4bc08f6f7f65fbd8573f2a9"
const val BASE_URL = "https://api.themoviedb.org/3/"
// https://api.themoviedb.org/3/search/multi?api_key=my_api_key&query=break&page=1
// https://image.tmdb.org/t/p/w342/or06FN3Dka5tukK1e9sl16pB3iy.jpg
class MovieService {
private val api =
Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build()
.create(MovieApi::class.java)
fun getData(movie: String, page: Int): Single<MovieResult> {
return api.getMovie(API_KEY, movie, page)
}
}
AddFragment.kt
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.LinearLayoutManager
import com.martiandeveloper.muuvi.R
import com.martiandeveloper.muuvi.adapter.RecyclerViewMovieAdapter
import com.martiandeveloper.muuvi.databinding.FragmentAddBinding
import com.martiandeveloper.muuvi.viewmodel.AddViewModel
import kotlinx.android.synthetic.main.fragment_add.*
class AddFragment : Fragment(), View.OnClickListener {
private lateinit var vm: AddViewModel
private val adapter = RecyclerViewMovieAdapter(arrayListOf())
private lateinit var binding: FragmentAddBinding
private lateinit var layoutManager: LinearLayoutManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
vm = activity?.run {
ViewModelProviders.of(this)[AddViewModel::class.java]
} ?: throw Exception("Invalid activity")
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding =
DataBindingUtil.inflate(inflater, R.layout.fragment_add, container, false)
binding.addViewModel = vm
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initUI()
}
private fun initUI() {
setRecyclerView()
observe()
setProgress(isRecyclerViewGone = false, isProgressLLViewGone = true)
binding.isClearIVGone = true
setListeners()
fragment_add_movieSeriesET.requestFocus()
val imm = context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(fragment_add_movieSeriesET, InputMethodManager.SHOW_IMPLICIT)
}
private fun setRecyclerView() {
layoutManager = LinearLayoutManager(context)
fragment_add_mainRV.layoutManager = layoutManager
fragment_add_mainRV.adapter = adapter
}
private fun observe() {
vm.movieList.observe(viewLifecycleOwner, Observer { movieList ->
movieList?.let {
adapter.updateMovieList(it)
}
})
vm.isError.observe(viewLifecycleOwner, Observer { isError ->
isError?.let {
setProgress(isRecyclerViewGone = false, isProgressLLViewGone = true)
if (it) {
setToast(resources.getString(R.string.something_went_wrong_please_try_again_later))
}
}
})
vm.isLoading.observe(viewLifecycleOwner, Observer { isLoading ->
isLoading?.let {
if (it) {
setProgress(isRecyclerViewGone = true, isProgressLLViewGone = false)
} else {
setProgress(isRecyclerViewGone = false, isProgressLLViewGone = true)
}
}
})
vm.movieSeriesETContent.observe(viewLifecycleOwner, Observer {
if (it.isNotEmpty()) {
vm.refreshData(it, 1)
binding.isClearIVGone = false
} else {
adapter.updateMovieList(arrayListOf())
binding.isClearIVGone = true
}
})
}
private fun setProgress(isRecyclerViewGone: Boolean, isProgressLLViewGone: Boolean) {
if (vm.movieSeriesETContent.value != null) {
val text =
"${resources.getString(R.string.searching_for)} \"${vm.movieSeriesETContent.value}\"..."
binding.searchingFor = text
}
binding.isMainRVGone = isRecyclerViewGone
binding.isProgressLLGone = isProgressLLViewGone
}
private fun setToast(text: String) {
Toast.makeText(context, text, Toast.LENGTH_SHORT).show()
}
private fun setListeners() {
fragment_add_clearIV.setOnClickListener(this)
}
override fun onClick(v: View?) {
if (v != null) {
when (v.id) {
R.id.fragment_add_clearIV -> fragment_add_movieSeriesET.text.clear()
}
}
}
}
AddViewModel.kt
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.martiandeveloper.muuvi.model.MovieResult
import com.martiandeveloper.muuvi.model.Movie
import com.martiandeveloper.muuvi.service.MovieService
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.observers.DisposableSingleObserver
import io.reactivex.schedulers.Schedulers
class AddViewModel : ViewModel() {
private val movieService = MovieService()
private val disposable = CompositeDisposable()
val movieList = MutableLiveData<ArrayList<Movie>>()
val isError = MutableLiveData<Boolean>()
val isLoading = MutableLiveData<Boolean>()
val movieSeriesETContent = MutableLiveData<String>()
fun refreshData(movie: String, page: Int) {
isLoading.value = true
disposable.add(
movieService.getData(movie, page).subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(object : DisposableSingleObserver<MovieResult>() {
override fun onSuccess(t: MovieResult) {
movieList.value = t.results
isError.value = false
isLoading.value = false
}
override fun onError(e: Throwable) {
isError.value = true
isLoading.value = false
}
})
)
}
}
I want to change the visibility of "Proceed to card" button,
to visible when the user clicks on add button and back to invisible when all the items got removed :
Screenshot
VISIBILITY is set to INVISIBLE in layout
I have added a count variable to compare
RestaurantMenuRecyclerAdapter.kt
package com.himanshu.hungerhunt.adapter
import com.himanshu.hungerhunt.R
import com.himanshu.hungerhunt.model.FoodMenu
import com.himanshu.hungerhunt.databse.FoodEntity
import com.himanshu.hungerhunt.activity.RestaurantMenuActivity
import android.widget.Toast
import android.widget.Button
import android.widget.TextView
import android.view.View
import android.view.LayoutInflater
import android.view.ViewGroup
import android.content.Context
import android.content.SharedPreferences
import androidx.recyclerview.widget.RecyclerView
class RestaurantMenuRecyclerAdapter(val context: Context, private val itemList: ArrayList<FoodMenu>) :
RecyclerView.Adapter<RestaurantMenuRecyclerAdapter.RestaurantMenuViewHolder>() {
var total: Int = 0
var count = 0
class RestaurantMenuViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val txtFoodId: TextView = view.findViewById(R.id.txtFoodId)
val txtFoodName: TextView = view.findViewById(R.id.txtFoodName)
val txtFoodPrice: TextView = view.findViewById(R.id.txtFoodPrice)
val btnAddFood: Button = view.findViewById(R.id.btnAddToCart)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RestaurantMenuViewHolder {
val view =
LayoutInflater.from(parent.context).inflate(R.layout.recycler_food_item, parent, false)
return RestaurantMenuViewHolder(view)
}
override fun getItemCount(): Int {
return itemList.size
}
override fun onBindViewHolder(holder: RestaurantMenuViewHolder, position: Int) {
val foodMenu = itemList[position]
val foodName = foodMenu.foodName
val foodId = foodMenu.foodId
val foodPrice = foodMenu.foodPrice
holder.txtFoodId.text = (position + 1).toString()
holder.txtFoodName.text = foodMenu.foodName
holder.txtFoodPrice.text = foodMenu.foodPrice
val foodEntity = FoodEntity(foodId, foodName, foodPrice)
holder.btnAddFood.setOnClickListener {
val sharedPreferences: SharedPreferences =
context.getSharedPreferences("Cart Preferences", Context.MODE_PRIVATE)
if (!RestaurantMenuActivity.DBAsyncTask(context, foodEntity, 1).execute().get()) {
val async = RestaurantMenuActivity.DBAsyncTask(context, foodEntity, 2).execute()
val result = async.get()
if (result) {
Toast.makeText(context, "${holder.txtFoodName.text} Added", Toast.LENGTH_SHORT)
.show()
holder.btnAddFood.setBackgroundResource(R.color.lightOrange)
holder.btnAddFood.text = "Remove"
total += foodMenu.foodPrice.toInt()
count += 1
sharedPreferences.edit().putInt("total", total).apply()
} else {
Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show()
}
} else {
val async = RestaurantMenuActivity.DBAsyncTask(context, foodEntity, 3).execute()
val result = async.get()
if (result) {
Toast.makeText(
context,
"${holder.txtFoodName.text} Removed",
Toast.LENGTH_SHORT
).show()
holder.btnAddFood.setBackgroundResource(R.color.materialRed)
holder.btnAddFood.text = "Add"
total -= foodMenu.foodPrice.toInt()
count -= 1
sharedPreferences.edit().putInt("total", total).apply()
} else {
Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show()
}
}
}
}
}
I have tried this
RestaurantMenuActivity().btnProceedToCart.findViewById<View>(R.id.btnProceedToCart).visibility = View.VISIBLE
But it is not working
you can use interface that will notify you in your activity when click on addFood button in your adapter.
First, make the interface in your adapter.
class RestaurantMenuRecyclerAdapter(val context: Context, private val itemList:
ArrayList<FoodMenu>) :
RecyclerView.Adapter<RestaurantMenuRecyclerAdapter.RestaurantMenuViewHolder>() {
interface RestaurantMenuListener {
fun onAddClick()
}
}
Secondly, pass the interface in your adapter from the activity along with the other parameters that you are passing.
class RestaurantMenuRecyclerAdapter(val context: Context, private val itemList:
ArrayList<FoodMenu>,val mCallBack : RestaurantMenuistener) :
RecyclerView.Adapter<RestaurantMenuRecyclerAdapter.RestaurantMenuViewHolder>() {
interface RestaurantMenuistener {
fun onAddClick()
}
}
And in your activity,
adapter = RestaurantMenuRecyclerAdapter(context,itemlist, Object:
RestaurantMenuRecyclerAdapter.RestaurantMenuistener{
override fun onAddClick(){
//Do your stuff here like hide or show.
}
})
Finally, in your adapter when you click on add button,
holder.btnAddFood.setOnClickListener {
mCallback.onAddClick()
}