Issue
Hello StackOverflow users!
I'm trying to do someting complicated (for a noob like me XD) and I have some questions.
How can I set my main screen buttons position form a preference screen? Like, if I have 2 buttons to inverse their position...
I tried to do with the code below in kotlin (please don't judge me, already told u I'm noob af) but I wanna have an idea how to make this wotk. XD
findPreference<Preference>("buttonpositions")!!.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { preference: Preference, _: Any? ->
val checked = (preference as CheckBoxPreference).isChecked
if(!checked) {
val myBtn = R.id.cleanBtn as Button
myBtn.setPadding(0, 100, 0, 0)
}
true
}
and the buttons is something like this:
<com.google.android.material.button.MaterialButton
style="@style/Widget.Material3.Button.UnelevatedButton"
android:id="@+id/cleanBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_columnWeight="1"
android:minWidth="0dp"
app:layout_rowWeight="1"
android:tooltipText="@string/tooltip_clean_button"
app:iconGravity="top"
app:icon="@drawable/ic_broom"
app:iconTint="@android:color/system_accent1_400"
android:textColor="@android:color/system_accent1_400"
android:text="@string/clean"/>
<com.google.android.material.button.MaterialButton
style="@style/Widget.Material3.Button.UnelevatedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_columnWeight="1"
app:layout_rowWeight="1"
android:id="@+id/analyzeBtn"
app:iconGravity="top"
app:icon="@drawable/ic_search"
android:tooltipText="@string/analyze_tooltip"
app:iconTint="@android:color/system_accent1_700"
android:textColor="@android:color/system_accent1_700"
android:text="@string/analyze"
android:minWidth="0dp"
app:backgroundTint="@android:color/transparent"/>
First. I'm preety sure my "code" isn't right composed + idk if I need to add someting to buttons itself.
Thanks for your time :D
Solution
Why your code won't work:
R.id.cleanBtn
is an Int ID, not a button. Trying to cast an Int into a Button will crash the app. (Casting is not the same thing as converting--it's promising the compiler that something is also something else already.) IDs are used to search existing view hierarchies for the actual view you want by using something likerootView.findViewById<Button>(R.id.cleanBtn)
, but this strategy isn't practical here since you don't have direct access to the view hierarchy.- Trying to change the button from the preference listener would only work when you change it. If the user rotates the screen or the exits the app and comes back, the main screen's view will be recreated back in the original position.
The right way to do this is not on the settings screen, but on the main screen. Preferences that are set on a preference screen by default are saved to the "default" shared preferences, and they are saved persistently, so they can be read from anywhere else in your app.
What I would do is read the current value of the preference in the onResume()
function of the activity or fragment of your main screen. onResume()
will get called every time that screen reappears, so it gives it an opportunity to check and apply the setting the first time the view appears and every time you return from the preferences screen, where the value may have changed.
//in main screen class
private var isButtonPositionFlipped = false
// Only need this function if in a Fragment
// Need to reset the property in case Fragment has recreated its view
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//...
isButtonPositionFlipped = false
}
override fun onResume() {
super.onResume()
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
// use requireContext() instead of this if we're in a Fragment class
val shouldFlipButtonPosition = sharedPreferences.getBoolean("buttonpositions", false)
if (isButtonPositionFlipped != shouldFlipButtonPosition) {
isButtonPositionFlipped = shouldFlipButtonPosition
val cleanBtn = findViewById<Button>(R.id.cleanBtn)
val analyzeBtn = findViewById<Button>(R.id.analyzeBtn)
// use requireView().findViewByID if in a Fragment class
if (isButtonPositionFlipped) {
// swap the buttons here
} else {
// swap them back here
}
}
}
As for how to swap them, that depends on the type of layout they're in. If they're in a ConstraintLayout, I think it will be pretty complicated, but I haven't tried it before. You might try putting each of the two buttons inside FrameLayouts. Then you could get the FrameLayout views and swap the view children between them.
Edit: Actually, I think it would be easier in this case to just make your buttons more generically named. Instead of swapping them, just change their text and click listeners to the opposites.
Answered By - Tenfour04
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.