How to "Catch and Forwarding" Intent (URL) in Kotin? - kotlin

---> Full Code for more details https://github.com/BUdiAKmal/CaseApp
I've been successfully pass the data, but how about the URL?
i need to open URL contained in each item to WebView Activity but by pressing the button on "Activity Details"...
How to do it from this code?
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Start - full screen
val window = window
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
) // End - full screen
setUpTabs() // Setup TabLayout
} // End - OnCreate
// Start - TabLayout
private fun setUpTabs() {
val adapter = ViewPagerAdapter(supportFragmentManager)
adapter.addFragment(MainTabFragment1(), "MainTab1")
adapter.addFragment(MainTabFragment1(), "MainTab2")
viewPager_tabLayout.adapter = adapter
tabs.setupWithViewPager(viewPager_tabLayout)
} // End - TabLayout
} // End - Class
MainTabFragment
class MainTabFragment1 : Fragment() {
lateinit var mainTabFragment1Adapter: MainTabFragment1Adapter // Initialize Adapter
private val sLM = LinearLayoutManager(context) // Initialize layoutManager
val addMainTabFragment1ModelList: MutableList<MainTabFragment1Model> = ArrayList() // Initialize listModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment1_main_tab, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initViewMainTabFragment1() // SetUp initView listModel
actionMainTabFragment1() // SetUp actionMainTabFragment1
} // End - OnCreate
// Start - intView listModel
private fun initViewMainTabFragment1() {
rv_mainTabFragment1.layoutManager = sLM
mainTabFragment1Adapter = MainTabFragment1Adapter(requireActivity())
rv_mainTabFragment1.adapter = mainTabFragment1Adapter
addMainTabFragment1ModelList.add(
MainTabFragment1Model(
"https://images.unsplash.com/photo-1585435465945-bef5a93f8849",
"Title RVItemNo.1 MainTabFragment1",
"Desc RVItenNo.1 MainTabFragment1",
"https://google.com"
)
)
addMainTabFragment1ModelList.add(
MainTabFragment1Model(
"https://images.unsplash.com/photo-1487846698364-db1316e3d140",
"Title RVItemNo.2 MainTabFragment1",
"Desc RVItenNo.2 MainTabFragment1",
"https://youtube.com"
)
)
addMainTabFragment1ModelList.add(
MainTabFragment1Model(
"https://images.unsplash.com/photo-1512295767273-ac109ac3acfa",
"Title RVItemNo.3 MainTabFragment1",
"Desc RVItenNo.3 MainTabFragment1",
"https://gmail.com"
)
)
addMainTabFragment1ModelList.add(
MainTabFragment1Model(
"https://images.unsplash.com/photo-1525896969906-0a4806967ef0",
"Title RVItemNo.4 MainTabFragment1",
"Desc RVItenNo.4 MainTabFragment1",
"https://blgger.com"
)
)
mainTabFragment1Adapter.setMainTabFragment1(addMainTabFragment1ModelList)
} // End - intView listModel
// Start - putExtra
fun actionMainTabFragment1() {
mainTabFragment1Adapter.setOnClickItemListenerMainTabFragment1(object : OnItemClickListener {
override fun onItemClick(item: View, position: Int) {
val i = Intent(context, DetailsActivity::class.java)
i.putExtra(
"titleTextMainTabFragment1",
mainTabFragment1Adapter
.getMainTabFragment1()
.get(position)
.titleTextMainTabFragment1
)
i.putExtra(
"descTextMainTabFragment1",
mainTabFragment1Adapter
.getMainTabFragment1()
.get(position)
.descTextMainTabFragment1
)
i.putExtra(
"imgURLMainTabFragment1",
mainTabFragment1Adapter
.getMainTabFragment1()
.get(position)
.imgURLMainTabFragment1
)
i.putExtra(
"btnURLMainTabFragment1",
mainTabFragment1Adapter
.getMainTabFragment1()
.get(position)
.btnURLMainTabFragment1
)
startActivity(i)
}
})
} // End - putExtra
}
MainTabFragment1Adapter
class MainTabFragment1Adapter(private val context: Context) :
RecyclerView.Adapter<MainTabFragment1Adapter.MainTabFragment1ViewHolder>() {
private val MainTabFragment1Model: MutableList<MainTabFragment1Model> = mutableListOf() // Initialize listModel
private lateinit var onSelectedListenerMainTabFragment1: OnItemClickListener // Initialize onItemListener
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainTabFragment1ViewHolder {
return MainTabFragment1ViewHolder(
LayoutInflater.from(context).inflate(R.layout.item_maintab_fragment1_layout, parent, false)
)
} // End - onCreateViewHolder
override fun getItemCount(): Int {
return MainTabFragment1Model.size
} // End - getItem
override fun onBindViewHolder(holder: MainTabFragment1ViewHolder, position: Int) {
holder.maintabfragment1BindView(MainTabFragment1Model[position])
} // End - onBindViewHolder
// Start - setMainTabFragment1
fun setMainTabFragment1(data: List<MainTabFragment1Model>) {
MainTabFragment1Model.clear()
MainTabFragment1Model.addAll(data)
notifyDataSetChanged()
} // End - setMainTabFragment1
// Start - getMainTabFragment1
fun getMainTabFragment1(): MutableList<MainTabFragment1Model> {
return MainTabFragment1Model
} // End - getMainTabFragment1
// Start - MainTabFragment1ViewHolder
inner class MainTabFragment1ViewHolder(maintabfragment1view: View) : RecyclerView.ViewHolder(maintabfragment1view) {
val ivMainTabFragment1 = maintabfragment1view.findViewById<ImageView>(R.id.iv_RVItem_MainTabFragment1)
val tvTitleMainTabFragment1 = maintabfragment1view.findViewById<TextView>(R.id.tv_titleText_MainTabFragment1)
val cvMainTabFragment1: MaterialCardView = maintabfragment1view.findViewById(R.id.cv_RVItem_MainTabFragment1)
fun maintabfragment1BindView(MainTabFragment1Model: MainTabFragment1Model) {
MainTabFragment1Model.apply {
val image = MainTabFragment1Model.imgURLMainTabFragment1
image.let {
Glide.with(itemView.context)
.load(it)
.into(ivMainTabFragment1)
Glide.with(itemView.context)
.load(it)
.centerCrop()
.fitCenter()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
}
}
tvTitleMainTabFragment1.text = MainTabFragment1Model.titleTextMainTabFragment1
}
init {
cvMainTabFragment1.setOnClickListener { onSelectedListenerMainTabFragment1.onItemClick(it, layoutPosition) }
}
} // End - MainTabFragment1BindViewHolder
// Start - OnItemListener
fun setOnClickItemListenerMainTabFragment1(onItemClickListener: OnItemClickListener) {
this.onSelectedListenerMainTabFragment1 = onItemClickListener
} // End - OnItemListener
} // End - Class
MainTabFragment1Model
data class MainTabFragment1Model
(var imgURLMainTabFragment1: String?,
var titleTextMainTabFragment1: String?,
var descTextMainTabFragment1: String?,
val btnURLMainTabFragment1: String?)
Listener
interface OnItemClickListener {
fun onItemClick(item: View, position:Int)
}
WebViewActivity
class WebViewActivity : AppCompatActivity() {
private lateinit var webView: WebView // Initialize WebView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_webview)
// Start - Assign Open New URL
val wBS = intent
val webSite = wBS.getStringExtra("btnURLMainTabFragment1")
// End - Assign Open New URL
// Start - full screen
val window = window
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
) // End - full screen
// Start - WebView
webView = findViewById(R.id.wv)
webView.setWebViewClient(object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
view?.visibility = View.INVISIBLE
if (Build.VERSION.SDK_INT >= 19) {
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null)
} else {
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
}
}
override fun onPageFinished(view: WebView?, url: String?) {
swipe?.isRefreshing = false
super.onPageFinished(view, url)
view?.visibility = View.VISIBLE
}
// Start - Fix Whatsapp Acces
override fun shouldOverrideUrlLoading(wv: WebView, url: String): Boolean {
if (url.startsWith("tel:") || url.startsWith("whatsapp:")) {
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse(url)
startActivity(intent)
webView.goBack()
return true
}
return false
} // End - Fix Whatsapp Acces
}) // End - WebView
refreshApp() // SetUp SwipeRefresh
// Start - WebView Setting
if (webSite != null) {
webView.loadUrl(webSite)
}
val webSettings = webView.settings
webSettings.javaScriptEnabled = true // js active
webSettings.domStorageEnabled = true // componenet load
webSettings.allowContentAccess = true
webSettings.loadsImagesAutomatically = true
webSettings.cacheMode = WebSettings.LOAD_NO_CACHE
webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH)
webSettings.setEnableSmoothTransition(true)
// End - WebView Setting
}// End -OnCreate
// Start - BackPressed CurrentView
override fun onBackPressed() {
if (webView.canGoBack()) {
webView.goBack()
} else
super.onBackPressed()
} // End - BackPressed CurrentView
// Start - SwipeRefresh
private fun refreshApp() {
swipe.setOnRefreshListener {
webView?.reload()
Toast.makeText(this, "Refresh!", Toast.LENGTH_SHORT).show()
}
} // End- SwipeRefresh
} // finish MainActivity
I hope someone can solve this case. thanks :)

