How to programmatically control Switch (button) in Android App - android-studio

I am developing an app in Android Studio.
I have a Switch to enable / disable some functionality.
I am using an xml file to define the colour of the thumb and track – both gray when switch is disabled (thumb to the left), and both green when the switch is enabled (thumb to the right).
This works fine.
However, I also need to update the switch display when a message is received from a remote Bluetooth device. For example, if the switch is in the disabled position (gray), and an enable message is received, then I want to update the switch display so that it is enabled (tall green, thumb to the right).
Right now, when I try to update the switch display, the switch thumb changes color to green (= desired behavior), but
(a) the thumb stays to the left, and
(b) the track stays gray.
My code is below.
Can anyone see what I am doing wrong?
Thanks in advance
Garrett
Switch definition:
<Switch
android:id="#+id/switch_1_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:thumbTint="#drawable/switch_selector"
android:trackTint="#drawable/switch_selector"
android:text=""
/>
When the switch is selected/pressed by the user:
switch_1_select.setOnClickListener {
if (switch_1_select.isChecked)
{
// do something
} else {
// do something else
}
}
XML file to (supposedly) control switch display:
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/colorGreen" android:state_checked="true" />
<item android:color="#color/colorGray"/>
</selector>
Code called when enable message received from remote device:
switch_1_select.isChecked = true
In pictures....
Here is a pic showing the switch in the disabled position (with thumb to the left, and both thumb and track gray).
Here is a pic showing the switch in the enabled position (with thumb to the right, and both thumb and track green). This is how the switch looks when the user clicks on it.
And finally, here is a pic showing the switch when I programmatically try to enable it (from its disabled position). Notice that although the thumb is green, the thumb remains to the left, and the track color remains gray.
Edit / Update:
I updated my switches to SwitchCompat, after reading this post:
How to change the color of a SwitchCompat from AppCompat library
Switch definition:
<androidx.appcompat.widget.SwitchCompat
android:id="#+id/switch_1_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text=""
/>
So I no longer use an XML style file to try and control the thumb / track colors.
Instead, in my app theme, I define the colors:
<!-- colorControlActivated is the color applied to framework controls
in their activated (ex. checked, switch on) state. -->
<item name="colorControlActivated">#color/colorGreen</item>
<!-- colorSwitchThumbNormal is color applied to framework switch
thumbs in their normal state. (switch off). -->
<item name="colorSwitchThumbNormal">#color/colorGray</item>
Result:
Some improvement
When I programmatically check / uncheck the switch, the thumb and track colours change (gray for unchecked, green for checked).
However the thumb position does NOT change.
To check / uncheck the switch programmatically, I have tried:
switch_1_select.toggle()
and
switch_1_select.isChecked = false
switch_1_select.isChecked = true
It looks like the code might need to manually set the thumb position
I tried this:
switch_cooler_status_select.setThumbPosition(0.0F)
switch_cooler_status_select.setThumbPosition(1.0F)
but I get the following error:
Cannot access 'setThumbPosition': it is package-private in
'SwitchCompat'

Related

Why Is My UI Not Showing When I Drop Items Into It From The Editor?

So I just downloaded Android Studio onto this compute. When the Layout Editor interface loads and I try to drag the XML items onto the screen, they do show up in the constraintView but not in the editor.
I get a render error that states "Couldn't resolve resource #string/helegrtsrewfrtsaw"
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginLeft="132dp"
android:layout_marginStart="132dp"
android:text="#string/helegrtsrewfrtsaw"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
Because you are using ConstraintLayout as parent layout, you need to to remove android:layout_width and android_layout:height then define constraints of your Switch in the Attributes tab on the right hand side.
It will allow system to arrange your View width/height and position base on parent layout (instead of using specific predefined values).
P.s: If you click on the exclamation mark !, it will tell you to add the constraints or the View will jump to position (0,0).

This view is not constrained, it only has designtime positions, so it will jump to (0,0) unless you add constraints The

