Populating Spinner items directly in xml layout

In your strings.xml define:

<string-array name="array_name">
<item>Array Item One</item>
<item>Array Item Two</item>
<item>Array Item Three</item>
</string-array>

In your layout:

<Spinner 
        android:id="@+id/spinner"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:drawSelectorOnTop="true"
        android:entries="@array/array_name"
    />

References
https://stackoverflow.com/questions/4029261/populating-spinner-directly-in-the-layout-xml

Animating Layout Changes

All you need to do is set an attribute in the layout to tell the Android system to animate these layout changes, and system-default animations are carried out for you.

<LinearLayout android:id="@+id/container"
    android:animateLayoutChanges="true"
    ...
/>

Now, all you need to do is add, remove, or update items in the layout and the items are animated automatically:

private ViewGroup mContainerView;
...
private void addItem() {
    View newView;
    ...
    mContainerView.addView(newView, 0);
}

Tip: If you want to supply custom layout animations, create a LayoutTransition object and supply it to the layout with the setLayoutTransition() method.

References
https://developer.android.com/training/animation/layout.html
https://stackoverflow.com/questions/41464629/expand-collapse-animation-in-cardview
https://github.com/mhdr/AndroidSamples/tree/master/104

Constraint Layout Vertical Align Center

If you have a ConstraintLayout with some size, and a child View with some smaller size, you can achieve centering by constraining the child’s two edges to the same two edges of the parent and set width to 0dp. That is, you can write:

app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"

Or

app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"

Example

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/stat_1"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:gravity="center"
        android:maxLines="1"
        android:text="10"
        android:textColor="#777"
        android:textSize="22sp"
        app:layout_constraintTop_toTopOf="@+id/stat_2"
        app:layout_constraintEnd_toStartOf="@+id/divider_1" />

    <TextView
        android:id="@+id/stat_detail_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Streak"
        android:textColor="#777"
        android:textSize="12sp"
        app:layout_constraintTop_toBottomOf="@+id/stat_1"
        app:layout_constraintStart_toStartOf="@+id/stat_1"
        app:layout_constraintEnd_toEndOf="@+id/stat_1" />

    <View
        android:id="@+id/divider_1"
        android:layout_width="1dp"
        android:layout_height="0dp"
        android:layout_marginEnd="16dp"
        android:background="#ccc"
        app:layout_constraintTop_toTopOf="@+id/stat_2"
        app:layout_constraintEnd_toStartOf="@+id/stat_2"
        app:layout_constraintBottom_toBottomOf="@+id/stat_detail_2" />

    <TextView
        android:id="@+id/stat_2"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:maxLines="1"
        android:text="243"
        android:textColor="#777"
        android:textSize="22sp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />

    <TextView
        android:id="@+id/stat_detail_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxLines="1"
        android:text="Calories Burned"
        android:textColor="#777"
        android:textSize="12sp"
        app:layout_constraintTop_toBottomOf="@+id/stat_2"
        app:layout_constraintStart_toStartOf="@+id/stat_2"
        app:layout_constraintEnd_toEndOf="@+id/stat_2" />

    <View
        android:id="@+id/divider_2"
        android:layout_width="1dp"
        android:layout_height="0dp"
        android:layout_marginStart="16dp"
        android:background="#ccc"
        app:layout_constraintBottom_toBottomOf="@+id/stat_detail_2"
        app:layout_constraintStart_toEndOf="@+id/stat_2"
        app:layout_constraintTop_toTopOf="@+id/stat_2" />

    <TextView
        android:id="@+id/stat_3"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:gravity="center"
        android:maxLines="1"
        android:text="3200"
        android:textColor="#777"
        android:textSize="22sp"
        app:layout_constraintTop_toTopOf="@+id/stat_2"
        app:layout_constraintStart_toEndOf="@+id/divider_2" />

    <TextView
        android:id="@+id/stat_detail_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxLines="1"
        android:text="Steps"
        android:textColor="#777"
        android:textSize="12sp"
        app:layout_constraintTop_toBottomOf="@+id/stat_3"
        app:layout_constraintStart_toStartOf="@+id/stat_3"
        app:layout_constraintEnd_toEndOf="@+id/stat_3" />

