Clickable Cardview to open another activity - android

MyAdapter.kt
im a beginner in this and how to open another activity when i click the cardview..previously it worked fine,but when i click the card nothing happens and only toast show up
I want the user to be able to click on a card and go to a different activity. If you click on card 1 you must go to the activity1. If you click on card 2 you must go to the activity2. Etc...
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.Toast
import androidx.cardview.widget.CardView
import androidx.viewpager.widget.PagerAdapter
import kotlinx.android.synthetic.main.card_item.view.*
class MyAdapter(private val context: Context, private val myModelArrayList: ArrayList<MyModel>) : PagerAdapter(){
override fun getCount(): Int {
return myModelArrayList.size //return list of records/items
}
override fun isViewFromObject(view: View, `object`: Any): Boolean {
return view == `object`
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
//inflate layout card_item.xml
val view = LayoutInflater.from(context).inflate(R.layout.card_item, container, false)
//get data
val model = myModelArrayList.get(position)
val title = model.title
val description = model.description
val date = model.date
val image = model.image
//set data to ui views
view.bannerIv.setImageResource(image)
view.titleTv.text = title
view.descriptionTv.text = description
view.dateTv.text = date
view.setOnClickListener {
val intent = Intent(context, SecondActivity::class.java)
context.startActivity(intent)
// finish();
}
//handle item/card click
view.setOnClickListener{
Toast.makeText(context,"$title \n $description \n $date", Toast.LENGTH_SHORT).show()
}
//add view to container
container.addView(view, position)
return view
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
container.removeView(`object` as View)
}
}
```

just simply remove your second view.setOnClickListener and move your toast to first view.setOnClickListener. As others mentioned second listener will be overridden.

Related

how to make a phone call from android adapter recyclerview using kotlin

I'm new to Kotlin and am trying to make phone call from a recycler view that has the button for the phone number, I want when i click on the button it should open up my phone dialer with the number automatically however when i click on the button, nothing happens.
here is what i've done:
I gave the permission for making a call in the manifest file
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<application
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
my recyclerview has the image, name, contact, the expertise and the button for calling the contact
here is my code snippet for the adapter that is supposed to carry out the activity. Im not sure, but maybe there could be a problem with my method.
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat.startActivity
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
class ConsultantAdapter(private val modelList: List<ConsultantModel>) :
RecyclerView.Adapter<ConsultantAdapter.ViewHolder>() {
private lateinit var callBtnListener: View.OnClickListener
classConsultantAdapter(valmodelList:List<ConsultantModel>,callBtnListener:View.OnClickListener) {}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val cImage: ImageView = itemView.findViewById(R.id.profile_image)
private val cName: TextView = itemView.findViewById(R.id.consultant_name)
private val cContact: TextView = itemView.findViewById(R.id.consultant_contact)
private val cExpertise: TextView = itemView.findViewById(R.id.consultant_expertise)
val callBtn: ImageView = itemView.findViewById(R.id.call_consultant_button)
fun setEvents(resource: String, name: String, contact: String, expertise: String) {
Glide.with(itemView.context).load(resource).into(cImage)
cName.text = name
cContact.text = contact
cExpertise.text = expertise
itemView.setOnClickListener{
val intent: Intent = Uri.parse(contact).let { number ->
Intent(Intent.ACTION_DIAL, number)
}
itemView.context.startActivity(intent)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val galleryView =
LayoutInflater.from(parent.context).inflate(R.layout.consultants_item, parent, false)
return ViewHolder(galleryView)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val resource = modelList[position].image
val name = modelList[position].name
val contact = modelList[position].contact
val expertise = modelList[position].expertise
holder.setEvents(resource, name, contact, expertise)
}
override fun getItemCount(): Int {
return modelList.size
}
}
Just add
setOnClickListener
to either your callBtn, or make a reference to your parent view like Relative Layout or whatever you have used to wrap all children views.
The ItemView here, is perhaps a root view for the layout, row or cell and you can bind it to any view using
as

Implicit Intent is not working due to context issue

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 :"))

Unresolved reference for applicationContext recycleview element (kotlin app for android)

I'm developing an android app in kotlin, and I want to have a button in every recyclerView element, which will launch an intent - the same in whole recycle view, but with different parameters(for now it's just position for testing, in final form that will be some value from database).
I write the following code for that(inside my adapter class):
override fun onBindViewHolder(holder: ProjectViewHolder, position: Int) {
val Edit: Button = holder.view.EditButton
Edit.setOnClickListener()
{
var projekt: Intent = Intent(applicationContext, Project::class.java)
projekt.putExtra("id", position)
startActivity(projekt)
}
But I get "unresolved refference" error for applicationContext. I used buttons with intent like that before and that worked perfectly fine, though this is the first time I'm trying to do it inside recyclerView element.
How to make it work? Maybe I just take the wrong approach and it should be done in different way?
Edit: Complete adapter class file:
package com.example.legoapp127260
import android.content.Intent
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 kotlinx.android.synthetic.main.project_item_layout.view.*
class ProjectAdapter : RecyclerView.Adapter<ProjectViewHolder>()
{
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ProjectViewHolder {
val layoutInflater = LayoutInflater.from(viewGroup.context)
val projectRow = layoutInflater.inflate(R.layout.project_item_layout, viewGroup, false)
return ProjectViewHolder(projectRow)
}
override fun getItemCount(): Int {
return 2;
}
override fun onBindViewHolder(holder: ProjectViewHolder, position: Int) {
val projectName: TextView = holder.view.projectName
val projectNames: Array<String> = arrayOf("Set 1", "Set 2")
val Edit: Button = holder.view.EditButton
projectName.setText(projectNames[position])
Edit.setOnClickListener()
{
var projekt: Intent = Intent(Edit.context, Project::class.java)
projekt.putExtra("id", position)
Edit.context.startActivity(projekt)
}
}
}
class ProjectViewHolder(val view: View) : RecyclerView.ViewHolder(view)
{
}
You can get context from your button:
var projekt: Intent = Intent(Edit.context, Project::class.java)
projekt.putExtra("id", position)
Edit.context.startActivity(projekt)

Wrongly run onBindViewHolder in Recyclerview - Kotlin

I'am trying to handle my recyclerview put there is a problem
when i scroll down (onBindView function) works fine
but when scroll back to the first items in recyclerview everything becomes wrong like the following images.
package com.leaderspro.mrlawyer.adapters
import android.graphics.Paint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.leaderspro.mrlawyer.R
import com.leaderspro.mrlawyer.models.TODOModel
import kotlinx.android.synthetic.main.todo_list.view.*
class TODOAdapter(private val mArray: ArrayList<TODOModel>) :
RecyclerView.Adapter<TODOAdapter.ViewHolder>() {
var mView: View? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
mView = LayoutInflater.from(parent.context).inflate(R.layout.todo_list, parent, false)
return ViewHolder(mView!!)
}
override fun getItemCount(): Int {
return mArray.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val mTODO = mArray[position]
if (mTODO.isDone == 0) {//not complete
holder.ivIsDone.setImageResource(R.drawable.ic_checkbox_unchecked)
} else if (mTODO.isDone == 1) {
holder.ivIsDone.setImageResource(R.drawable.ic_checkbox_checked)
holder.tvTodoTask.paintFlags =
holder.tvTodoTask.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG //put line on done Tasks
}
holder.tvTodoTask.text = mTODO.task
holder.tvTODODate.text = mTODO.date
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val tvTodoTask = itemView.tvTodoTask!!
val tvTODODate = itemView.tvTODODate!!
val ivIsDone = itemView.ivIsDone!!
val todoListMainLinear = itemView.todoListMainLinear!!
}
}
works fine
https://i.stack.imgur.com/6mBUJ.png
works fine
https://i.stack.imgur.com/qcpLK.png
Wrongly called onBindView when Scroll Back
https://i.stack.imgur.com/2sRsu.png
use holder.adapterposition instead of position
val mTODO = mArray[holder.adapterposition]
for more info check: https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.Adapter.html?hl=en#onBindViewHolder(VH,%20int)
edit:
as #Pawel has pointed out, the flags should be cleared when mTodo.isDone == 0.
that should get the job done

Select just one ImageView at a time inside RecyclerView Adapter

I have a RecyclerView filled with different images, when the user click one of then i apply a border to highlight the image. Everything is working fine, however, the user can click multiple images and all of then get highlighted, i want to select only one at a time. I have search over multiples sites and posts however none of them have a solution that works for me. Here is an image:
I am using a ImageView click listener, not an ItemClickListener.
Here is the adapter code:
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
class AccountViewHolder(view: View) : RecyclerView.ViewHolder(view) {
var accountImage: ImageView =
view.findViewById(R.id.account_image_placeholder)
}
class AddEditAccountAdapter(private var context: Context, private var
accountImages: ArrayList<String>) :
RecyclerView.Adapter<AccountViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):
AccountViewHolder {
val imageItem = LayoutInflater.from(context).inflate(
R.layout.account_image_item,
parent, false
)
return AccountViewHolder(imageItem)
}
override fun getItemCount(): Int {
return accountImages.size
}
override fun onBindViewHolder(holder: AccountViewHolder, position: Int) {
val accountImageId =
context.getResources().getIdentifier(accountImages.get(position), "drawable", context.getPackageName())
holder.accountImage.setImageResource(accountImageId)
holder.accountImage.setOnClickListener {
holder.accountImage.setBackgroundResource(R.drawable.image_highlight)
}
}
}
you should have a global field to hold your selected position like below:
var selectedPos = -1 // hold selected position in your adapter
// in your bindView, because your view will be reused, you should always check the selected position to set the suitable background
holder.accountImage.setBackgroundResource(if(selectedPos == position) yourImageHightlight else yourNormalImage)
holder.accountImage.setOnClickListener {
selectedPos = position
notifyDataSetChanged()// or something like notifyItemChanged()...
}

Categories

Resources