How to open (enter) SettingsFragment or any Fragment on Android (Kotlin) - kotlin

I am learning Android programing, and I can not figure it out how to open settings fragment when button is clicked.
This fragment is not in the navigation map, so it is not possible to connect them in navigation and to use findNavController().navigate(actionFromTo)
As explained on developer guide: https://developer.android.com/guide/topics/ui/settings
I have created fragment:
class PreferencesFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.preferences, rootKey)
}
}
What I need to write in click listener to enter settings fragment?
Click listener is:
binding.buttonSettings.setOnClickListener {
}
I have tried with to use code in developers guide:
binding.buttonSettings.setOnClickListener {
val fragmentManager: FragmentManager? = activity?.supportFragmentManager
fragmentManager?.beginTransaction()?.replace(R.id.preferencesFragment, PreferencesFragment())?.commit()
}
But program crashes when button is pressed, with error:
No view found for...

The issue seems to be the content ID you want to replace, therefore you need to pass the current content ID you want to replace
see below code, use android.R.id.content instead of R.id.preferencesFragment
binding.buttonSettings.setOnClickListener {
val fragmentManager: FragmentManager? = activity?.supportFragmentManager
fragmentManager?.beginTransaction()?.replace(android.R.id.content, PreferencesFragment())?.commit()
}

Related

Kotlin, How do I dismiss an App by pressing the Back button Activity which is not the launcher activity in android?

I have a login activity with navigation fragments , one is the splash screen and then navigate to Login Fragment this is the Launcher Activity and it checks if the user is already logged in and then start de Initial Activity if is already logged in.
In the Initial Activity i have a navigation fragments but when the user press the back button the Activity Launch start instead of close the activity. I want the user to close the app like the same behavior that occurs when back button is pressed on the launcher activity. How do i achieve this?
This is the splash fragment in the Launcher Activity:
fun initListeners() {
val DURATION = 2500
user_app.toString()
val handler = Handler()
handler.postDelayed({
if (user_app.isEmpty() && pwd_app.isEmpty()) {
navigationToLogin()
} else {
Toast.makeText(safeActivity, "SesiĆ³n iniciada ${OPERATOR_APP.getPreferenceToString().toString()}", Toast.LENGTH_SHORT).show()
startActivity(Intent(safeActivity,XTInitActivity::class.java))
}
}, DURATION.toLong())
}
fun navigationToLogin() {
val navigate = SplashFragmentDirections.actionSplashFragmentToXTLoginFragment()
findNavController().navigate(navigate)
}
}
I try when the methon onBackPressed whit its callbacks but its now deprecated for most recent API
I think you should make a separate activity for splash and keep the splash activity as the launcher instead of Login activity and and then if the user is not signed in then only go to Loginactivity else start the MainActivity (XTInitActivity in your case)
However if you need to make LoginActivity as the launcher activity then use the following:
override fun onBackPressed(){
super.onBackPressed()
exitProcess(0)
}
override onBackPressed in Initial Activity
override fun onBackPressed() {
super.onBackPressed()
exitProcess(0)
}

Composable Focus

I have a project where we display a graph, this graph is in an Box which is scrollable.
By opening the view, we need to center the root node which causes the problem currently.
Determining the position and setting the values of the states is currently done the following way:
.onGloballyPositioned { coordinates -> scrollBy = coordinates.positionInParent().y - dpstate!!.scrollState.firstVisibleItemScrollOffset
}
.onFocusChanged {
if(it.isFocused ){
print("is focused")
scope.launch { dpstate!!.scrollState.animateScrollBy(scrollBy)
dpstate!!.offsetState.value = Offset(leftX.toFloat(),dpstate!!.offsetState.value.y)
}
}
}
in the modifier of the box.
The state dpstate is an instance of the following:
data class DisplayState(
val scrollState: LazyListState,
val scaleState: MutableState<Float>,
val offsetState: MutableState<Offset>,
val editState: MutableState<Boolean>,
val showInfo:Map<Int, MutableState<Boolean>>,)
Important is, that I need to center by opening it, not by clicking a button.
My try was in the calling code of all of this the following code:
DisposableEffect(Unit){
com.github.tukcps.appel.ui.rendering.focusRequester!!.requestFocus()
onDispose { }
}
There is no exception, it just don't do anything, thanks for your help.

