Jetpack Compose Material date range picker [duplicate] - android-studio

I want to open datePicker dialog on a button click in Jetpack compose.
For that, I am using the below code inside the button's onClick action.
val context = LocalContext.current
Button(onClick = {
(context as AppCompatActivity).let {
val picker = MaterialDatePicker.Builder.datePicker().build()
picker.show(it.supportFragmentManager, picker.toString())
picker.addOnPositiveButtonClickListener {
// some code
}
}
})
If I am using the ComponentActivity, supportFragmentManager is not supported.
Is it fine to extend the activity from AppCompatActivity?
Or is there any other way, I can get the solution if the above-mentioned solution is not correct?

You can use the AppCompatActivity since it extends FragmentActivity which extends ComponentActivity.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val activity = LocalContext.current as AppCompatActivity
Button(onClick={ showDatePicker(activity)}){
Text("Picker")
}
}
}
}
fun showDatePicker(activity: AppCompatActivity){
val picker = MaterialDatePicker.Builder.datePicker().build()
activity?.let {
picker.show(it.supportFragmentManager, picker.toString())
picker.addOnPositiveButtonClickListener {
}
}
}
Note: it requires at least the AppCompat 1.3.0 version.

Related

Problems with SmartToolbar not recreating fragments

I'm having a problem with this SmartToolbar, if I open the app and click on the chat or book icon it opens perfectly and shows the fragments, but if I click on another icon to open another fragment, when I go back to them they don't show more The fragments that should be on the smartToolbar, as shown in the prints below, bug everything! I need to help on this as soon as possible !!!
[Opens normally When I click on another item and go back to it, it no longer opens the SmartToolbar fragmentshere]2
enter image description here
I will send the homeAcitivity code, where is the layout that opens the fragments of the buttonNavigationBar
class HomeActivity : AppCompatActivity() {
var MY_ACCOUNT = 1
var LIBRARY = 2
var HOME = 3
var CHAT = 4
var SETTINGS = 5
private var Content: ConstraintLayout? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportActionBar!!.hide()
nav.show(HOME)
nav.setBackgroundColor(Color.TRANSPARENT)
abrirHome()
addOnMeowNavigattionBarIcons()
addOnNotificationInform()
chamarFragments()
}
fun abrirHome() {
val fragment = HomeFragment.newInstance()
addFragment(fragment)
}
fun addOnMeowNavigattionBarIcons() {
nav.add(MeowBottomNavigation.Model(MY_ACCOUNT, R.drawable.ic_baseline_account_circle_24))
nav.add(MeowBottomNavigation.Model(LIBRARY, R.drawable.ic_baseline_menu_book_24))
nav.add(MeowBottomNavigation.Model(HOME, R.drawable.ic_baseline_home_24))
nav.add(MeowBottomNavigation.Model(CHAT, R.drawable.ic_baseline_chat_24))
nav.add(MeowBottomNavigation.Model(SETTINGS, R.drawable.ic_baseline_settings_24))
}
fun addOnNotificationInform() {
nav.setCount(CHAT, "99")
}
fun chamarFragments() {
nav.setOnClickMenuListener {
when (it.id) {
HOME -> {
val fragment = HomeFragment.newInstance()
addFragment(fragment)
}
MY_ACCOUNT -> {
val fragment = MyAccountFragment.newInstance()
addFragment(fragment)
}
LIBRARY -> {
val fragment = LibraryFragment.newInstance()
addFragment(fragment)
}
CHAT -> {
val fragment = ChatFragment.newInstance()
addFragment(fragment)
}
SETTINGS -> {
val fragment = SettingsFragment.newInstance()
addFragment(fragment)
}
}
}
}
private fun addFragment(fragment: Fragment) {
supportFragmentManager
.beginTransaction()
.replace(R.id.parentfragments,fragment,fragment.javaClass.simpleName)
.addToBackStack(null)
.commit()
}
fun sair(view: View){
FirebaseAuth.getInstance().signOut()
val bundle = ActivityOptions.makeSceneTransitionAnimation(this).toBundle()
val intent = Intent(this, login::class.java)
startActivity(intent,bundle)
}
}
This is the code of the fragment Library that has a SmartToolbar that calls two more fragments within it, MyLibrary and Store
class LibraryFragment: Fragment() {
companion object{
fun newInstance():LibraryFragment {
val args = Bundle()
val fragment = LibraryFragment()
fragment.arguments = args
return fragment
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return inflater.inflate(R.layout.library_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val adapter = FragmentPagerItemAdapter(
fragmentManager, FragmentPagerItems.with(context)
.add("Minha Bilioteca", MyLibraryFragment::class.java)
.add("Loja", StoreFragment::class.java)
.create())
viewpager.adapter = adapter
viewpagertab.setViewPager(viewpager)
}
}
And this is the MyLibrary fragment that is shown inside the Library that is shown inside HomeActivity
class MyLibraryFragment: Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.mylibrary_fragment, container, false)
}
}

