Kotlin RecyclerView - Update item to DB - android-studio

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

Related

KOTLIN - expandableListView.setOnChildClickListener not working

As my tilte, i have a expandable listview, but setOnChildClick event do not working, setOnGroupExpandListener setOnGroupClickListener being active. help me pls. thanks all !!!!
This is my code, fragment and adapter.
Fragment:
class DiscoverFilterFragment:Fragment() {
private lateinit var binding: FragmentFilterDiscoverBinding
private lateinit var filterAdapter : ExpandableListAdapter
private lateinit var titleList : List<String>
private lateinit var itemsList : HashMap<String, List<String>>
private val viewModel: DiscoverViewModel by activityViewModels()
var searchText : String = ""
var authorText : String = ""
var dateIssueText : String = ""
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
binding = FragmentFilterDiscoverBinding.inflate(inflater, container, false)
getDataFromApi(searchText, authorText + ",equals", dateIssueText + ",equals")
onItemsClickEvent()
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
private fun getDataFromApi(searchText : String, authorText : String, dateIssueText : String) {
titleList = ArrayList()
itemsList = HashMap()
viewModel.discoverFilter(searchText, authorText, dateIssueText)
viewModel.getFilterObserverableItem().observe(viewLifecycleOwner){
it?.let { it ->
titleList = it.keys.toList()
//Log.d("Title List","${titleList}")
itemsList = it
//Log.d("Title List","${itemsList}")
filterAdapter = DiscoverFilterAdapter(requireContext(), titleList, itemsList)
binding.expFilter.setAdapter(filterAdapter)
(filterAdapter as DiscoverFilterAdapter).notifyDataSetChanged()
}
}
}
private fun onItemsClickEvent() {
val expandableListView = binding.expFilter
expandableListView.setOnGroupExpandListener {
Toast.makeText(
activity,
"Open"
,Toast.LENGTH_SHORT).show()
}
expandableListView.setOnChildClickListener {
parent, v, groupPosition, childPosition, id ->
Toast.makeText(activity, "Clicked: ", Toast.LENGTH_SHORT).show()
false
}
// expandableListView.setOnChildClickListener { parent, v, groupPosition, childPosition, id ->
// Log.d("Items Clicked","")
// Toast.makeText(
// activity,
// titleList[groupPosition]
// + " : "
// + itemsList[titleList[groupPosition]]!![childPosition],
// Toast.LENGTH_SHORT).show()
// false
// }
}
}
My Adapter
class DiscoverFilterAdapter internal constructor(
private val context: Context,
private val titleList: List<String>,
private val itemsList: HashMap<String, List<String>>) : BaseExpandableListAdapter() {
private var authorTextLive : MutableLiveData<String> = MutableLiveData()
fun getAuthorTextObserverable() : MutableLiveData<String> {
return authorTextLive
}
override fun getGroupCount(): Int {
return titleList.size
}
override fun getChildrenCount(groupPosition: Int): Int {
return this.itemsList[this.titleList[groupPosition]]!!.size
}
override fun getGroup(groupPosition: Int): Any {
return titleList[groupPosition]
}
override fun getChild(groupPosition: Int, childPosition: Int): Any {
return this.itemsList[this.titleList[groupPosition]]!![childPosition]
}
override fun getGroupId(groupPosition: Int): Long {
return groupPosition.toLong()
}
override fun getChildId(groupPosition: Int, childPosition: Int): Long {
return childPosition.toLong()
}
override fun hasStableIds(): Boolean {
return false
}
override fun getGroupView(
groupPosition: Int,
isExpanded: Boolean,
convertView: View?,
parent: ViewGroup?
): View {
var convertView = convertView
val listTitle = getGroup(groupPosition) as String
if (convertView == null) {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
convertView = inflater.inflate(R.layout.discover_filter_list, null)
}
val titleText = convertView!!.findViewById<TextView>(R.id.listTitle)
titleText.text = listTitle
return convertView
}
override fun getChildView(
groupPosition: Int,
childPosition: Int,
isLastChild: Boolean,
convertView: View?,
parent: ViewGroup?
): View {
var convertView = convertView
val listItems = getChild(groupPosition, childPosition) as String
if (convertView == null) {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
convertView = inflater.inflate(R.layout.discover_filter_item, null)
}
val itemsText = convertView!!.findViewById<TextView>(R.id.listItem)
itemsText.text = listItems
return convertView
}
override fun isChildSelectable(groupPosition: Int, childPosition: Int): Boolean {
return true
}
}
Solved, Im alredy refer this link, I have added android:descendantFocusability="blocksDescendants" in Child XML and it really the solution.
Link:
Android ExpandableListView and onChildClick not working

