I'm currently trying to open an AlertDialog where some data will be displayed inside it.
class AlertsDialogRemi : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.alerts_dialog, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val alerts = arrayOf("AlertsDialogRemi 1", "AlertsDialogRemi 2", "AlertsDialogRemi 3")
for(alert in alerts){
Log.i(TAG, "Alert : $alert")
}}
And I call it from this (MainActivity):
fun showDialog(){
mydialog = Dialog(this, R.style.DialogCustomTheme)
mydialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
mydialog.setContentView(R.layout.alerts_dialog_remi)
mydialog.create()
txt = mydialog.findViewById(R.id.close_modal_alerte)
txt.isEnabled = true
txt.setOnClickListener{
mydialog.cancel()
}
mydialog.show()
}
When I open the fragment as a real fragment, I can my alerts. But when I open it as a Dialog, I don't see the alerts (but I have the layout displayed)
How can I get my alerts inside my AlertDialog (as a Dialog thanks to showDialog())?
This dialog has nothing to do with the AlertsDialogRemi class.
Declare the setOnShowListener for the dialog, before mydialog.show(), and put the code you want to execute when the dialog is shown inside the lambda:
mydialog.setOnShowListener {
//write your code here
}
setOnShowListener
public void setOnShowListener(DialogInterface.OnShowListener listener)
Sets a listener invoked when the dialog is shown.
Related
Code:
class ProfileFragment : Fragment() {
lateinit var ProfileSetting : ImageView
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
var view = inflater.inflate(R.layout.fragment_profile, container, false)
ProfileSetting = view.findViewById(R.id.imgProfileSetting)
return view
}
}
Clicking the button doesn't switch the page in app.
imgProfileSetting is button.
Your Button does not have any ClickListener, implement it :
ProfileSetting.setOnClickListener {
//Do your stuff
}
I have been trying to figure this out for a bit now. I see a lot of developers and youtubers (tutorials) saying that we should use as little activities as possible in order for a faster, more efficient and less resource heavy code/app. I was wondering if there is a way to create a Log-in and Sign-up using only the MainActivity for both Log-in and Sign-Up in combination with fragments for navigation between them.
Or
Do we need atleast 2 or more activities to handle that process ( Log-in & Sign-Up )?
Example: 1 activity for log-in and 1 activity for sign-up.
Appreciate and welcome any answers regarding this topic!
Theoretically, you could have your entire application run on a single Activity and use Fragments for all of the pages.
Each fragment has its own lifecycle within the activity.
MainActivity can look like this
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
loadFragment(2)
}
public fun loadFragment(page: Int){
if(page == 1){
// load login
val manager = supportFragmentManager.beginTransaction()
manager.replace(R.id.fragment_holder, LoginFragment()).commit()
}else{
// load register
val manager = supportFragmentManager.beginTransaction()
manager.replace(R.id.fragment_holder, LoginFragment()).commit()
}
}
}
LoginFragment can look like this
class LoginFragment : Fragment() {
lateinit var myButton: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_login, container, false)
myButton = view.findViewById(R.id.my_button)
myButton.apply {
setOnClickListener { toRegister() }
}
return view;
}
fun toRegister(){
// replace the fragment in main activity with register fragment
(requireActivity() as MainActivity).loadFragment(1)
}
}
RegisterFragment can look like this
class RegisterFragment : Fragment() {
lateinit var mButton: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_register, container, false)
mButton = view.findViewById(R.id.my_button)
mButton.apply {
setOnClickListener { toLogin() }
}
return view;
}
fun toLogin(){
// replacing the fragment in the main activity with the login fragment
(requireActivity() as MainActivity).loadFragment(1)
}
}
Basically, we replace the fragment displayed in the activity by calling loadfragment.
This logic can be applied to as many fragments as is necessary.
Im new in programming, and i got stuck with adding onClickListener in my FragmentHome.kt
i added this code to my existing activity:
val exc = this.findViewById<Button>(R.id.execute)
exc.setOnClickListener {
Toast.makeText(this, "You clicked me.", Toast.LENGTH_SHORT).show()
}
I tried set onClicklistener on a blank activity and it worked, but when i added it to an existing
Fragment activity it does nothing (it should display a toast with some text)
I see no error messages so i don't know where the problem could be.
Thank you for your responses.
enter code here
public class FragmentHome : Fragment() {
public class HomeFragmentElements : AppCompatActivity() {
private lateinit var spinView: Spinner
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.fragment_home)
val exc = this.findViewById<Button>(R.id.execute)
exc.setOnClickListener {
Toast.makeText(this, "You clicked me.", Toast.LENGTH_SHORT).show()
}
spinView = findViewById(R.id.spinner)
spinView.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
TODO("Not yet implemented")
}
override fun onNothingSelected(parent: AdapterView<*>?) {
TODO("Not yet implemented")
}
}
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home, container, false)
}
}
enter code here
Try to put your code into "onViewCreated":
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val exc = this.findViewById<Button>(R.id.execute)
exc.setOnClickListener {
Toast.makeText(this, "You clicked me.", Toast.LENGTH_SHORT).show()
}
}
onViewCreated is executed after "onCreateView". View bindings and initializations should be into onViewCreated
change the following in your onCreateView
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view: View = inflater.inflate(R.layout.fragment_home, container, false)
collectId(view)
return view
}
fun collectId(view: view){
val exc = view.findViewById<Button>(R.id.execute)
exc.setOnClickListener {
Toast.makeText(this, "You clicked me.", Toast.LENGTH_SHORT).show()
}
}
You can consider viewBinding instead of findViewById
It looks like you have defined an AppCompatActivity subclass inside your Fragment class's definition, kind of like this:
class MyFragment: Fragment {
class MyActivity: AppCompatActivity() {
//...
}
}
The ability to define a non-inner class in a nested way is purely a code organization tool. There is absolutely no connection between your Fragment and Activity classes here. The code above is no different than if you did this, with each class in a completely different file:
class MyFragment: Fragment {
}
class MyActivity: AppCompatActivity() {
}
It also doesn't make sense to think of an Activity as a child of a Fragment. A Fragment is a piece of an Activity, so it's the other way around.
All the code that you have in this Activity's onCreate should be put in the Fragment's onViewCreated() function, except for the call to setContentView(), because that's what your overriding of onCreateView() does. And remove the unused nested Activity class.
Also, you don't need to override onCreateView if you're simply inflating a layout and returning it. You can put the layout directly in the super-constructor call like this:
public class FragmentHome : Fragment(R.layout.fragment_home) {
private lateinit var spinView: Spinner
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// your view setup code
}
}
I Have an activity fragment whereby i have it call out values from a separate data class and also a .xml file
I want the button in the .xml file to be accessible in the Kotlin CLASS.however, an error keeps showing that the declared function is unreachable.
What i have done:
the kotlin class page:
class HomeFragment : Fragment() {
private val personcolletionref =Firebase.firestore.collection( "users")
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home, container, false)
submitbutton.setOnClickListener {
}
}
private fun savePerson (person: Person) = CoroutineScope(Dispatchers.IO).launch {
try {
personcolletionref.add(person).await()
withContext(Dispatchers.Main) {
Toast.makeText(activity, "Successful", Toast.LENGTH_LONG).show()
}
}catch (e: Exception) {
withContext(Dispatchers.Main) {
Toast.makeText(activity, e.message, Toast.LENGTH_LONG).show()
}
}
}
}
the button in the xml file to be called:
<Button
android:id="#+id/submitbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="268dp"
android:text="Submit"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="#+id/edittextage"
app:layout_constraintStart_toStartOf="#+id/edittextage" />
In the onCreateView method, you just have to return the view. Override the following method and write your button on click listener init
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
submitbutton.setOnClickListener {
}
}
I am working kotlin. I have a fragment on my Activity . l want when click on button inside of fragment activity go to another activity .
this code my used in fragment class
class fragment_Arr :Fragment(), View.OnClickListener {
override fun onClick(v: View?) {
val intent = Intent(activity, FlightDeatilasDep::class.java)
startActivity(intent)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_arrivel,container,false)
loadmorefilghtsbeforday.setOnClickListener{this}
}
}
when l debug app and click on button no event happening !
loadmorefilghtsbeforday.setOnClickListener{} body of the lambda is empty - nothing happen.
Please register your listener by
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_arrivel,container,false)
loadmorefilghtsbeforday.setOnClickListener(this)
return view
}
or if you prefer using lambdas
loadmorefilghtsbeforday.setOnClickListener{ onClick(null) } could be called but then your fragment don't need to implements View.OnClickListener.
and class names in Kotlin/java should start from capital later: FragmentArr.
_ is not recommended