Make a TabBar inside a specific NavBar fragment

my app use bottomNavBar with 3 fragments [Settings / Home / Gallery].
Now I'm trying to make a TabBar with 3 new Tabs inside of "Settings". [setting01 / setting02 / setting03]
I followed carefully this tutorial : https://www.youtube.com/watch?v=qfFANw7nPMU
and I used viewPager2 when the video uses viewPager.
but I'm still stuck in MainActivity.kt because for some reasons these two line (from the tutorial) didn't work for me :
viewPager2.adapter = PageAdapter(supportFragmentManager)
tabLayout.setupWithViewPager(viewPager2)
here is my entire MainActivity.kt file :
package com.example.appname
import android.os.Bundle
import com.google.android.material.bottomnavigation.BottomNavigationView
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.example.appname.ui.settings.PageAdapter
import kotlinx.android.synthetic.main.fragment_settings.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navView: BottomNavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
val appBarConfiguration = AppBarConfiguration(setOf(
R.id.navigation_settings, R.id.navigation_swapper, R.id.navigation_gallery))
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
viewPager2.adapter = PageAdapter(supportFragmentManager)
tabLayout.setupWithViewPager(viewPager2)
}
}
I'm almost certain that this error exists because these two lines should be somewhere else because of the particular situation of my application.
To find yourself in a situation similar to mine I recommend you to start a new project under android studio using the template "Bottom Navigation Activity" and then follow the tutorial.
A friend of mine give me the solution.
Nothing new in MainActivity.kt like I was thinking.
Here is the new code to make tabBar in the Settings fragment :
settingFragment.kt
class SettingsFragmentAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {
private val fragments =
listOf(
fragment_setting_teams(),
fragment_setting_general(),
fragment_setting_movies()
)
override fun getItemCount(): Int = fragments.size
override fun createFragment(position: Int): Fragment = fragments[position]
}
class SettingsFragment : Fragment() {
private lateinit var settingsViewModel: SettingsViewModel
private lateinit var settingsAdapter: SettingsFragmentAdapter
private lateinit var viewPager: ViewPager2
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val tabLayout = view.findViewById<TabLayout>(R.id.tabLayout)
settingsAdapter =
SettingsFragmentAdapter(
this
)
viewPager = view.findViewById(R.id.viewPager2)
viewPager.adapter = settingsAdapter
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
when (position) {
0 -> tab.text = "Teams"
1 -> tab.text = "General"
2 -> tab.text = "Movies"
}
}.attach()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
settingsViewModel =
ViewModelProviders.of(this).get(SettingsViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_settings, container, false)
return root
}
}

How to pass string from activity to another activity in kotlin