This view is not constrained, it only has designtime positions, so it will jump to (0,0) unless you add constraints.
The layout editor allows you to place widgets anywhere on the canvas, and it records the current position with designtime attributes (such as layout_editor_absoluteX.) These attributes are not applied at runtime, so if you push your layout on a device, the widgets may appear in a different location than shown in the editor. To fix this, make sure a widget has both horizontal and vertical constraints by dragging from the edge connections.
This may help someone.
I am using Android Studio 3.1 and i faced same problem but i didn't find these options (Constraint Layout -> Infer Layout) as suggested in the above answer.
Then after carefully checking i found "Infer Constraint" option above the layout window (refer to screenshot below in step 1)
Step 1: Click on "Infer Constraint". This may solve your problem, but if your widget still not visible (as in my case), then follow step 2.
Step 2: Click on "AppTheme" and select "NoTitleBar" theme as selected in the screenshot
This solved my problem.
Add the following piece of code to your code:
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
Right click on design layout in Android Studio, then select "Constrain Layout" and sub menu is open, then select "infer Layout" and compile your App.
From Android Studio v3 and up, Infer Constraint was removed from the dropdown.
Use the magic wand icon in the toolbar menu above the design preview; there is the "Infer Constraints" button. Click on this button, this will automatically add some lines in the text field and the red line will be removed.
In my project this error was caused by android:layout_width="fill_parent" and android:layout_height="fill_parent" expressions. fill_parent constant is obsolete. Changing to to match_parent solved the problem:
<ViewFlipper
android:id="#+id/viewFlipper1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
</ViewFlipper>
Android studio hint says:
This view is not constrained. It only has designtime positions, so it will jump to (0,0) at runtime unless you add the constraints less... (Ctrl+F1)
The layout editor allows you to place widgets anywhere on the canvas, and it records the current position with designtime attributes (such as layout_editor_absoluteX). These attributes are not applied at runtime, so if you push your layout on a device, the widgets may appear in a different location than shown in the editor.
To fix this, make sure a widget has both horizontal and vertical constraints by dragging from the edge connections.
Good Work. Just make a little change, according to my experience, You have to CLICK the " Infer Constraint " (a magic stick button).To make Infer Constraint appear, Remember the Palette (button/image/text etc) which you dragged on the constraint layout (screen). You have to click the very palette and it'll appear on the top right side. Click that magic stick button and your error will be removed.
Here is my fix (100% working):
1, Please drag and drop the images that you entered in folder "drawable". Note to keep the original name
2, Click the play(Green Triangle) button
3, It shows an error please click on your image and right click> Refactor> Rename>
All place> Refactor and then run the application again> Restart
Note that the image name must not contain "-", "_"
When you run the app it will save the name to memory so just re-enter the image with your original name and then click Refactor> Rename> enter another name (must not contain any characters)> select All place(This will change the entire corrupted name to something that works better)> Refactor and rerun your application!
To position a SurfaceView in the center of the ConstraintLayout, using the holder setFixedSize, change layout_width to "wrap_content".
// setting holder
holder?.setFixedSize(640, 480)
XML
<androidx.constraintlayout.widget.ConstraintLayout
android:id = "#+id/player_view"
android:gravity = "center"
android:layout_width = "0dp"
android:layout_height = "0dp"
app:layout_constraintTop_toTopOf = "parent"
app: layout_constraintBottom_toBottomOf = "parent"
app:layout_constraintEnd_toEndOf = "parent"
app:layout_constraintStart_toStartOf = "parent">
<SurfaceView
android:id = "#+id/surfaceView"
android:gravity = "center"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
app:layout_constraintTop_toTopOf = "parent"
app:layout_constraintBottom_toBottomOf = "parent"
app:layout_constraintEnd_toEndOf = "parent"
app:layout_constraintStart_toStartOf = "parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

Snackbar for Circular Android Wear Designs