Related

Synthetics to Viewbinding issues (onBackPress & Navigation Drawer)

I am updating my app to completely remove synthetics and move to viewbinding, however I am struggling with converting the onBackPressed method (now also deprecated) with my Activity, Fragment and Navigation Drawer.
I originally had it like this:
Activity (Before)
override fun onCreate(savedInstanceState: Bundle?) {
Log.d(TAG, "onCreate")
super.onCreate(savedInstanceState)
val activityBinding: BusinessActivityBinding = DataBindingUtil.setContentView(
this,
R.layout.business_activity
)
nav_view.setNavigationItemSelectedListener(this)
val headerView = activityBinding.navView.getHeaderView(0)
headerView.navHeaderEmailText.setOnClickListener { sendSupportEmail() }
navController = findNavController(this, R.id.NavHostFragment)
// other stuff
}
fun openCloseNavigationDrawer() {
if (business_drawer_layout.isDrawerOpen(GravityCompat.START)) {
business_drawer_layout.closeDrawer(GravityCompat.START)
} else {
business_drawer_layout.openDrawer(GravityCompat.START)
}
}
override fun onBackPressed() {
val navHostFragment: NavHostFragment = supportFragmentManager.findFragmentById(R.id.NavHostFragment) as NavHostFragment
val backStackEntryCount = navHostFragment?.childFragmentManager?.backStackEntryCount
when {
(business_drawer_layout.isDrawerOpen(GravityCompat.START)) -> business_drawer_layout.closeDrawer(
GravityCompat.START
)
(backStackEntryCount == 0) -> dialogLeaveApp()
else -> super.onBackPressed()
}
}
private fun dialogLeaveApp(){
MaterialDialog(this).show {
title(R.string.business_activity_dialog_leave_app_heading)
message(R.string.business_activity_dialog_leave_app_message)
positiveButton(R.string.business_activity_dialog_confirm_button){
super.onBackPressed()
}
negativeButton(R.string.business_activity_dialog_cancel_button) {
dismiss()
}
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.nav_sites_fragment -> navigateWithClearStack(R.id.sitesFragment)
R.id.nav_projects_fragment -> navigateWithClearStack(R.id.projectsFragment)
R.id.nav_contacts_fragment -> navigateWithClearStack(R.id.contactsFragment)
R.id.nav_tasks_fragment -> navigateWithClearStack(R.id.tasksFragment)
R.id.nav_profile_fragment -> makeToast("Todo: Profile Fragment")
R.id.nav_settings_fragment -> navigateWithClearStack(R.id.settingsFragment)
}
business_drawer_layout.closeDrawer(GravityCompat.START)
return true
}
private fun navigateWithClearStack(destination: Int) {
businessViewModel.clearCurrentVMData()
val navHostFragment: NavHostFragment = supportFragmentManager.findFragmentById(R.id.NavHostFragment) as NavHostFragment
val inflater = navHostFragment.navController.navInflater
val graph = inflater.inflate(R.navigation.business_navigation)
graph.startDestination = destination
navController.graph = graph
}
}
Fragment (already using viewbinding)
class SitesFragment : Fragment() {
private lateinit var navController: NavController
private lateinit var businessViewModel: BusinessViewModel
private lateinit var sitesAdapter: SitesRecyclerViewAdapter
private var _binding: SitesFragmentBinding? = null // this property is only valid between onCreateView & onDestroyView
private val binding get() = _binding!! //https://stackoverflow.com/questions/57647751/android-databinding-is-leaking-memory
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
Log.d(TAG, "onCreateView()")
activity?.let {
businessViewModel = ViewModelProvider(it).get(BusinessViewModel::class.java)
Log.d(TAG, "businessViewModel = $businessViewModel")
}
Log.d(TAG, businessViewModel.currentStatus("${TAG}, onCreateView()"))
// Inflate the layout for this fragment
_binding = SitesFragmentBinding.inflate(inflater, container, false)
val view = binding.root
binding.apply {
sitesDrawerMenuButton.setOnClickListener {
(activity as BusinessActivity).openCloseNavigationDrawer()
Log.d(TAG, "sitesDrawerMenuButton clicked, openCloseNavigationDrawer()")
}
// Other listeners
}
return view
}
Activity (After)
private var _binding: BusinessActivityBinding? = null
private val binding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
Log.d(TAG, "onCreate")
super.onCreate(savedInstanceState)
// Inflate the layout for this activity
_binding = BusinessActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
val navHostFragment = supportFragmentManager.findFragmentById(R.id.NavHostFragment) as NavHostFragment
this.navController = navHostFragment.navController
binding.navView.setupWithNavController(this.navController)
// Setup OnBackPressedDispatcher
val backPressedCallback = object:OnBackPressedCallback(false){
override fun handleOnBackPressed() {
onBackButtonPressed()
}
}
// Other stuff
}
fun openCloseNavigationDrawer() { // accessed by Fragment
if (binding.businessDrawerLayout.isDrawerOpen(GravityCompat.START)) {
binding.businessDrawerLayout.closeDrawer(GravityCompat.START)
} else {
binding.businessDrawerLayout.openDrawer(GravityCompat.START)
}
}
fun onBackButtonPressed() {
val navHostFragment: NavHostFragment = supportFragmentManager.findFragmentById(R.id.NavHostFragment) as NavHostFragment
val backStackEntryCount = navHostFragment.childFragmentManager.backStackEntryCount
when {
(binding.businessDrawerLayout.isDrawerOpen(GravityCompat.START)) -> binding.businessDrawerLayout.closeDrawer(
GravityCompat.START
)
(backStackEntryCount == 0) -> dialogLeaveApp()
}
}
private fun dialogLeaveApp(){
// as before
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
// as before
}
private fun navigateWithClearStack(destination: Int) {
// as before
}
So the issue is that when you back press, it simply exits the app, rather than triggering my function onBackButtonPressed() (which replaces the depricated onBackPressed())and variable 'backPressedCallback' is never used..