I am trying to pass over a text to my second activity but it does not seem to be working correctly.
For my main activity i have a a textview and the text says 'Cat'. When the image on the first activity is pressed on, I want "Cat" to be passed over to the second activity. The second activity's textview should also display "Cat", however when I do this, it will show up as "Info(name=Cat)" rather then just "Cat".
I am not sure where i went wrong.
This is my main activity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val image = findViewById<ImageView>(R.id.imageView)
val text = findViewById<TextView>(R.id.textView)
image.setOnClickListener {
val intent= Intent(this, MainActivity2::class.java).apply {
putExtra("name", Info("Cat"))
}
startActivity(intent)
}
}
}
My parcelable class
#Parcelize
data class Info(val name : String) : Parcelable {
}
This is my second activity
class MainActivity2 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
val info = intent.getParcelableExtra<Info>("name")
val name = findViewById<TextView>(R.id.textView2)
name.text = info.toString()
}
}
You're converting the whole Info data class to its string representation. You only want the name property from the data class.
name.text = info.name

Error when calling the second activity using a button

I have a problem calling a second activity using a password recovery button. I get the app stopped.
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
fun goToRecover(view: View) {
val intent = Intent(this,RecoverPasswordActivity::class.java)
this.startActivity(intent)
}
}
Did you try adding the onClick in the XML-layout like this?
android:onClick="/*your method name*/"
If so, make sure that there are no typos. In your case it would probably be:
android:onClick="addOne"
OR
You can also listen for the click events programmatically. like below:
set the Button in OnCreate method:
var goToRecoverBtn = findViewById(R.id./*id name here*/)
after that add the ClickListener to the goToRecoverBtn:
goToRecoverBtn.setOnClickListener{
// do anything whatever you want
}
OR
MainActivity code looks like below
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var goToRecoverBtn = findViewById(R.id./*id name here*/)
goToRecoverBtn.setOnClickListener{
val intent = Intent(this#MainActivity, RecoverPasswordActivity::class.java)
startActivity(intent)
}
}
}
BTW could you please show us your .xml file?

Can I Inject activity's viewmodel and use It inside Dialog Fragment

I am trying to Inject activity's view model and I want use it inside Dialog Fragment, how to inject it with Kodein? and use the view model which I've inject before in other activity or fragments.
I've try tutorial from medium here is the tutorial
https://proandroiddev.com/android-viewmodel-dependency-injection-with-kodein-249f80f083c9
I am trying to access injection result from activity's view model
but when I try access some object inside the viewModel from Dialog Fragment the value is null not the same with activity's viewModel
// This is from Activity
private val viewModelFactory: TriplogisticViewModelFactory by instance()
private val viewModel: TriplogisticViewModel by lazy {
ViewModelProviders
.of(this#ContactDetailBottomSheetDialogFragment, viewModelFactory)
.get(TriplogisticViewModel::class.java)
}
Log.e("VIEWMODEL_ACTIVITY", viewModel.mode.get().toString) // result is SENDER_MODE
I am expecting when I access some object inside the dialog fragment's viewModel, I got same value as activity's viewModel
// This is from Dialog Fragment
private val viewModelFactory: TriplogisticViewModelFactory by instance()
private val viewModel: TriplogisticViewModel by lazy {
ViewModelProviders
.of(this#ContactDetailBottomSheetDialogFragment, viewModelFactory)
.get(TriplogisticViewModel::class.java)
}
I want same result as activity's viewModel object but I got null result
Log.e("VIEWMODEL_FRAGMENT", viewModel.mode.get().toString) // result is null
You have to use shared ViewModel. Use activity owner for instantiating the ViewModel. Looks like:
class SharedViewModel : ViewModel() {
val selected = MutableLiveData<Item>()
fun select(item: Item) {
selected.value = item
}
}
class MasterFragment : Fragment() {
private lateinit var itemSelector: Selector
private lateinit var model: SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
model = activity?.run {
ViewModelProviders.of(this)[SharedViewModel::class.java]
} ?: throw Exception("Invalid Activity")
itemSelector.setOnClickListener { item ->
// Update the UI
}
}
}
class DetailFragment : Fragment() {
private lateinit var model: SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
model = activity?.run {
ViewModelProviders.of(this)[SharedViewModel::class.java]
} ?: throw Exception("Invalid Activity")
model.selected.observe(this, Observer<Item> { item ->
// Update the UI
})
}
}
For details click here

Resources