Firebase Realtime Database images are not showing up in fragment kotlin class

I'm trying to show images from my Firebase Realtime Database storage. I've done this before with a previous version of my app, but the difference is how I implemented it. My adapter and arraylist class are exactly the same, but instead of using an activity I switched to using fragments.
What I essentially did was copy my old work and make the appropriate changes so I wouldn't run into errors, but unfortunately I ran into some. My images from Firebase are not showing up at all and I'm not sure what is the problem.
Adapter Class
class AbstractAdapter(private val mContext: Context, private val abstractList: ArrayList<Abstract>) : RecyclerView.Adapter<AbstractAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.abstract_image_view, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
Glide.with(mContext)
.load(abstractList[position].abstract)
.into(holder.imageView)
}
override fun getItemCount(): Int {
return abstractList.size
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var imageView: ImageView = itemView.findViewById(R.id.abstractImageView)
}
companion object {
private const val Tag = "RecyclerView"
}
}
Data class
class Abstract {
var abstract: String? = null
constructor() {}
constructor(abstract: String?) {
this.abstract = abstract
}
}
Fragment in which images will be shown
class AbstractWallpapers: Fragment(), PurchasesUpdatedListener {
private lateinit var subscribeAbstract: Button
private var billingClient: BillingClient? = null
lateinit var recyclerView: RecyclerView
lateinit var abstractlist: ArrayList<Abstract>
private var recyclerAdapterAbstract: AbstractAdapter? = null
private var myRef3: DatabaseReference? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_abstract_wallpaper, container, false)
recyclerView = requireView().findViewById(R.id.abstract_recyclerView)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
recyclerView = view.findViewById(R.id.abstract_recyclerView)
val layoutManager = LinearLayoutManager(requireActivity())
recyclerView.layoutManager = layoutManager
recyclerView.setHasFixedSize(true)
myRef3 = FirebaseDatabase.getInstance().reference
abstractlist = ArrayList()
ClearAll()
GetDataFromFirebase()
subscribeAbstract = view.findViewById(R.id.abstract_subscribe_btn)
subscribeAbstract.setOnClickListener {
subscribeAbstract()
}
// Establish connection to billing client
//check subscription status from google play store cache
//to check if item is already Subscribed or subscription is not renewed and cancelled
billingClient = BillingClient.newBuilder(requireActivity()).enablePendingPurchases().setListener(this).build()
billingClient!!.startConnection(object : BillingClientStateListener {
override fun onBillingSetupFinished(billingResult: BillingResult) {
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
val queryPurchase = billingClient!!.queryPurchases(BillingClient.SkuType.SUBS)
val queryPurchases = queryPurchase.purchasesList
if (queryPurchases != null && queryPurchases.size > 0) {
handlePurchases(queryPurchases)
} else {
saveSubscribeValueToPref(false)
}
}
}
override fun onBillingServiceDisconnected() {
Toast.makeText(requireActivity(), "Service Disconnected", Toast.LENGTH_SHORT).show()
}
})
//item subscribed
if (subscribeValueFromPref) {
subscribeAbstract.visibility = View.GONE
} else {
subscribeAbstract.visibility = View.VISIBLE
}
}
// Code related to Firebase
#SuppressLint("NotifyDataSetChanged")
private fun GetDataFromFirebase() {
val query: Query = myRef3!!.child("Abstract")
query.addListenerForSingleValueEvent(object : ValueEventListener {
#SuppressLint("NotifyDataSetChanged")
override fun onDataChange(snapshot: DataSnapshot) {
for (dataSnapshot: DataSnapshot in snapshot.children) {
val abstract = Abstract()
abstract.abstract = dataSnapshot.child("abstract").value.toString()
abstractlist.add(abstract)
}
recyclerAdapterAbstract = abstractlist.let { AbstractAdapter(requireActivity(), it) }
recyclerView.adapter = recyclerAdapterAbstract
recyclerAdapterAbstract!!.notifyDataSetChanged()
}
override fun onCancelled(error: DatabaseError) {}
})
if (recyclerAdapterAbstract != null) recyclerAdapterAbstract!!.notifyDataSetChanged()
}
private fun ClearAll() {
abstractlist.clear()
abstractlist = ArrayList()
}
I fixed my problem. It turns out my rules in Firebase Realtime Database rules for read were set to false instead. My code works perfect. It was only a stupid error on my part.