FATAL EXCEPTION when Forwarding Intent (URL) in kotlin

---> Full Code for more details https://github.com/BUdiAKmal/CaseApp
After passing URL from "RecyclerView" to Button on "DetailsActivity" , i try to forwarding and load the URL to "WebViewActivity" when user click the "Button on DeetailsActivity".
and finally i get this error :
FATAL EXCEPTION: main
Process: com.caseapp, PID: 5139
java.lang.StackOverflowError: stack size 8MB
at android.os.Parcel.-get0(Unknown Source:0)
at android.os.Parcel$ReadWriteHelper.writeString(Parcel.java:353)
at android.os.Parcel.writeString(Parcel.java:675)
at android.content.ComponentName.writeToParcel(ComponentName.java:320)
at android.content.ComponentName.writeToParcel(ComponentName.java:335)
at android.content.Intent.writeToParcel(Intent.java:9566)
at android.os.Parcel.writeParcelable(Parcel.java:1791)
at android.os.Parcel.writeValue(Parcel.java:1697)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:838)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1542)
at android.os.Bundle.writeToParcel(Bundle.java:1232)
at android.os.Parcel.writeBundle(Parcel.java:878)
at android.content.Intent.writeToParcel(Intent.java:9599)
at com.caseapp.ui.activities.DetailsActivity.initView$lambda-2$lambda-1(DetailsActivity.kt:68)
at com.caseapp.ui.activities.DetailsActivity.$r8$lambda$JHNmedXwzuffRCNJln7AS9uz4NI(Unknown Source:0)
at com.caseapp.ui.activities.DetailsActivity$$ExternalSyntheticLambda0.onClick(Unknown Source:2)
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Start - full screen
val window = window
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
) // End - full screen
setUpTabs() // Setup TabLayout
} // End - OnCreate
// Start - TabLayout
private fun setUpTabs() {
val adapter = ViewPagerAdapter(supportFragmentManager)
adapter.addFragment(MainTabFragment1(), "MainTab1")
adapter.addFragment(MainTabFragment1(), "MainTab2")
viewPager_tabLayout.adapter = adapter
tabs.setupWithViewPager(viewPager_tabLayout)
} // End - TabLayout
} // End - Class
MainTabFragment1.kt
class MainTabFragment1 : Fragment() {
lateinit var mainTabFragment1Adapter: MainTabFragment1Adapter // Initialize Adapter
private val sLM = LinearLayoutManager(context) // Initialize layoutManager
val addMainTabFragment1ModelList: MutableList<MainTabFragment1Model> = ArrayList() // Initialize listModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment1_main_tab, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initViewMainTabFragment1() // SetUp initView listModel
actionMainTabFragment1() // SetUp actionMainTabFragment1
} // End - OnCreate
// Start - intView listModel
private fun initViewMainTabFragment1() {
rv_mainTabFragment1.layoutManager = sLM
mainTabFragment1Adapter = MainTabFragment1Adapter(requireActivity())
rv_mainTabFragment1.adapter = mainTabFragment1Adapter
addMainTabFragment1ModelList.add(
MainTabFragment1Model(
"https://images.unsplash.com/photo-1585435465945-bef5a93f8849",
"Title RVItemNo.1 MainTabFragment1",
"Desc RVItenNo.1 MainTabFragment1",
"https://google.com"
)
)
addMainTabFragment1ModelList.add(
MainTabFragment1Model(
"https://images.unsplash.com/photo-1487846698364-db1316e3d140",
"Title RVItemNo.2 MainTabFragment1",
"Desc RVItenNo.2 MainTabFragment1",
"https://youtube.com"
)
)
addMainTabFragment1ModelList.add(
MainTabFragment1Model(
"https://images.unsplash.com/photo-1512295767273-ac109ac3acfa",
"Title RVItemNo.3 MainTabFragment1",
"Desc RVItenNo.3 MainTabFragment1",
"https://gmail.com"
)
)
addMainTabFragment1ModelList.add(
MainTabFragment1Model(
"https://images.unsplash.com/photo-1525896969906-0a4806967ef0",
"Title RVItemNo.4 MainTabFragment1",
"Desc RVItenNo.4 MainTabFragment1",
"https://blgger.com"
)
)
mainTabFragment1Adapter.setMainTabFragment1(addMainTabFragment1ModelList)
} // End - intView listModel
// Start - putExtra
fun actionMainTabFragment1() {
mainTabFragment1Adapter.setOnClickItemListenerMainTabFragment1(object : OnItemClickListener {
override fun onItemClick(item: View, position: Int) {
val i = Intent(context, DetailsActivity::class.java)
i.putExtra(
"titleTextMainTabFragment1",
mainTabFragment1Adapter
.getMainTabFragment1()
.get(position)
.titleTextMainTabFragment1
)
i.putExtra(
"descTextMainTabFragment1",
mainTabFragment1Adapter
.getMainTabFragment1()
.get(position)
.descTextMainTabFragment1
)
i.putExtra(
"imgURLMainTabFragment1",
mainTabFragment1Adapter
.getMainTabFragment1()
.get(position)
.imgURLMainTabFragment1
)
i.putExtra(
"btnURLMainTabFragment1",
mainTabFragment1Adapter
.getMainTabFragment1()
.get(position)
.btnURLMainTabFragment1
)
startActivity(i)
}
})
} // End - putExtra
}
DetailsActivity.kt
class DetailsActivity : AppCompatActivity() {
var prodBundle: Bundle? = null // Initialize getString (bundle) from MainActivity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_details)
// Start - full screen
val window = window
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
) // End - full screen
initView() // Setup getString from RecyclerView Main Activity
} // End - OnCreate
// Start - getString from RecyclerView Main Activity
fun initView() {
prodBundle = intent.extras
tv_titleText.text = prodBundle?.getString("titleTextMainTabFragment1")
tv_descText.text = prodBundle?.getString("descTextMainTabFragment1")
prodBundle?.getString("imgURLMainTabFragment1").let {
Glide.with(this).asBitmap()
.load(it)
.into(iv_imgURL)
Glide.with(this).asBitmap()
.load(it)
.centerCrop()
.fitCenter()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
}
prodBundle?.getString("btnURLMainTabFragment1").let {
btn_wvURL.setOnClickListener {
val gotoWebView = Intent(this#DetailsActivity, WebViewActivity::class.java)
gotoWebView.putExtra("btnURLMainTabFragment1", gotoWebView)
startActivity(gotoWebView)
}
}
} // End - getString from RecyclerView Main Activity }
} // End - Class
MainTabFragment1Adapter.kt
class MainTabFragment1Adapter(private val context: Context) :
RecyclerView.Adapter<MainTabFragment1Adapter.MainTabFragment1ViewHolder>() {
private val MainTabFragment1Model: MutableList<MainTabFragment1Model> = mutableListOf() // Initialize listModel
private lateinit var onSelectedListenerMainTabFragment1: OnItemClickListener // Initialize onItemListener
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainTabFragment1ViewHolder {
return MainTabFragment1ViewHolder(
LayoutInflater.from(context).inflate(R.layout.item_maintab_fragment1_layout, parent, false)
)
} // End - onCreateViewHolder
override fun getItemCount(): Int {
return MainTabFragment1Model.size
} // End - getItem
override fun onBindViewHolder(holder: MainTabFragment1ViewHolder, position: Int) {
holder.maintabfragment1BindView(MainTabFragment1Model[position])
} // End - onBindViewHolder
// Start - setMainTabFragment1
fun setMainTabFragment1(data: List<MainTabFragment1Model>) {
MainTabFragment1Model.clear()
MainTabFragment1Model.addAll(data)
notifyDataSetChanged()
} // End - setMainTabFragment1
// Start - getMainTabFragment1
fun getMainTabFragment1(): MutableList<MainTabFragment1Model> {
return MainTabFragment1Model
} // End - getMainTabFragment1
// Start - MainTabFragment1ViewHolder
inner class MainTabFragment1ViewHolder(maintabfragment1view: View) : RecyclerView.ViewHolder(maintabfragment1view) {
val ivMainTabFragment1 = maintabfragment1view.findViewById<ImageView>(R.id.iv_RVItem_MainTabFragment1)
val tvTitleMainTabFragment1 = maintabfragment1view.findViewById<TextView>(R.id.tv_titleText_MainTabFragment1)
val cvMainTabFragment1: MaterialCardView = maintabfragment1view.findViewById(R.id.cv_RVItem_MainTabFragment1)
fun maintabfragment1BindView(MainTabFragment1Model: MainTabFragment1Model) {
MainTabFragment1Model.apply {
val image = MainTabFragment1Model.imgURLMainTabFragment1
image.let {
Glide.with(itemView.context)
.load(it)
.into(ivMainTabFragment1)
Glide.with(itemView.context)
.load(it)
.centerCrop()
.fitCenter()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
}
}
tvTitleMainTabFragment1.text = MainTabFragment1Model.titleTextMainTabFragment1
}
init {
cvMainTabFragment1.setOnClickListener { onSelectedListenerMainTabFragment1.onItemClick(it, layoutPosition) }
}
} // End - MainTabFragment1BindViewHolder
// Start - OnItemListener
fun setOnClickItemListenerMainTabFragment1(onItemClickListener: OnItemClickListener) {
this.onSelectedListenerMainTabFragment1 = onItemClickListener
} // End - OnItemListener
} // End - Class
MainTabFragment1Model.kt
data class MainTabFragment1Model
(var imgURLMainTabFragment1: String?,
var titleTextMainTabFragment1: String?,
var descTextMainTabFragment1: String?,
val btnURLMainTabFragment1: String?)
Listener.kt
interface OnItemClickListener {
fun onItemClick(item: View, position:Int)
}
WebViewActivity.kt
class WebViewActivity : AppCompatActivity() {
private lateinit var webView: WebView // Initialize WebView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_webview)
// Start - Assign Open New URL
val wBS = intent
val webSite = wBS.getStringExtra("btnURLMainTabFragment1")
// End - Assign Open New URL
// Start - full screen
val window = window
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
) // End - full screen
// Start - WebView
webView = findViewById(R.id.wv)
webView.setWebViewClient(object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
view?.visibility = View.INVISIBLE
if (Build.VERSION.SDK_INT >= 19) {
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null)
} else {
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
}
}
override fun onPageFinished(view: WebView?, url: String?) {
swipe?.isRefreshing = false
super.onPageFinished(view, url)
view?.visibility = View.VISIBLE
}
// Start - Fix Whatsapp Acces
override fun shouldOverrideUrlLoading(wv: WebView, url: String): Boolean {
if (url.startsWith("tel:") || url.startsWith("whatsapp:")) {
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse(url)
startActivity(intent)
webView.goBack()
return true
}
return false
} // End - Fix Whatsapp Acces
}) // End - WebView
refreshApp() // SetUp SwipeRefresh
// Start - WebView Setting
if (webSite != null) {
webView.loadUrl(webSite)
}
val webSettings = webView.settings
webSettings.javaScriptEnabled = true // js active
webSettings.domStorageEnabled = true // componenet load
webSettings.allowContentAccess = true
webSettings.loadsImagesAutomatically = true
webSettings.cacheMode = WebSettings.LOAD_NO_CACHE
webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH)
webSettings.setEnableSmoothTransition(true)
// End - WebView Setting
}// End -OnCreate
// Start - BackPressed CurrentView
override fun onBackPressed() {
if (webView.canGoBack()) {
webView.goBack()
} else
super.onBackPressed()
} // End - BackPressed CurrentView
// Start - SwipeRefresh
private fun refreshApp() {
swipe.setOnRefreshListener {
webView?.reload()
Toast.makeText(this, "Refresh!", Toast.LENGTH_SHORT).show()
}
} // End- SwipeRefresh
} // finish MainActivity
I know there must be something wrong in my "DetailsActivity.kt",
especially on this line :
prodBundle?.getString("btnURLMainTabFragment1").let {
btn_wvURL.setOnClickListener {
val gotoWebView = Intent(this#DetailsActivity, WebViewActivity::class.java)
gotoWebView.putExtra("btnURLMainTabFragment1", gotoWebView)
startActivity(gotoWebView)
}
How to solve it?
I hope someone can solve this case. And thanks for taking your time.
Here you are sending the intent as an extra to the intent itself:
val gotoWebView = Intent(this#DetailsActivity, WebViewActivity::class.java)
>>> gotoWebView.putExtra("btnURLMainTabFragment1", gotoWebView)
You can try:
prodBundle?.getString("btnURLMainTabFragment1")?.let { url->
btn_wvURL.setOnClickListener {
val gotoWebView = Intent(this#DetailsActivity, WebViewActivity::class.java)
gotoWebView.putExtra("btnURLMainTabFragment1", url)
startActivity(gotoWebView)
}
This should work.

Kotlin - lateinit property fragmentHomeBinding has not been initialized

I am working on a kotlin application that contains fragments. I am converting an app I created using activity to fragments but I am having an issue. I get an error when running the app that the property fragmentHomeBinding has not been initialized and the app closes.
Here's the fragment Home.kt
class Home : Fragment() {
private lateinit var fusedLocationProviderClient: FusedLocationProviderClient
private lateinit var fragmentHomeBinding: FragmentHomeBinding
#SuppressLint("WrongViewCast")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
getCurrentLocation()
fragmentHomeBinding.etGetCityName.setOnEditorActionListener { v, actionId, keyEvent ->
if(actionId == EditorInfo.IME_ACTION_SEARCH)
{
getCityWeather(fragmentHomeBinding.etGetCityName.text.toString())
val view = activity?.currentFocus
if(view!=null)
{
val imm:InputMethodManager=
activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(view.windowToken, 0)
fragmentHomeBinding.etGetCityName.clearFocus()
}
true
}
else false
}
}
private fun getCityWeather(cityName:String)
{
fragmentHomeBinding.pbLoading.visibility = View.VISIBLE
ApiUtilities.getApiInterface()?.getCityWeatherData(cityName, API_KEY)?.enqueue(
object:Callback<ModelClass>{
override fun onResponse(call: Call<ModelClass>, response: Response<ModelClass>) {
setDataOnViews((response.body()))
}
override fun onFailure(call: Call<ModelClass>, t: Throwable) {
Toast.makeText(activity?.applicationContext, "Wrong City", Toast.LENGTH_SHORT).show()
}
})
}
private fun getCurrentLocation()
{
if(checkPermission())
{
if(isLocationEnabled())
{
if(ActivityCompat.checkSelfPermission(
requireActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
requireActivity(),
android.Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
){
requestPermission()
return
}
fusedLocationProviderClient.lastLocation.addOnCompleteListener(requireActivity()){ task->
val location: Location?=task.result
if(location==null)
{
fetchCurrentLocationWeather(23.76137119142536.toString(), 90.35059989467042.toString())
}
else
{
fetchCurrentLocationWeather(location.latitude.toString(),location.longitude.toString())
}
}
}
else
{
Toast.makeText(activity?.applicationContext, "Turn on Location", Toast.LENGTH_SHORT).show()
val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivity(intent)
}
}
}
private fun fetchCurrentLocationWeather(latitude: String, longitude:String)
{
fragmentHomeBinding.pbLoading.visibility = View.VISIBLE
ApiUtilities.getApiInterface()?.getCurrentWeatherData(latitude, longitude, API_KEY)?.enqueue(
object : Callback<ModelClass> {
override fun onResponse(call: Call<ModelClass>, response: Response<ModelClass>) {
if(response.isSuccessful)
{
setDataOnViews(response.body())
}
}
override fun onFailure(call: Call<ModelClass>, t: Throwable) {
Toast.makeText(activity?.applicationContext, "ERROR", Toast.LENGTH_SHORT).show()
}
})
}
private fun setDataOnViews(body: ModelClass?) {
val sdf = SimpleDateFormat("dd/MM/yyyy hh:mm")
val currentDate = sdf.format(Date())
fragmentHomeBinding.tvDateTime.text = currentDate
fragmentHomeBinding.tvDayMaxTemp.text = ""+kelvinToCelsius(body!!.main.temp_max) + "°"
fragmentHomeBinding.tvDayMinTemp.text = ""+kelvinToCelsius(body!!.main.temp_min) + "°"
fragmentHomeBinding.tvTemp.text = ""+kelvinToCelsius(body!!.main.temp)
fragmentHomeBinding.tvFeelsLike.text = "Feels like: "+kelvinToCelsius(body!!.main.feels_like) + "°"
fragmentHomeBinding.tvWeatherType.text = body.weather[0].main
fragmentHomeBinding.tvPressure.text = body.main.pressure.toString()
fragmentHomeBinding.tvHumidity.text = body.main.humidity.toString() + " %"
fragmentHomeBinding.tvWindSpeed.text = body.wind.speed.toString() + " m/s"
fragmentHomeBinding.tvCityName.text = body.name
updateUI(body.weather[0].id)
}
private fun updateUI(id: Int) {
fragmentHomeBinding.pbLoading.visibility = View.GONE
fragmentHomeBinding.mainLayout.visibility = View.VISIBLE
}
private fun kelvinToCelsius(temp: Double): Double
{
var intTemp = temp
intTemp = intTemp.minus(273)
return intTemp.toBigDecimal().setScale(1, RoundingMode.UP).toDouble()
}
companion object
{
const val PERMISSION_REQUEST_ACCESS_LOCATION = 100
const val API_KEY = "3c709ccaf2730aa1c263925f75db631a"
}
private fun isLocationEnabled():Boolean{
val locationManager:LocationManager=activity?.getSystemService(Context.LOCATION_SERVICE) as LocationManager
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(
LocationManager.NETWORK_PROVIDER
)
}
private fun requestPermission(){
ActivityCompat.requestPermissions(
requireActivity(), arrayOf(android.Manifest.permission.ACCESS_COARSE_LOCATION,
android.Manifest.permission.ACCESS_FINE_LOCATION),
PERMISSION_REQUEST_ACCESS_LOCATION
)
}
private fun checkPermission():Boolean{
if(ActivityCompat.checkSelfPermission(requireActivity(),
android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(requireActivity(),
android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
{
return true
}
return false
}
#Suppress("DEPRECATION")
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if(requestCode== PERMISSION_REQUEST_ACCESS_LOCATION)
{
if(grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(activity?.applicationContext, "Granted", Toast.LENGTH_SHORT).show()
getCurrentLocation()
}
else{
Toast.makeText(activity?.applicationContext, "Denied", Toast.LENGTH_SHORT).show()
}
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
fragmentHomeBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
// Inflate the layout for this fragment
return fragmentHomeBinding.root
}
}
Here's the error that shows up on logcat:
2022-05-20 17:45:20.582 22026-22048/com.example.weather D/EGL_emulation: app_time_stats: avg=30.74ms min=18.05ms max=34.54ms count=33
2022-05-20 17:45:21.416 22026-22026/com.example.weather D/AndroidRuntime: Shutting down VM
2022-05-20 17:45:21.417 22026-22026/com.example.weather E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.weather, PID: 22026
kotlin.UninitializedPropertyAccessException: lateinit property fragmentHomeBinding has not been initialized
at com.example.weather.Home.onCreate(Home.kt:58)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2949)
at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:475)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:278)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2100)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3138)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:3072)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:251)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:502)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:246)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1455)
at android.app.Activity.performStart(Activity.java:8076)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3660)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7839)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
2022-05-20 17:45:21.435 22026-22026/com.example.weather I/Process: Sending signal. PID: 22026 SIG: 9
Help's appreciated, thanks.
Your Fragment viewbinding instance fragmentHomeBinding is initialised at onCreateView() life cycle method. But you are accessing at onCreate() lifecycle method. In Fragment lifecycle, onCreate() will be called before onCreatedView().
As a result you are accessing an object which is not initialised.
To resolve the issue, move your viewbinding reference code in onCreate() to onCreateView() as below.
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
fragmentHomeBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
fragmentHomeBinding.etGetCityName.setOnEditorActionListener { v, actionId, keyEvent ->
if(actionId == EditorInfo.IME_ACTION_SEARCH)
{
getCityWeather(fragmentHomeBinding.etGetCityName.text.toString())
val view = activity?.currentFocus
if(view!=null)
{
val imm:InputMethodManager=
activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(view.windowToken, 0)
fragmentHomeBinding.etGetCityName.clearFocus()
}
true
}
else false
}
// Inflate the layout for this fragment
return fragmentHomeBinding.root
}