</android.support.constraint.ConstraintLayout>

References
https://stackoverflow.com/questions/45220013/constraint-layout-vertical-align-center

How to make ConstraintLayout work with percentage values

Use: a guideline with app:layout_constraintGuide_percent like this:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.3" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Hello text"
        app:layout_constraintLeft_toRightOf="@id/guideline"
        app:layout_constraintRight_toRightOf="parent" />

</android.support.constraint.ConstraintLayout>

And then you can use this guideline as anchor points for other views.

Two minor but important notes:

  • TextView width should be 0dp i.e. match constraint and not match parent
  • Guideline orientation should be vertical not horizontal

References
https://stackoverflow.com/questions/42958168/constraint-layout-with-percentage-not-working-as-expected
https://stackoverflow.com/questions/37318228/how-to-make-constraintlayout-work-with-percentage-values

Transition animations between activities on Android above Lollipop

styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:windowContentTransitions" tools:targetApi="lollipop">true</item>
    </style>

Caller Activity

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(this).toBundle();
            startActivity(intent, bundle);
        } else {
            startActivity(intent);
        }

Calling Activity

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Slide transition=new Slide();
            transition.setDuration(300);
            transition.setSlideEdge(Gravity.BOTTOM);
            transition.setMode(Visibility.MODE_IN);
            getWindow().setEnterTransition(transition);
        }

References
https://stackoverflow.com/questions/35064342/activity-transitions-not-working
https://developer.android.com/training/material/animations.html
https://github.com/lgvalle/Material-Animations

How to Install and Secure the Mosquitto MQTT Messaging Broker on Ubuntu 16.04

Installing Mosquitto

sudo add-apt-repository ppa:mosquitto-dev/mosquitto-ppa
sudo apt-get update
sudo apt-get install mosquitto mosquitto-clients

Installing Certbot for Let’s Encrypt Certificates

sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot

Running Certbot

sudo ufw allow 80
sudo ufw allow 443
sudo certbot certonly --standalone

Enter your domain : mqtt.example.com

Setting up Certbot Automatic Renewals

sudo crontab -e
. . .
15 3 * * * certbot renew --noninteractive --post-hook "systemctl restart mosquitto"

Configuring MQTT Passwords

sudo mosquitto_passwd -c /etc/mosquitto/passwd sammy
sudo nano /etc/mosquitto/conf.d/default.conf
allow_anonymous false
password_file /etc/mosquitto/passwd
sudo systemctl restart mosquitto

Configuring MQTT SSL

sudo nano /etc/mosquitto/conf.d/default.conf
. . .
listener 1883 localhost

listener 8883
certfile /etc/letsencrypt/live/mqtt.example.com/cert.pem
cafile /etc/letsencrypt/live/mqtt.example.com/chain.pem
keyfile /etc/letsencrypt/live/mqtt.example.com/privkey.pem
sudo systemctl restart mosquitto
sudo ufw allow 8883

References
https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-the-mosquitto-mqtt-messaging-broker-on-ubuntu-16-04

Filter RecyclerView by placing a SearchView on Toolbar

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // show option menu for current activity

        getMenuInflater().inflate(R.menu.search_lab_tests, menu);

        MenuItem menuItem = menu.findItem(R.id.itemSearchTests);
        final SearchView searchView = (SearchView) menuItem.getActionView();
        
        // perform search when text changes
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {

                searchData(newText);
                return true;
            }
        });

        //return super.onCreateOptionsMenu(menu);
        return true;
    }

References
https://www.youtube.com/watch?v=j9_hcfWVkIc