Can i monitor a variable changed in another class in kotlin?

Im in a fragment1 and i want go to fragment2 if an event occurred in a class called from the fragment1. I have tried a callback of fuction: function in Class call a function in fragment1 to go in fragment but i collect this error:
Process: com.example.ilmiogioco, PID: 7992java.lang.IllegalStateException: Method addObserver must be called on the main thread
at androidx.lifecycle.LifecycleRegistry.enforceMainThreadIfNeeded(LifecycleRegistry.java:317)
at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.java:172)
at androidx.savedstate.SavedStateRegistryController.performRestore(SavedStateRegistryController.java:61)
at androidx.navigation.NavBackStackEntry.<init>(NavBackStackEntry.java:88)
at androidx.navigation.NavBackStackEntry.<init>(NavBackStackEntry.java:73)
at androidx.navigation.NavController.navigate(NavController.java:1138)
at androidx.navigation.NavController.navigate(NavController.java:944)
at androidx.navigation.NavController.navigate(NavController.java:877)
at androidx.navigation.NavController.navigate(NavController.java:863)
at androidx.navigation.NavController.navigate(NavController.java:851)
at com.example.ilmiogioco.FullscreenFragmentSolo.follow(FullscreenFragmentSolo.kt:77)
at com.example.ilmiogioco.Solo.SpaceView.update(SpaceView.kt:276)
at com.example.ilmiogioco.Solo.SpaceView.run(SpaceView.kt:120)
at java.lang.Thread.run(Thread.java:919)
EDIT: I have fullscreenfragmentsolo (fragment1) that want in gameoverfragment (fragment2) if the class spaceview called in fullscreenfragmentsolo collect a lost game. The function follow() is called by spaceview for return in fullscreenfragmentsolo (maybe this is the thread error).
class FullscreenFragmentSolo : Fragment() {
private var spaceView: SpaceView? = null
private lateinit var backgroundMusic: MediaPlayer
private lateinit var window: Window
private var binding: FragmentFullscreenSoloBinding? = null
object size{
var x = 0
var y = 0
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
(activity as AppCompatActivity?)!!.supportActionBar!!.hide()
getActivity()?.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
val soundEffects = SoundEffects(requireContext())
soundEffects.playSound(SoundEffects.backgroundMusic)
val outMetrics = DisplayMetrics()
getActivity()?.getWindow()?.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
window = activity?.getWindow()!!
window.attributes.width
window.attributes.height
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
val display = activity?.display
display?.getRealMetrics(outMetrics)
} else {
#Suppress("DEPRECATION")
val display = activity?.windowManager?.defaultDisplay
#Suppress("DEPRECATION")
display?.getMetrics(outMetrics)
}
size.y = outMetrics.heightPixels
size.x = outMetrics.widthPixels
backgroundMusic = MediaPlayer.create(requireContext(), R.raw.background_music)
backgroundMusic.isLooping = true
backgroundMusic.start()
val fragmentBinding = FragmentFullscreenSoloBinding.inflate(inflater, container, false)
binding = fragmentBinding
fragmentBinding.root
spaceView = SpaceView(requireContext(), size, this)
return spaceView
}
fun follow(){
findNavController().navigate(R.id.action_fullscreenFragmentSolo_to_gameoverFragment)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding?.soloFragment = this
}
override fun onResume() {
super.onResume()
spaceView?.resume()
}
fun stopFunction() {
spaceView?.stop()
}
override fun onPause() {
super.onPause()
backgroundMusic.release()
spaceView?.pause()
}
override fun onDestroyView() {
super.onDestroyView()
binding = null
}
GameoverFragment:
open class GameoverFragment : Fragment() {
private var binding: GameoverFragmentBinding? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val fragmentBinding = GameoverFragmentBinding.inflate(inflater, container, false)
binding = fragmentBinding
return fragmentBinding.root
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding?.gameoverFragment = this
}
fun Menu(){
findNavController().navigate(R.id.action_gameoverFragment_to_startFragment)
}
> override fun onDestroyView() {
> super.onDestroyView()
> binding = null }
Can you help me?
This exception is due to your code calling (through navigation) the LifecycleRegistry.addObserver from a thread other than the Main thread. You have to ensure that you call the navigation from the main thread.
Change to this in the follow() function
import android.os.Handler
import android.os.Looper
// ...
fun follow() {
Handler(Looper.getMainLooper()).post {
findNavController().navigate(R.id.action_fullscreenFragmentSolo_to_gameoverFragment)
}
}

