android pro tips
19 subscribers
5 links
Download Telegram
to apply an alpha (0..255) to your color, you can mask the rgb part, shift the alpha bytes and add it to the rgb part

(color and 0x00ffffff) or (alpha shl 24)

#kotlin #color #alpha
since android 10, there is gesture navigation in the system. if your custom view conflicts with gestures (e.g. drawing or slider), don't forget to add exclusion

it is recommended to override onLayout in your view and set exclusion there whenever the position or size are changed

#sdk #gestures #customview
one of the ways to optimize the recycler view is to call the setHasFixedSize(true). there is a common misunderstanding about what this method means

what it really means is that the recycler view should not change its size depending on its content, e.g. the number of items. this way it allows to optimize re-measuring

#library #recyclerview #optimization
when you create a widget – you need to set the preview

there is a wonderful utility for this

#tool #widget #preview
obsolete since the release of the new logcat in android studio dolphin

in the logcat search field in android studio there is a dropdown list of recent searches

to open it – hover your mouse over the search icon,
or when the search field is focused, press alt+down or option+down for mac

#androidstudio #logcat #hotkey
if you are developing a customizable widget, it's a good idea to give users a preview

remote views class has a special RemoteViews#apply method that inflates remote views into a regular view hierarchy, which you can add to the interface

#sdk #widget #remoteviews #preview
when you turn on show layout bounds in the developer menu, you may see these four squares in the corners and a crosshair on some views

this is just an indication that the view has focus at the moment

#sdk #focus #debug
if you want to make a special preview for your custom view, or if you don't want to do some work if it is a preview, you need to know where the view is drawn

there is a method View#isInEditMode, which returns true if the view is drawn in the layout editor

#sdk #customview #layouteditor
if you use ellipsize = TextUtils.TruncateAt.END or android:ellipsize="end", you should keep in mind a few things

do not use wrap content for the layout width, and remember to specify maxLines, otherwise ellipsize will not work

#sdk #textview #ellipsize
if your app does not require multi-touch support on every screen, it can be disabled by adding this lines to your app theme

#sdk #multitouch #theme
<item name="android:windowEnableSplitTouch">false</item>
<item name="android:splitMotionEvents">false</item>
if your application is declared to use the Manifest.permission.CAMERA, which is not granted, trying to use the MediaStore.ACTION_IMAGE_CAPTURE action
will result in a SecurityException

however, you can bypass this restriction by using a similar action – MediaStore.ACTION_IMAGE_CAPTURE_SECURE

#sdk #permission #camera
sometimes you need to create an activity the only purpose of which will be to perform some action and finish immediately. these activities do not actually display the user interface, they finish themselves before they are resumed

there is a theme for such activities that you can use – android:Theme.NoDisplay

#sdk #theme #activity
there are scenarios where you cannot run the application with the debugger, for example when the application process is restarted.

to be able to attach the debugger in the right place there is a method Debug.waitForDebugger(). it will block execution until you attach the debugger manually

#sdk #debug #restart
the Activity class has a reportFullyDrawn() method. It is useful when you want to measure the time from startup to the moment the app content is loaded

call it when the UI is fully rendered and populated with all the necessary data, logcat will output how much time has passed from startup to the moment of the call

#sdk #activity #startup
If you want to go completely full screen - there are plenty of tutorials. But if you have a device with cutouts there is one more thing to do.

Add to your app's theme android:windowLayoutInDisplayCutoutMode and set it to always. This will allow your app to extend into the cutout areas on the all edges of the screen.

#sdk #theme #fullscreen
Since API level 30, the View class has a method isShowingLayoutBounds, which returns true if the view is attached and the system developer setting to show the layout bounds is enabled.

This is useful if you want to add debug drawing for a custom view in a nice way.

#sdk #customview #debug
There's a classic problem: create an intent that will only open email clients, and will have an attachment. The tricky part is that Intent.ACTION_SENDTO cannot accept an attachment, while Intent.ACTION_SEND opens not only email clients.

The solution is to use seleclor, which allows you build an intent containing a generic protocol while targeting it more specifically to open email clients only.

#sdk #intent #email

val selectorIntent = Intent().apply {
setAction(Intent.ACTION_SENDTO)
setData(Uri.parse("mailto:"))
}
val intent = Intent().apply {
setAction(Intent.ACTION_SEND)
setSelector(selectorIntent)
// Add attachment
}
The View class has an API for setting a tooltip, that will be shown to the user on a long click, or on a mouse hover event.

You can specify the tooltip text by calling the View#setTooltipText() method.

#sdk #view #accessibility
Since API level 31 the apps are required to check for SCHEDULE_EXACT_ALARM permission in order to use exact alarm APIs.

To make the user’s life easier, you can set the Intent's data URI to specify the application package name to directly invoke the management UI specific to your app.

#sdk #permission #alarms

val intent = Intent(
Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM,
Uri.parse(context.packageName),
)
If you have a transparent activity, you might as well want to disable a splash screen.

Luckily, there is a flag just for that.

#sdk #theme #splash

<item name="android:windowDisablePreview">true</item>