Dimitry Ivanov

Di's blog

How to toggle boolean in SQLite

Okay, SQLite doesn't have a separate Boolean datatype, but it's not uncommon to use an INTEGER to store one. How can we toggle this value in a single SQL statement without retrieving stored value first?

Continue

EmotionLayout

I've stumbled upon an interesting UI effect by Chris Banes implemented with MotionLayout. Unfortunately... well. Unfortunately it's MotionLayout, so motions are defined in XML scene files sprinkled with constrains and references to views. If you haven't seen one — go ahead and see the one that defines UI effect in question. Now, there must be a simpler way...

Continue

public static void main for Android

Sometimes I find myself wanting to evaluate some Android code without launching an app on a device or an emulator (and without adding log statements in random components). For example Java has a public static void main method that can be added in any class and launched right from the IDE. Can this be done for Android?

public class MainActivity extends Activity {

    public static void main(String[] args) {
        final String input = "tel:+34 666 55 52 22";
        System.out.printf("input: %s, uri: %s%n", input, Uri.parse(input));
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

Unfortunately this will fail with somewhat famous exception:

Exception in thread "main" java.lang.RuntimeException: Stub!
	at android.net.Uri.parse(Uri.java:293)
	at io.noties.psvm.MainActivity.main(MainActivity.java:11)

This happens because our code is compiled with android.jar dependency (that can be found in $ANDROID_SDK/platforms/android-${version}/android.jar) that has only public API definitions. All API method signatures are present but their bodies contain a single statement: throw new RuntimeException("Stub!"). android.jar here is a runtime dependency. We still can operate on public API during development, but actual implementation is provided by a device or an emulator when an app is launched.

I labeled the java.lang.RuntimeException: Stub! as somewhat famous because you might've seen it whilst trying to launch java unit tests that contain Android code. This problem is long gone with the help of amazing Robolectric testing framework. But wait... this must mean that Robolectric has a proper android.jar with all the methods present. Can we use it?

Continue

Google Pixel

The more you think about it the more it becomes obvious that Google Pixel is a perfect name for a Google brand. Especially if you take into account the tracking pixels that are so wide-spread in web-pages you visit or emails you read. Only this time data collection is taken to a truly next level closing the gap between physical and digital world. Precise geolocation, MAC addresses of networking hardware, available Wi-Fi networks, nearby cell towers, non-stop audio recording, access to photo cameras, behavioral patterns, VPN configs and true IP addresses and much-much more were still not available to web pages. Until the true Pixel emerged...

Gradient Messenger Round 2

In the previous article we've implemented gradient background with fixed scrolling behavior. Similar effect can be seen in the Fa¢ebook Messenger app. Now it's the time to give our app some UI polish - we will add rounded corners to chat messages and introduce messages grouping. Most of the changes will happen in our custom RecyclerView.ItemDecoration which source can be found here. As a bonus point we will make our RecyclerView.ItemDecoration ready for RecyclerView.ItemAnimator animations.

Continue

Kotlin is fun!!

kotlin is fun!!

Gradient Messenger

In this article we will reproduce fixed gradient background for chat messages. Similar effect can be seen in the Fa¢ebook Messenger application. We will use custom Drawable, RecyclerView and RecyclerView.ItemDecoration.

TL;DR: browse the source code

Continue

We have everything

We have:

  • interesting tasks
  • cutting edge tech
  • cross functional teams
  • team leads
  • human resources heads
  • talent hunters
  • QA
  • product managers
  • product owners
  • vision bearers
  • keepers of team spirit
  • meetups͙
  • h̺͒acka͠t̃on͢s̚
  • f̵ree snͭacks
  • c̯ͭ̌ͤof̝ͯf͚ee
  • amazi̯͡ng openͩ off̬̽i͜ce
  • sc͊rum̂ m̱a͢ste̎rs
  • ag͘i͊le e̘n̹͘̕thusiͫ͡a͉͖̽sts
  • advͅoca̛̫̚͞ts̖͌ of wȟă͞t-not
  • n̸͂o͆̏thǐn̳g wor͑ks̈!
  • no̬thͥ̚i̕n҉̬̯gͅ wͨork͚̏͜s̵͔͡?

Complex Android animations - Tutorial

Achieving complex animations on Android might be a daunting task. Especially when an arbitrary number of views are involved and/or they have specific ordering (one-after-another, grouping, delays, etc). Using built-in ValueAnimator, ObjectAnimator, ViewPropertyAnimator or AnimatorSet would result in untangled mess of callbacks and won't be extensible, easy to tweak nor maintain.

gif

This tutorial will show how to achieve complex animations in a clean and easy way in just few lines of code.

Continue

Local Maven repository

With a little help of Gradle one can have a local Maven repository literally with a single line of code in the build configuration file:

repositories {
    maven { url 'file:///Users/me/.maven-local' }
}

It can be used to release your local artifacts also. For example, if you are using gradle-mvn-push:

if (project.hasProperty('local') {
    ext.RELEASE_REPOSITORY_URL = 'file:///Users/me/.maven-local'
}
./gradlew upA -Plocal

BTW upA here stands for uploadArchives but Gradle allows us to shorten task name a bit

Continue

Enhance Android source code for developers

It's actually a follow-up of the previous @since tag to Android source distribution. Turned out this can be done by ourselves (plus a bit more). Here is the final result:

/**
 * Called by the system when the activity changes from fullscreen mode to multi-window mode and
 * visa-versa.
 *
 * @see android.R.attr#resizeableActivity
 * @param isInMultiWindowMode True if the activity is in multi-window mode.
 * @deprecated Use {@link #onMultiWindowModeChanged(boolean, Configuration)} instead.
 * @since 7.0 Nougat (24)
 * @deprecated 8.0 Oreo (26)
 */
@Deprecated
public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
    // Left deliberately empty. There should be no side effects if a direct
    // subclass of Activity does not call super.
}

TLDR: Enhance!

Continue

@since tag to Android source distribution

Some time ago I come up with simple enhancement for the Android source code that is distributed via SDK Manager: adding the @since javadoc tag to the public API.

Just imagine:

/**
* Sets a rectangular area on this view to which the view will be clipped
* when it is drawn. Setting the value to null will remove the clip bounds
* and the view will draw normally, using its full bounds.
*
* @param clipBounds The rectangular area, in the local coordinates of
* this view, to which future drawing operations will be clipped.

* @since 4.3 (18)
*/
public void setClipBounds(Rect clipBounds) {
...

Issue on the bug tracker.

Continue

Newton's Cradle Drawable (Tumbleweed Android)

gif

Implementation steps to create Newton's Cradle drawable for Android.

Continue

Square Frame Layout

A simple implementation of FrameLayout to be used in a RecyclerView with a GridLayoutManager in order to achieve square shaped layout. Does not depend on external dimensions. Will always be square even if you change spanCount at runtime.

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// to be continued...
Continue

Grid items equal spacing (RecyclerView)

This is how to achieve equal spacing between grid elements and RecyclerView borders. Applicable for both GridLayoutManager and StaggeredGridLayoutManager. No modification of existing Adapter is required.

2 columns 3 columns 4 columns
Continue