How to solve view binding null pointer exception when activity restarts and fragment recreates

Anytime my MainActivity restarts because of changing of dark mode and i try to click i get nullpointer exception.
The error is below
I have a BaseFragment
lateinit var mContext:Context
lateinit var mActivity:Activity
var myId = ""
val firebaseMethods: FirebaseMethods by lazy { FirebaseMethods(requireActivity()) }
override fun onDestroy() {
super.onDestroy()
removeListeners()
}
override fun onAttach(context: Context) {
super.onAttach(context)
showLogI("onAttach")
}
override fun onDetach() {
super.onDetach()
showLogI("onDetach")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mContext = requireContext()
mActivity = requireActivity()
showLogI("onCreate")
if(getCurrentUser() != null){
myId = getCurrentUserId()
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?)
: View {
showLogI("onCreateView")
val view = setContentView(inflater, container, savedInstanceState)
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initView(view)
setListener()
initData()
}
protected abstract fun setContentView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?):View
protected abstract fun setListener()
protected abstract fun initData()
I also have a PostFragment
var posts:ArrayList<Post> = arrayListOf()
var pgPosts:ArrayList<Post> = arrayListOf()
var ids:ArrayList<String> = arrayListOf()
val keys:ArrayList<String> = arrayListOf()
var totalSize = 0
var query: Query? = null
var postAdapter:PostAdapter? = null
var counter = 0
var adUnit = ""
var adminId = ""
override fun onDestroy() {
super.onDestroy()
postAdapter?.removeListeners()
destroyAds()
}
private var _binding: FragmentPostBinding? = null
private val binding get() = _binding!!
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun setContentView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentPostBinding.inflate(inflater, container, false)
return binding.root
}
override fun setListener() {
}
override fun initData() {
getArgs()
toggleOrientation()
showProgress()
setAdapter()
val spannableString = "No Internet Connection. Retry".createSpan("Retry"){ spannableString, start, end ->
mContext.setSpan(spannableString, "click", start, end, R.color.green){readPosts()}
}
if (mContext.isConnectingToInternet()) readPosts() else hideProgressWithSpan(spannableString)
adUnit = mContext.getString(R.string.ads_unit_video)
firebaseMethods.getAdmin { admin->
adminId = admin.admin_id
//adUnit = admin.native_ads_unit
}
}
fun changeLayout(orientation:String){
this.orientation = orientation
toggleOrientation()
setAdapter()
}
fun toggleOrientation(){
if (orientation == "big") {
max = 5
binding.recyclerview.lm()
} else if (orientation == "small") {
max = 15
binding.recyclerview.lm("grid", 3)
}
}
I get this null pointer exception
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.wh, PID: 26862
java.lang.NullPointerException at com.wh.ui.fragment.post.PostFragment.getBinding(PostFragment.kt:101)
at com.wh.ui.fragment.post.PostFragment.toggleOrientation(PostFragment.kt:160)
at com.wh.ui.fragment.post.PostFragment.changeLayout(PostFragment.kt:154)
As #Tenfour04 has said , you're accessing the binding when the fragment has been detached. You need to first check if the fragment has been added like so
if(isAdded){
//do something with the binding
}
Thanks a lot. I finally found the solution. I was checking if state is null for my bottom navigation view fragments and if null using new fragment, if not finding fragmentbytag. I just guessed to create the fragment without checking state and it worked.

Rcyclervier inside recyclerview, adapter result getting at one place