How to retrigger focusRequester.requestFocus() when coming back to a composable?

I have a MyBasicTextField in a composable to request user input:
#Composable
fun MyBasicTextField() {
val keyboardController = LocalSoftwareKeyboardController.current
val focusRequester = remember{ FocusRequester() }
BasicTextField(
modifier = Modifier
.focusRequester(focusRequester),
keyboardActions = keyboardActions ?: KeyboardActions(onAny = { keyboardController?.hide() }),
)
LaunchedEffect(Unit) {
focusRequester.requestFocus()
}
}
The keyboard automatically slides in when showing this composable, always.
But wherever MyBasicTextField is used:
I tap on a LinkifiedText to leave and open a browser to show link
I tap BACK
and come back to previous MyBasicTextField screen, the keyboard is not shown
also the focusRequester.requestFocus() is not triggered again when coming back
How can I solve my issue?
Create a top-level variable in your activity, then modify it from within the onStart overridden method. Use that variable as the key for LaunchedEffect in place of Unit. That variable basically keeps track of when the user enters the app.
var userIn by mutableStateOf (true)
In your Composable,
Launched effect(userIn){
if(userIn && isKeyboardShown){
...
}
}
Boring,
You can use my answer here as well, but instead of incrmenting the launchKey every time it's called, only increment the launchKey once user clicks on the browser link, that way it will not pop up during other re-compositions.

Kotlin|Tornadofx: How to open new fxml screen on mouse click in another fxml screen

I have a very simple task but can't do it.
I have Kotlin|Tornadofx app.
I open the fxml screen:
class MainView : View() {
override val root : VBox by fxml("/Screen 1.fxml")
}
There is a button in Screen1.fxml. I need the app to open another screen (Screen2.fxml) on button pressed in Screen1.fxml.
I got stuck by this. Only a function call is available from Screen1.fxml by means of onAction="#FunctiondefinedinMainView". But swapping views in MainView is only available by
button("Go to Screen2") {
action {
replaceWith<Screen2>()
}
constructs, which I cannot accomplish because I only can call a function from within Screen1.fxml. And I do not have buttons in MainView.
Thanks in advance.
First, you should add an id to your button in your Screen 1.fxml file:
<Button fx:id="myButtonId">
Then, you can get a reference to that button in your MainView:
class MainView : View() {
override val root: VBox by fxml("/Screen 1.fxml")
val button: Button by fxid("myButtonId")
}
Now, you can set the click listener for your button to replace the screen:
class MainView : View() {
override val root: VBox by fxml("/Screen 1.fxml")
val button: Button by fxid("myButtonId")
init {
button.setOnAction {
replaceWith<Screen2>()
}
}
}
I haven't tried this before but it should work, in case it doesn't, feel free to leave a comment.

How to create a paint application like Messenger's emoji paint on captured photo in Kotlin

So I'm making an app which needs to paint garland, light bulbs and other decoration. I have a code which will make an imageview on Action_Move but the app crashes. see the code below
fun drawLights(){
val listener = View.OnTouchListener(function = { view, motionEvent ->
val x = motionEvent.getX()
val y = motionEvent.getY()
when (motionEvent.action){
MotionEvent.ACTION_DOWN -> {
Toast.makeText(this,"Action Down",Toast.LENGTH_SHORT).show()
}
MotionEvent.ACTION_MOVE -> {
Toast.makeText(this, "Moving", Toast.LENGTH_SHORT).show()
////Imageview Creation Here using late init var
}
MotionEvent.ACTION_UP -> {
Toast.makeText(this,"Done" ,Toast.LENGTH_SHORT).show()
}
}
true
})
edit_Canvas.setOnTouchListener(listener)
}
Does anyone here know any blog related to this or already resolved this problem? Thanks!
You need to look for topics on drawing on the Android Canvas. There are lots of sample codes out there
This one's from the official documentation in drawing on the Canvas https://developer.android.com/training/custom-views/custom-drawing