The classic Snackbar provided from Android design library works in wear project.
In square display they looks fine, but in round they don't.
The corner of the snackbar are cropped by the circular display.
Does anyone know a workaround?
I don't want to use toast.
see the image:
the code that I use:
Snackbar.make(view, serverMessage, Snackbar.LENGTH_SHORT).show();
Thanks
According to the Android blog, there are several ways you can do this. These are :
Using BoxInsertLayout which is mentioned in the Use a Shape-Aware Layout guide.
The BoxInsetLayout class included in the Wearable UI Library extends FrameLayout and lets you define a single layout that works for both square and round screens. This class applies the required window insets depending on the screen shape and lets you easily align views on the center or near the edges of the screen.
WatchViewStub
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/watch_view_stub"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:rectLayout="#layout/rect_activity_main"
app:roundLayout="#layout/round_activity_main"
tools:context="com.android.example.watchviewstub.MainActivity"
tools:deviceIds="wear">

Screen orientation in editor in Android Studio

In android studio, when run, my program is displayed in landscape mode and works perfectly well. However, when viewing the xml design, the virtual device is displayed in portrait mode. How do I display the xml in landscape mode?
Short Cut
Ctrl+F11 Switch layout orientation portrait/landscape backwards [AVD]
The screenOrientation is the attribute of activity element. The
orientation of android activity can be portrait, landscape, sensor,
unspecified etc. You need to define it in the AndroidManifest.xml
file.
You can add
android:screenOrientation="landscape"
Your screen will always display in Landscape mode, when you rotate
your device, no changes will apply for the current activity.
Like
<activity
android:name=".ActivityName"
android:label="#string/app_name"
android:screenOrientation="landscape" />
Please check official Guideline:
https://developer.android.com/guide/topics/manifest/activity-element.html#screen
Click that button next to "Nexus 5".

Android RatingBar - a complete mess

I know this is going to sound ranty, but it just feels like Android's UI components and behaviours are off the wall sometimes.
Consider the following XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<RatingBar
android:id="#+id/ratingBar1"
android:style="#android:style/Widget.Holo.Light.RatingBar.Small"
android:progress="3"
android:max="5"
android:numStars = "5"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Screenshots of how that would look on different device sizes:
Nexus S rating bar
Tablet rating bar
Small Device rating bar
Even though it's only in the preview tool, I can confirm that's actually how it looks on the devices.
The small device behaviour is maddening. How does a RatingBar that specifies 5 stars only get 3 displayed, why not scale down the stars to fit in the window?
Thinking the wrap_content width was the issue, I switched to layout_width="fill_parent" and that didn't change the look on a small device, but it completely messed up on Tablets (so much for "numStars" of 5):
My question is, is there a way to get proper behaviour for the RatingBar in terms of sizing? You would think the numStars or max would be sufficient but it's completely arbitrary. When the RatingBar is stretched so that it draws more stars, it adds stars and see how with a progress of 3, it draws it according to the number of stars displayed? It doesn't make sense not to adhere to numStars!
If there is no way to get logical performance from the RatingBar, are there any alternatives including 3rd party widgets? If not, I guess I could always draw 5 ImageViews and just rig it to perform accordingly.
(Keep in mind all this behaviour was exhibited with just one RatingBar in the layout - forget trying to size with other widgets/components, or utilizing your own styles. I know it's been done, but why is this the default behavior?)
I felt the same way as you when using the stock RatingBar, so I made my own: SimpleRatingBar.
It features:
Fully working android:layout_width: it can be set to wrap_content, match_parent or abritary dp.
Arbitrary number of stars.
Arbitrary step size.
Size of stars can be controlled exactly or by setting a maximum size.
Customizable colors (border, fill and background of stars).
Customizable size separation between stars.
Customizable border width of stars.
Allows to set OnRatingBarChangeListener
Stars fill can be set to start from left to right or from right to left (RTL language support).
AnimationBuilder integrated in the view to set rating programatically with animation.
Here is a preview of it.
You can find it either in jcenter or in Maven Central. So in your build.gradle file just add to your dependencies:
compile 'com.iarcuschin:simpleratingbar:0.1.+'
I hope it's useful.

Resources