i want to add next page (every page is 10) to my recyclerview but it delet my last page

my recyclerview fragment:
this is the fragment that I set my recycler view , I want when touch the continue button (btn_continue) add the rest of the list, which is actually the next page, to my list when I click the button
But it deletes the previous list and displays the new list
and i use the kotlin coruotine, viewmodel and recyclerview
class AllUnpublishedAdsFragment : Fragment() {
lateinit var unpublishedAdsAdapter: UnpublishedAdsAdapter
var items = ArrayList<M_Ads>()
lateinit var loadMoreItems: ArrayList<M_Ads>
lateinit var scrollListener: RecyclerViewLoadMoreScroll
lateinit var mLayoutManager: RecyclerView.LayoutManager
val page = "1"
var newpage = page.toInt()
var navController: NavController? = null
lateinit var btn_continue: Button
private lateinit var viewModel: MainViewmodels
lateinit var token: String
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_all_unpublished_ads, container,
false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btn_continue = view.findViewById<Button>(R.id.btn_continueAds)
token = arguments?.getString(TOKEN_KEY).toString()
Log.i("TOKEN", token)
setupViewModel(token, page)
continueAds()
unpublishedAdsAdapter.itemClickListener = { item, position ->
val id = item.id
val bundle_id = Bundle()
bundle_id.putString(ID_KEY, id.toString())
navController = Navigation.findNavController(view)
//view.findNavController().navigate(R.id.action_UnpublishedAds_to_Detail,
bundle_id)
navController!!.navigate(
R.id.action_allUnpublishedAdsFragment_to_adsDetailFragment,
bundle_id
)
}
}
private fun setupViewModel(token: String, page: String) {
LoadingDialog.show(requireContext(), { ld ->
recy_unpublished_ads.layoutManager = LinearLayoutManager(activity)
val decoration = DividerItemDecoration(activity, DividerItemDecoration.VERTICAL)
recy_unpublished_ads.addItemDecoration(decoration)
viewModel = ViewModelProvider(this).get(MainViewmodels::class.java)
unpublishedAdsAdapter = UnpublishedAdsAdapter()
recy_unpublished_ads.adapter = unpublishedAdsAdapter
viewModel.adsListObserve().observe({ lifecycle }, { model ->
items.clear()
items.addAll(model.adsList!!)
unpublishedAdsAdapter.setUpdateData(items)
ld.dismiss()
btn_continue.visibility = View.VISIBLE
})
viewModel.getAdsList(token, page)
})
}
fun continueAds() {
var isTouched=false
btn_continue.setOnClickListener {
isTouched=true
newpage = newpage + 1
Log.i("CONTINUE", newpage.toString())
setupViewModel(token, newpage.toString())
unpublishedAdsAdapter.notifyDataSetChanged()
isTouched=false
}
}
RetrofitInstance class
class RetrofitInstance {
companion object{
fun getRetrofitInstance (): Retrofit{
// val interceptor = HttpLoggingInterceptor()
// interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
// val client: OkHttpClient = OkHttpClient.Builder().addInterceptor(interceptor).build()
val okHttpClient: OkHttpClient = OkHttpClient.Builder()
.readTimeout(60, TimeUnit.SECONDS)
.connectTimeout(60, TimeUnit.SECONDS)
.build()
return Retrofit.Builder()
.baseUrl(BASEURL)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build()
}
}
}
my adapter:
class UnpublishedAdsAdapter : RecyclerView.Adapter<UnpublishedAdsAdapter.MyViewHolder>() {
var items = ArrayList<M_Ads>()
var itemClickListener: ((item: M_Ads, position: Int) -> Unit)? = null
lateinit var mcontext: Context
class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
class LoadingViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
fun setUpdateData(items: ArrayList<M_Ads>) {
this.items = items
notifyDataSetChanged()
}
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val img_ads = view.findViewById<ImageView>(R.id.img_recy_ads)
val txt_title = view.findViewById<TextView>(R.id.txt_recy_ads_title)
val txt_accountType = view.findViewById<TextView>(R.id.txt_recy_ads_acctype)
fun bind(data: M_Ads) {
txt_title.setText(data.title)
txt_accountType.setText(data.accountType)
if (!data.image1.equals("")) {
Picasso.with(img_ads.context).load(data.image1).into(img_ads)
} else {
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
mcontext = parent.context
return if (viewType == Constant.VIEW_TYPE_ITEM) {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.row_recy_unpublished_ads, parent, false)
MyViewHolder(view)
} else {
val view =
LayoutInflater.from(mcontext).inflate(R.layout.progress_loading, parent, false)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
view.progressbar.indeterminateDrawable.colorFilter =
BlendModeColorFilter(Color.WHITE, BlendMode.SRC_ATOP)
} else {
view.progressbar.indeterminateDrawable.setColorFilter(
Color.WHITE,
PorterDuff.Mode.MULTIPLY
)
}
MyViewHolder(view)
}
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.bind(items.get(position))
handleClick(holder)
}
fun handleClick(holder: UnpublishedAdsAdapter.MyViewHolder) {
holder.itemView.setOnClickListener {
val position = holder.adapterPosition
itemClickListener?.invoke(items.get(position), position)
}
}
override fun getItemCount(): Int {
return items.size
}
my Viewmodel:
class MainViewmodels:ViewModel() {
lateinit var getAds:MutableLiveData<Main_ModelAds>
init {
getAds= MutableLiveData<Main_ModelAds>()
}
fun adsListObserve():MutableLiveData<Main_ModelAds>{
return getAds
}
fun getAdsList(token:String,page:String){
viewModelScope.launch(Dispatchers.IO) {
try {
Log.i("ERRORRES",token + "")
val retrofitInstance=RetrofitInstance.getRetrofitInstance().create(RetrofitService::class.java)
val response=retrofitInstance.unPublishedAdsList(token,page)
getAds.postValue(response)
}catch (ex:Exception){
Log.i("ERRORRES", ex.message.toString() + "")
}
}
}
What you want here is to update the list that you are showing when the user clicks the button.
In this case you should use ListAdapter.
You can refer to this article for implementation:
https://developer.android.com/reference/androidx/recyclerview/widget/ListAdapter

How to call a method of a fragment from adapter class?

I have seen many questions like this but they are not the same as my situation and I couldn't use those solutions.
I have a fragment (OrdersByStatusFragment.kt) and the method I want to call from the adapter is getOrderStatusList()
class OrdersByStatusFragment : BaseFragment() {
private lateinit var binding: OrderStatusLayoutBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_orders_by_status, container, false)
}
override fun onResume() {
super.onResume()
getOrderStatusList()
}
fun getOrderStatusList() {
showProgressDialog(resources.getString(R.string.please_wait))
FirestoreClass().getOrderStatusList(this#OrdersByStatusFragment)
}
fun successOrderStatusList(orderStatusList: ArrayList<OrderStatus>) {
hideProgressDialog()
if (orderStatusList.size > 0) {
rv_order_by_status.visibility = View.VISIBLE
tv_no_orders_by_status_found.visibility = View.GONE
rv_order_by_status.layoutManager = LinearLayoutManager(activity)
rv_order_by_status.setHasFixedSize(true)
val orderStatusListAdapter =
OrderStatusListAdapter(requireActivity(), orderStatusList)
rv_order_by_status.adapter = orderStatusListAdapter
} else {
rv_order_by_status.visibility = View.GONE
tv_no_orders_by_status_found.visibility = View.VISIBLE
}
}
fun successNewOrderStatus() {
Toast.makeText(requireContext(), "Success", Toast.LENGTH_SHORT).show()
}
}
Adapter OrderStatusListAdapter.kt
open class OrderStatusListAdapter(
private val context: Context,
private var list: ArrayList<OrderStatus>,
) : RecyclerView.Adapter<OrderStatusListAdapter.MyViewHolder>() {
class MyViewHolder(var binding: OrderStatusLayoutBinding) :
RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(
OrderStatusLayoutBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val model = list[position]
if (true) {
GlideLoader(context).loadProductPicture(
model.image,
holder.itemView.iv_order_status_item_image
)
val dateFormat = "dd MMM yyyy HH:mm"
val formatter = SimpleDateFormat(dateFormat, Locale.getDefault())
val calendar: Calendar = Calendar.getInstance()
calendar.timeInMillis = model.order_datetime
val orderDateTime = formatter.format(calendar.time)
holder.itemView.tv_order_status_order_date.text = orderDateTime
holder.itemView.tv_order_status_item_name.text = model.items[0].title
holder.itemView.tv_order_status_item_price.text = "$${model.total_amount}"
holder.itemView.tv_order_status.text = model.order_status
holder.itemView.tv_order_status_order_id.text = model.id
holder.binding.spnOrderChangeStatus.onItemSelectedListener =
object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
holder.binding.tvSpinnerValue.text =
parent?.getItemAtPosition(position).toString()
}
override fun onNothingSelected(parent: AdapterView<*>?) {
}
}
holder.binding.btnOrderStatusChangeStatus.setOnClickListener {
Toast.makeText(context, "Button Clicked", Toast.LENGTH_SHORT).show()
FirestoreClass().updateOrderStatus(
model.id,
holder.binding.tvSpinnerValue.text.toString()
)
Toast.makeText(context, "DB Updated", Toast.LENGTH_SHORT).show()
}
holder.itemView.ib_order_status_delete_product.visibility = View.GONE
holder.itemView.setOnClickListener {
val intent = Intent(context, SoldProductDetailsActivity::class.java)
intent.putExtra(Constants.EXTRA_SOLD_PRODUCT_DETAILS, model)
context.startActivity(intent)
}
}
}
}
As you can see the fun getOrderStatusList() in the OrdersByStatusFragment.kt is actually calling a method in the FirestoreClass.kt. Following is the getOrderStatusList() in the FirestoreClass.kt
fun getOrderStatusList(fragment: OrdersByStatusFragment) {
mFireStore.collection(Constants.ORDERS)
.whereIn("order_status", listOf("Pending", "In process"))
.get()
.addOnSuccessListener { document ->
val list: ArrayList<OrderStatus> = ArrayList()
for (i in document.documents) {
val orderStatus = i.toObject(OrderStatus::class.java)!!
orderStatus.id = i.id
list.add(orderStatus)
}
fragment.successOrderStatusList(list)
}
.addOnFailureListener {
fragment.hideProgressDialog()
}
}
The way I solved something like this is to pass a reference to the method into the adapter's constructor, then you can call the method in the adapter.
See kotlin-how-to-pass-a-function-as-parameter-to-another
In general, the link shows a class containing a method called buz.
Let's say your adapter has a constructor like:
class MyAdapter (private val context: Context, val buzz: () -> Unit) : RecyclerView.Adapter<RecyclerView.ViewHolder>()
then you can create the adapter like
MyAdapter(applicationContext, ::buz)
In the adapter the method can be called normally:
buzz()