I am making android application, where i am using recyclerview inside recyclerview, all working is fine but i am getting my second adapter result at one place
Out of 4 results two results should shown in above
Problem:
In my recyclerview result shoud show like: 1[1,2,3] // this is my recyclerview inside recyclerview 2[1,2,3]
but i am getting result like 1[] 2[1,2,3 1,2,3] // but i am getting result like this
history.kt
class history : Fragment(), KodeinAware {
lateinit var recyclerView : RecyclerView
lateinit var layoutManager : LinearLayoutManager
lateinit var orid_TA_Adapter : history_adapter
lateinit var orid_TA : ArrayList<orderID_Am_ST>
lateinit var db : FirebaseFirestore
val auth = FirebaseAuth.getInstance()
val Fuser = auth.currentUser
override val kodein: Kodein by kodein { activity?.applicationContext!! }
private val factory: CustomerViewModelFactory by instance()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view= inflater.inflate(R.layout.fragment_history, container, false)
recyclerView = view?.findViewById(R.id.history)!!
layoutManager = LinearLayoutManager(activity as Context)
recyclerView.layoutManager = layoutManager
recyclerView.setHasFixedSize(true)
orid_TA = arrayListOf()
orid_TA_Adapter = history_adapter(orid_TA,requireContext())
recyclerView.adapter = orid_TA_Adapter
All_orid_TA()
return view
}
private fun All_orid_TA(){
db = FirebaseFirestore.getInstance()
db.collection("Order Details1/${Fuser?.uid}/OrderID").addSnapshotListener(object :
EventListener<QuerySnapshot> {
override fun onEvent(value: QuerySnapshot?, error: FirebaseFirestoreException?) {
if(error != null){
Log.e("Firestore error",error.message.toString())
return
}
for(doc: DocumentChange in value?.documentChanges!!){
if(doc.type == DocumentChange.Type.ADDED){
orid_TA.add(doc.document.toObject(orderID_Am_ST::class.java))
}
}
orid_TA_Adapter.notifyDataSetChanged()
}
})
}
}
history_adapter.kt
class history_adapter(private var oidta:ArrayList<orderID_Am_ST>, val context: Context): RecyclerView.Adapter<history_adapter.ViewHolder>() {
val fireStore = FirebaseFirestore.getInstance()
// lateinit var recyclerView : RecyclerView
lateinit var layoutManager : LinearLayoutManager
lateinit var history_product_Adapter : history_product_adapter
lateinit var history_product : ArrayList<Add_to_FireStore>
lateinit var db : FirebaseFirestore
val auth = FirebaseAuth.getInstance()
val Fuser = auth.currentUser
private val viewPool = RecyclerView.RecycledViewPool()
class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
val slot_time_history: TextView = itemView.findViewById(R.id.slot_time_history)
val delivery_address_history: TextView = itemView.findViewById(R.id.delivery_address_history)
val totalamount_history: TextView = itemView.findViewById(R.id.totalamount_history)
val recyclerView: RecyclerView = itemView.findViewById(R.id.product_history)
val shop_name_history: TextView = itemView.findViewById(R.id.shop_name_history)
val order_ID_history: TextView = itemView.findViewById(R.id.order_ID_history)
val order_date_history: TextView = itemView.findViewById(R.id.order_date_history)
val phone_number_history: TextView = itemView.findViewById(R.id.phone_number_history)
val cancel_order: Button = itemView.findViewById(R.id.cancel_order)
val status_order: TextView = itemView.findViewById(R.id.status_order)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.history_adapter, parent, false)
return history_adapter.ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val orderId_TA : orderID_Am_ST = oidta[position]
holder.slot_time_history.text = orderId_TA.slot_time
holder.delivery_address_history.text = orderId_TA.deliver_address
holder.totalamount_history.text = orderId_TA.total_ammount
holder.order_ID_history.text = orderId_TA.order_id
holder.order_date_history.text = orderId_TA.order_date
holder.status_order.text = orderId_TA.status
layoutManager = LinearLayoutManager(context)
//layoutManager.initialPrefetchItemCount = oidta.size
//layoutManager = LinearLayoutManager(holder.recyclerView.context, RecyclerView.VERTICAL, false)
holder.recyclerView.layoutManager = layoutManager
holder.recyclerView.setHasFixedSize(true)
history_product = arrayListOf()
history_product_Adapter = history_product_adapter(history_product, context)
holder.recyclerView.adapter = history_product_Adapter
holder.recyclerView.setRecycledViewPool(viewPool)
//All_product_List(orderId_TA.order_id)
db = FirebaseFirestore.getInstance()
db.collection("customer/user/profile").document("${Fuser?.uid}").get().addOnCompleteListener {
if(it.isSuccessful){
val shop_name = it.result["shopname"]
holder.shop_name_history.text = shop_name.toString()
holder.phone_number_history.text = Fuser?.phoneNumber.toString()
}
}
//oidta[holder.adapterPosition].order_id OID0a7bedfd469649bd9a
//db.collection("Order Details1/${Fuser?.uid}/OrderID/${orderId_TA.order_id.toString()}
db.collection("Order Details1/${Fuser?.uid}/OrderID/OID1945395f651948f186/order").addSnapshotListener(object :
EventListener<QuerySnapshot> {
override fun onEvent(value: QuerySnapshot?, error: FirebaseFirestoreException?) {
if(error != null){
Log.e("Firestore error",error.message.toString())
return
}
for(doc: DocumentChange in value?.documentChanges!!){
if(doc.type == DocumentChange.Type.ADDED){
//history_product.add(doc.document.toObject(Add_to_FireStore::class.java))
history_product.add(doc.document.toObject(Add_to_FireStore::class.java))
}
}
//history_product
history_product_Adapter.notifyDataSetChanged()
}
})
val order_time:String = orderId_TA.order_date.toString()
val sdf1 = SimpleDateFormat("dd/M/yyyy H:mm:ss")
val currentDate_Time = sdf1.format(Date())
val format = SimpleDateFormat("dd/M/yyyy H:mm:ss")
val diff = format.parse(currentDate_Time).time - format.parse(order_time).time
val hours:Int = (diff/3600000).toInt()
if(hours <= 5000){
if(holder.status_order.text == "cancelled"){
holder.cancel_order.isClickable = false
holder.cancel_order.setBackgroundColor(Color.GRAY)
}else{
holder.cancel_order.setOnClickListener {
val alertDialogBuilder = AlertDialog.Builder(context)
alertDialogBuilder.setTitle(Html.fromHtml("<font color='#00BFFF'>Cancel Order</font>"))
// alertDialogBuilder.setIcon(R.drawable.exit)
alertDialogBuilder.setMessage("Are you sure sure want to Cancel Order?")
alertDialogBuilder.setCancelable(false)
alertDialogBuilder.setPositiveButton(
Html.fromHtml("<font color='#00BFFF'>Yes</font>"),
DialogInterface.OnClickListener { dialog, which ->
Toast.makeText(context, "Cancelling Order", Toast.LENGTH_SHORT).show()
FirebaseFirestore.getInstance().collection("Order Details1/${Fuser?.uid}/OrderID").document("${orderId_TA.order_id}").update("status","cancelled")
holder.status_order.text = orderId_TA.status
})
alertDialogBuilder.setNegativeButton(
Html.fromHtml("<font color='#00BFFF'>No</font>"),
DialogInterface.OnClickListener { dialog, which ->
Toast.makeText(
context,
"You clicked cancel",
Toast.LENGTH_LONG
).show()
})
val alertDialog: AlertDialog = alertDialogBuilder.create()
alertDialog.show()
}
}
}else{
holder.cancel_order.setBackgroundColor(Color.GRAY)
holder.cancel_order.setOnClickListener {
Toast.makeText(context, "Can not cancel order after 5 hours", Toast.LENGTH_SHORT).show()
}
}
}
override fun getItemCount(): Int {
return oidta.size
}
}
history_product_adapter.kt
class history_product_adapter(private var prod_det1:ArrayList<Add_to_FireStore>, val context: Context): RecyclerView.Adapter<history_product_adapter.ViewHolder>() {
class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
val product__name: TextView = itemView.findViewById(R.id.product__name)
val product__kgsize: TextView = itemView.findViewById(R.id.product__kgsize)
val product__varientsize: TextView = itemView.findViewById(R.id.product__varientsize)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.history_product_adapter, parent, false)
return history_product_adapter.ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val orderId_TA : Add_to_FireStore = prod_det1[position]
holder.product__name.text = orderId_TA.productName
holder.product__kgsize.text = orderId_TA.kgsize
holder.product__varientsize.text = orderId_TA.varientsize
}
override fun getItemCount(): Int {
return prod_det1.size
}
}

Resources