I have a problem because I am trying to add an onReceiptsAdd () function to onStart () but I don't know how to make it work. how to add onReceiptsAdd () to onStart ()
here is my code:
class ScanFragment : Fragment(), OnReceiptsItemAdd {
private var _binding: FragmentScanBinding? = null
private val binding get() = _binding!!
private val scanVm by viewModels<ScanViewModel>()
private val adapter = ReceiptsAdapter(this)
private val SCAN_DEBUG = "SCAN_DEBUG"
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
_binding = FragmentScanBinding.inflate(inflater, container, false)
// Inflate the layout for this fragment
return binding.root
}
override fun onStart() {
super.onStart()
val value = binding.etBlank.text?.trim().toString()
val from = binding.etBlank.text?.trim().toString()
val image = binding.etBlank.text?.trim().toString()
val rootRef = FirebaseFirestore.getInstance()
val usersRef = rootRef.collection("receipts")
val auth = FirebaseAuth.getInstance()
auth.currentUser?.apply {
usersRef.document(uid).set(mapOf(
"id" to uid,
"from" to from,
"value" to value,
"image" to image,
)).addOnCompleteListener { task ->
if (task.isSuccessful) {
Log.d("TAG", "User successfully added.")
} else {
Log.d("TAG", task.exception!!.message!!)
}
}
}
}
override fun onReceiptsAdd(receipts: dataReceipts, position: Int) {
scanVm.addFavReceipt(receipts)
}
}
Related
Fragment1 exists in MainActivity and Fragment2 exists in Fragment1.
Fragment2 contains a recycler view, and inside the recycler view there are items with a move button. When I click the go button, I want to switch to a screen other than the RcyclerView with the items currently displayed in Fragment2.
adpater
class Quality_Material_Certification(
val material_name : String,
val use_type : String,
val standard : String,
val material_num : String
)
class QualityMaterialCertificationAdapter(private val dataset:
List<Quality_Material_Certification>) :RecyclerView.Adapter<QualityMaterialCertificationAdapter.QualityMaterialCertificationViewHolder>() {
class QualityMaterialCertificationViewHolder(val binding:
ItemQualityMaterialCertificationBinding) :
RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int):
QualityMaterialCertificationViewHolder {
val view =LayoutInflater.from(viewGroup.context).inflate(R.layout.item_quality_material_certification, viewGroup, false)
return QualityMaterialCertificationViewHolder(ItemQualityMaterialCertificationBinding.bind(view))
}
override fun onBindViewHolder(viewHolder: QualityMaterialCertificationViewHolder, position: Int) {
val listposition = dataset[position]
viewHolder.binding.materialName.text= listposition.material_name
viewHolder.binding.useType.text = listposition.use_type
viewHolder.binding.standard.text = listposition.standard
viewHolder.binding.goToMoreBtn.setOnClickListener {
setDataAtFragment(Fragment2(), listposition.material_num)
}
}
override fun getItemCount() = dataset.size
private fun setDataAtFragment(fragment: Fragment, material : String)
{
val bundle = Bundle()
val transaction = binding.root.supportFragmentManager?.beginTransaction()
bundle.putString("material", material)
fragment.arguments = bundle
transaction?.replace(R.id.appro_fl, fragment)?.commit()
}
}
fragment1
private var token : String? = null
private var const_code : String? = null
private var list = arrayListOf<Quality_Material_Certification>()
class Fragment1 : Fragment() {
private lateinit var binding:
FragmentQualityManagementFirefightingMaterialsCertificationBinding
var material: GetApproMaterListDTO? = null
lateinit var data: Quality_Material_Certification
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = FragmentQualityManagementFirefightingMaterialsCertificationBinding.inflate(layoutInflater)
binding.materialRecycler.layoutManager = LinearLayoutManager(context)
binding.materialRecycler.adapter = QualityMaterialCertificationAdapter(list)
arguments?.let {
token = it.getString("token").toString()
const_code = it.getString("cons_code").toString()
}
val dto = RequestDTO( "0", "9")
retrofit.requestservice(sysCd, token.toString(), dto).enqueue(object :
Callback<GetApproMaterListDTO> {
override fun onFailure(call: Call<GetApproMaterListDTO>, t: Throwable) { Log.d("retrofit", t.toString()) }
#SuppressLint("NotifyDataSetChanged")
override fun onResponse(call: Call<GetApproMaterListDTO>, response: Response<GetApproMaterListDTO>) {
material = response.body()
list.clear()
for (i in 0 until material?.value?.list!!.size) {
val material_name = material?.value?.list?.get(i)?.material_name.toString()
val use_type = material?.value?.list?.get(i)?.use_type.toString()
val standard = material?.value?.list?.get(i)?.standard.toString()
val material_num = material?.value?.list?.get(i)?.material_num.toString()
data = Quality_Material_Certification(material_name, use_type, standard ,material_num )
list.add(data)
}
binding.materialRecycler.adapter?.notifyDataSetChanged()
}
})
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return binding.root
}
companion object {
#JvmStatic
fun newInstance(param1: String, param2: String) =
Fragment1().apply {
arguments = Bundle().apply {
}
}
}
}
modified comment opinion
apdapter
interface clicktoDetail{
fun onClickDetail(model : CertificationDTO)
}
class CertificationAdapter(
private val context: Context,
private val dataset: List<CertificationDTO>,
private val clickListener: clicktoDetail)
: RecyclerView.Adapter<QualityMaterialCertificationAdapter.ChangeHolder>() {
inner class ChangeHolder(val binding: ItemCertificationBinding) : RecyclerView.ViewHolder(binding.root){
//val btn :Button = button.findViewById(R.id.go_to_more_btn)
init{
binding.goToMoreBtn.setOnClickListener { clickListener.onClickDetail(dataset[position]) }
}
}
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ChangeHolder {
val view = LayoutInflater.from(viewGroup.context).inflate(R.layout.item_certification, viewGroup, false)
return ChangeHolder(ItemCertificationBinding.bind(view))
}
override fun onBindViewHolder(viewHolder: ChangeHolder, position: Int) {
val listposition = dataset[position]
viewHolder.binding.materialName.text= listposition.material_name
viewHolder.binding.useType.text = listposition.use_type
viewHolder.binding.standard.text = listposition.standard
viewHolder.binding.madeCompanyName.text = listposition.produce_co
/* viewHolder.binding.goToMoreBtn.setOnClickListener {
val intent = Intent(context, Fragment1::class.java)
intent.putExtra("cons_code", listposition.project_const)
intent.run{
context.startActivity(this)
(context as Activity).finish()
}
}*/
}
override fun getItemCount() = dataset.size
}
Fragment
private var token : String? = null
private var const_code : String? = null
private var material_list = arrayListOf<Quality_Material_CertificationDTO>()
class Certification_Fragment : Fragment() {
private lateinit var binding: FragmentQualityManagementFirefightingMaterialsCertificationBinding
var material: GetListDTO? = null
lateinit var material_data : Quality_Material_CertificationDTO
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = FragmentCertificationBinding.inflate(layoutInflater)
val retrofitApproMaterList = RetrofitC("http://")
val GetApproMaterListService: GetApproMaterListService = retrofitApproMaterList.create(GetListService::class.java)
binding.materialRecycler.layoutManager = LinearLayoutManager(context)
binding.materialRecycler.adapter = CertificationAdapter(requireContext(), material_list, GotoDetail())
arguments?.let {
token = it.getString("token").toString()
const_code = it.getString("cons_code").toString()
}
val mdto = RequestDTO("", "")
GetApproMaterListService.requestappromaterial(sysCd, token, mdto).enqueue(object :
Callback<GetListDTO> {
override fun onFailure(call: Call<GetListDTO>, t: Throwable) { Log.d("retrofit", t.toString()) }
#SuppressLint("NotifyDataSetChanged")
override fun onResponse(call: Call<GetAListDTO>, response: Response<GetListDTO>) {
material = response.body()
material_list.clear()
for (i in 0 until material?.value?.list!!.size) {
val material_name = material?.value?.list?.get(i)?.material_name.toString()
val use_type = material?.value?.list?.get(i)?.use_type.toString()
val standard = material?.value?.list?.get(i)?.standard.toString()
val produce_co = material?.value?.list?.get(i)?.produce_co.toString()
val material_num = material?.value?.list?.get(i)?.material_num.toString()
material_data = Quality_Material_CertificationDTO(material_name, use_type, standard, produce_co ,material_num)
material_list.add(material_data)
CertificationAdapter(requireContext(), material_list, GotoDetail())
}
binding.materialRecycler.adapter?.notifyDataSetChanged()
}
})
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return binding.root
}
companion object {
#JvmStatic
fun newInstance(param1: String, param2: String) =
Quality_Management_Firefighting_Materials_Certification_Fragment().apply {
arguments = Bundle().apply {
}
}
}
class GotoDetail : Fragment(), clicktoDetail{
override fun onClickDetail(model: Quality_Material_CertificationDTO) {
val bundle = Bundle()
val transaction = activity?.supportFragmentManager?.beginTransaction()
bundle.putString("cons_code", const_code)
bundle.putString("token", token)
Fragment().arguments = bundle
transaction?.replace(R.id.appro_fl, Certification_More_Fragment())!!.commit()
}
}
}
You are trying to access activities and fragments inside your adapter class which is incorrect. Never do that! Instead, create an item click listener and create a reference to it in your activity. This way you can handle item click in your activity and perform fragment transactions.
Here, You can take help on how to do so by making an onClickInterface
In my fragment named FragmentFavs, I get the data from Firebase and show it in the RecyclerView.
This is my model data class
data class NewsDBModel(
val key : String? ="",
val author : String? = "",
var title : String? = "",
val description : String? = "",
val url : String? = "",
val urlToImage : String? = "",
val publishedAt : String? = ""
)
This is my FragmentFavs
class FragmentFavs : Fragment() {
private lateinit var bind : FragmentFavsBinding
private lateinit var arrNews : ArrayList<NewsDBModel>
private lateinit var ref : DatabaseReference
private lateinit var auth: FirebaseAuth
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
bind = FragmentFavsBinding.inflate(inflater, container, false)
return bind.root
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
bind.rvFavs.setHasFixedSize(true)
bind.rvFavs.layoutManager = LinearLayoutManager(context)
arrNews = arrayListOf<NewsDBModel>()
getFavorites()
}
private fun getFavorites() {
auth = Firebase.auth
val currentUser = auth.currentUser
if(currentUser!=null){
val uid = currentUser.uid
ref = FirebaseDatabase.getInstance().getReference("favorites").child(uid)
ref.addValueEventListener(object : ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
if(snapshot.exists()){
for(favSnapshot in snapshot.children){
val news = favSnapshot.getValue(NewsDBModel::class.java)
arrNews.add(news!!)
}
bind.rvFavs.adapter = FavoritesAdapter(context!!,arrNews)
}
}
override fun onCancelled(error: DatabaseError) {
}
})
}else{
val intent = Intent(context,Login::class.java)
startActivity(intent)
}
}
}
Then when I want to delete the item in the cardview, I successfully delete it from the database, but the RecyclerView is not updated.
Also, when I delete an item, that item is deleted, but other items are copied and displayed. I can't understand why.
When the deletion is done, I delete the item from the arraylist and run the notifyItemRemoved() method, but it doesn't work. What should I do?
This is my RecyclerView adapter
class FavoritesAdapter(val context : Context, var arrNews : ArrayList<NewsDBModel>): RecyclerView.Adapter<FavoritesAdapter.ModelViewHolder>() {
val database = Firebase.database
private lateinit var auth: FirebaseAuth
val myRef = database.getReference("favorites")
class ModelViewHolder(val bind: FavoritesRowBinding): RecyclerView.ViewHolder(bind.root){}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ModelViewHolder {
val bind = FavoritesRowBinding.inflate(LayoutInflater.from(parent.context),parent,false)
return ModelViewHolder(bind)
}
override fun onBindViewHolder(holder: ModelViewHolder, position: Int) {
holder.bind.txtFavoritesDate.text = arrNews.get(position).publishedAt.toString().trim()
holder.bind.txtFavoritesAuthor.text = arrNews.get(position).author.toString().trim()
holder.bind.txtFavoritesTitle.text = arrNews.get(position).title.toString().trim()
holder.bind.cardViewFav.setOnClickListener {
auth = Firebase.auth
val currentUser = auth.currentUser
val uid = currentUser!!.uid
myRef.child(uid).child(arrNews.get(position).key!!).removeValue()
arrNews.removeAt(position)
notifyItemRemoved(position)
}
}
override fun getItemCount(): Int {
return arrNews.size
}
}
The error in "adapter = UserAdapter(users)" says type mismatch required: context "Change parameter Context type of primary constructor of class UserAdapter to ArrayList" I tried running it while the "adapter = UserAdapter(users)" is enclosed as a comment (like so //adapter = UserAdapter(users)) in shows an error in logcat saying "java.lang.NullPointerException: v.findViewById(R.id.RVusermain) must not be null
at com.example.chattrialskot.fragments.Year1.onCreateView(Year1.kt:49) ".
USERS.kt
class Users {
var userstuID: String? = null;
var username: String? = null;
var useremail: String? = null;
var useraccstat: String? = null;
var useruid: String? = null;
var useryear: String? = null;
constructor(){}
constructor(userstuID: String?, username: String?, useremail: String?, useraccstat: String?,
useruid: String?, useryear: String?){
this.userstuID = userstuID
this.username = username
this.useremail = useremail
this.useraccstat = useraccstat
this.useruid = useruid
this.useryear = useryear
} }
USER ADAPTER
class UserAdapter(var UAContext: Context, var userlist: ArrayList<Users>):
RecyclerView.Adapter<UserAdapter.UsersViewHolder> (){
fun UserAdapter(userlist: ArrayList<Users>, mContext: Context){
this.userlist = userlist
this.UAContext = mContext
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UsersViewHolder {
val view:View = LayoutInflater.from(UAContext).inflate(
R.layout.userlayout, parent,
false)
return UserAdapter.UsersViewHolder(view)
}
FRAGMENT
class Year1 : Fragment() {
companion object {
fun newInstance(): Year1 {
return Year1()
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val v = inflater.inflate(R.layout.fragment_year1, container, false)
userrecyclerviewer = v.findViewById<RecyclerView>(R.id.RVyear1)
userrecyclerviewer.setHasFixedSize(true)
userrecyclerviewer.layoutManager = LinearLayoutManager(context)
userrecyclerviewer.adapter = adapter
users = ArrayList()
adapter = UserAdapter(users)
getUsers()
return v
}
private fun getUsers(){
FireAuth = FirebaseAuth.getInstance()
FireDB = FirebaseDatabase.getInstance().getReference()
FireDB.child("users").addValueEventListener(object: ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
users.clear()
for(postSnapshot in snapshot.children){
val userfrmDB = postSnapshot.getValue(Users::class.java)
if(FireAuth.currentUser?.uid != userfrmDB?.useruid
&& userfrmDB?.useraccstat != "Banned")
{
users.add(userfrmDB!!)
}
}
adapter.notifyDataSetChanged()
}
override fun onCancelled(error: DatabaseError) {
}
})
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}}
class Year1 : Fragment() {
companion object {
fun newInstance(): Year1 {
return Year1()
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val v = inflater.inflate(R.layout.fragment_year1, container, false)
userrecyclerviewer = v.findViewById<RecyclerView>(R.id.RVusermain)
userrecyclerviewer.setHasFixedSize(true)
getUsers()
users = ArrayList()
userrecyclerviewer.layoutManager = LinearLayoutManager(context)
adapter = UserAdapter(context?, users)
userrecyclerviewer.adapter = adapter
return v
}
private fun getUsers(){
FireAuth = FirebaseAuth.getInstance()
FireDB = FirebaseDatabase.getInstance().getReference()
FireDB.child("users").addValueEventListener(object: ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
users.clear()
for(postSnapshot in snapshot.children){
val userfrmDB = postSnapshot.getValue(Users::class.java)
if(FireAuth.currentUser?.uid != userfrmDB?.useruid
&& userfrmDB?.useraccstat != "Banned")
{
users.add(userfrmDB!!)
}
}
adapter.notifyDataSetChanged()
}
override fun onCancelled(error: DatabaseError) {
}
})
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}}
You were getting Nullpointer exception because you were setting adapter even it has been initialized. Please, follow the code above.
call getUsers() this method in main thread before you pass the list to adapter because you list should not be null. Then pass the context and list to adapter like this
users = ArrayList()
getUsers()
adapter = UserAdapter(requireContext(),users)
class FeedRecyclerAdapter (private val postList : ArrayList<Post>) : RecyclerView.Adapter<FeedRecyclerAdapter.PostHolder>() {
class PostHolder(val binding: FragmentDataBinding) : RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PostHolder {
val binding = FragmentDataBinding.inflate(LayoutInflater.from(parent.context),parent,false)
return PostHolder(binding)
}
override fun onBindViewHolder(holder: PostHolder, position: Int) {
holder.binding.verimText.text = postList.get(position).lsi
}
override fun getItemCount(): Int {
return postList.size
}
Here is the code written for recyclerView.
private lateinit var firestore: FirebaseFirestore
private lateinit var auth: FirebaseAuth
private var _binding: FragmentDataBinding? = null
private val binding get() = _binding!!
private lateinit var postArrayList : ArrayList<Post>
private lateinit var feedAdapter : FeedRecyclerAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
auth = Firebase.auth
firestore = Firebase.firestore
postArrayList = ArrayList<Post>()
feedAdapter = FeedRecyclerAdapter(postArrayList)
getData()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentDataBinding.inflate(inflater, container, false)
val view = binding.root
return view
}
private fun getData(){
firestore.collection("Posts").addSnapshotListener { value, error ->
if (error!=null){
Toast.makeText(requireContext(),error.localizedMessage,Toast.LENGTH_SHORT).show()
}else{
if (value !=null){
if (!value.isEmpty){
val documents = value.documents
for (document in documents){
val araziBoyutu = document.get("Arazi Boyutu") as String
val araziEgimi = document.get("Arazi Eğimi") as String
val panelBoyutu = document.get("Panel Boyutu") as String
val panelSayisi = document.get("Panel Sayisi") as String
val sehir = document.get("Şehir") as String
val post = Post(panelSayisi,panelBoyutu,araziEgimi,araziBoyutu,sehir)
postArrayList.add(post)
recyclerView.adapter = FeedRecyclerAdapter(postArrayList)
}
feedAdapter.notifyDataSetChanged()
}
}
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.recyclerView.adapter = feedAdapter
recyclerView.layoutManager = LinearLayoutManager(activity)
The code here is the part where I define the RecylcerView and save the information.
I can pull the data, I can see it on firebase, when I print it with println, I can read it in the console, I can go to the page where the text should be written, but I can't see this data in the verimText TextView I'm trying to print.
Try to call notifyDataSetChanged() or notifyItemRangeInserted() after adding post.
Recyclerview should be declared inside onViewCreated Method
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val recyclerView = view.findViewById(R.id.recyclerView) as RecyclerView
recyclerView.layoutManager = LinearLayoutManager(activity)
recyclerView.adapter = FeedRecyclerAdapter(postArrayList)
}
move this line
recyclerView.adapter = FeedRecyclerAdapter(postArrayList)
to
val post = Post(panelSayisi,panelBoyutu,araziEgimi,araziBoyutu,sehir)
postArrayList.add(post)
recyclerView.adapter = FeedRecyclerAdapter(postArrayList)//move to here
I'm still trying to wrap my head around working with viewmodels and a bit confused now that I also have a dialog and recyclerview items but will try to be as clear as I can here if I can get any help please.
I have a dialog with items that when one of them is selected and closed should return data to my calling fragment so the selected item is displayed under that view.
However, once the item is selected and the dialog dismissed, I don't see the new selected item as the one showing on the UI but still the old item instead. (When the fragment is first started it displays the item that is set as selected on my list. The selected value is hardcoded at first but updated when the item is clicked and I can see the update has taken place when I debug the viewmodel observer inside the onDismiss method for the dialog).
I'm a couple of hours on this and have tried a few different things such as calling the viewmodel inside onResume or onDismiss and changing the viewmodel to be initiated by by activityViewModels() as per this post but none of these have worked so far and I think I'm stuck at the moment. Below my most recent version of the code.
class CovidCheckInFragment : Fragment(R.layout.fragment_covid_check_in) {
var navController: NavController? = null
private val model: MainViewModel by activityViewModels()
#RequiresApi(Build.VERSION_CODES.M)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
navController = Navigation.findNavController(view)
model.userMutableLiveData.observe(viewLifecycleOwner, Observer<Any?> { list ->
if (list != null)
(list as Iterable<*>).map {
if ((it as ModelDialogOption).selected == true) {
tvHeader.text = it.title
}
}
})
}
}
..
class MyDialogFragment : DialogFragment(), RecyclerDialogOptionsItem.AdapterListener {
private val viewModel: MainViewModel by activityViewModels()
private lateinit var adapter: GroupAdapter<GroupieViewHolder>
var selectedPosition = -1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, R.style.AppTheme_Dialog_Custom)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_dialog, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
rvOptions.layoutManager = LinearLayoutManager(activity)
adapter = GroupAdapter()
rvOptions.adapter = adapter
ivClose.setOnClickListener {
this.dismiss()
}
initViewModel()
}
private fun initViewModel() {
viewModel.userMutableLiveData.observe(this, Observer { list ->
for (i in list!!) {
adapter.add(
RecyclerDialogOptionsItem(
this#MyDialogFragment,
i,
this#MyDialogFragment
)
)
}
})
}
override fun onClickItem(position: Int) {
selectedPosition = position
adapter.notifyDataSetChanged()
Log.i("clicked", "position: $position")
}
}
..
class MainViewModel : ViewModel() {
private var list: ArrayList<ModelDialogOption>? = null
val userMutableLiveData: MutableLiveData<ArrayList<ModelDialogOption>?> = MutableLiveData()
init {
populateList()
userMutableLiveData.value = list!!
}
private fun populateList() {
list = ArrayList()
list!!.add(ModelDialogOption("Prefer not to say", false))
list!!.add(ModelDialogOption("16-39", false))
list!!.add(ModelDialogOption("40-59", true))
list!!.add(ModelDialogOption("60+", false))
}
}
..
class RecyclerDialogOptionsItem(
private val fragment: MyDialogFragment,
private val modelDialogOption: ModelDialogOption,
private val adapterListener: AdapterListener
) : Item<GroupieViewHolder>() {
companion object {
var clickListener: AdapterListener? = null
}
override fun bind(viewHolder: GroupieViewHolder, position: Int) {
viewHolder.apply {
with(viewHolder.itemView) {
tvTitle.text = modelDialogOption.title
clickListener = adapterListener
if (fragment.selectedPosition == position) {
ivChecked.visible()
modelDialogOption.selected = true
} else {
ivChecked.invisible()
modelDialogOption.selected = false
}
itemView.setOnClickListener {
clickListener?.onClickItem(adapterPosition)
}
}
}
}
override fun getLayout() = R.layout.rv_options_item_row
interface AdapterListener {
fun onClickItem(position: Int)
}
}
Thank you very much.
Your main view model should be like this
class MainViewModel : ViewModel() {
private var list: ArrayList<ModelDialogOption>? = null
val userMutableLiveData = MutableLiveData<ArrayList<ModelDialogOption>>()
init {
populateList()
userMutableLiveData.value = list!!
}
private fun populateList() {
list = ArrayList()
list!!.add(ModelDialogOption("Prefer not to say", false))
list!!.add(ModelDialogOption("16-39", false))
list!!.add(ModelDialogOption("40-59", true))
list!!.add(ModelDialogOption("60+", false))
}
fun updateItem(position:Int){
val itemToUpdate = list!!.get(position)
itemToUpdate.selected = !itemToUpdate.selected!!
list!![position] = itemToUpdate
}
fun flushItems(){
userMutableLiveData.value = list!!
}
}
Then from MyDialogFragment Should be like this.
class MyDialogFragment : DialogFragment(), RecyclerDialogOptionsItem.AdapterListener {
private val viewModel: MainViewModel by activityViewModels()
private lateinit var adapter: GroupAdapter<GroupieViewHolder>
var selectedPosition = -1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, R.style.AppTheme_Dialog_Custom)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_dialog, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
rvOptions.layoutManager = LinearLayoutManager(activity)
adapter = GroupAdapter()
rvOptions.adapter = adapter
ivClose.setOnClickListener {
this.dismiss()
}
initViewModel()
}
override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
viewModel.flushItems()
}
private fun initViewModel() {
viewModel.userMutableLiveData.observe(this, Observer { list ->
for (i in list!!) {
adapter.add(
RecyclerDialogOptionsItem(
this#MyDialogFragment,
i,
this#MyDialogFragment
)
)
}
})
}
override fun onClickItem(position: Int) {
selectedPosition = position
adapter.notifyDataSetChanged()
viewModel.updateItem(position)
Log.i("clicked", "position: $position")
}
}