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

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

Copy database from assets to databases folder on Android

ContextWrapper cw =new ContextWrapper(getApplicationContext());
DB_PATH =cw.getFilesDir().getAbsolutePath()+ "/databases/";
private void copyDataBase()
    {
        Log.i("Database",
                "New database is being copied to device!");
        byte[] buffer = new byte[1024];
        OutputStream myOutput = null;
        int length;
        // Open your local db as the input stream
        InputStream myInput = null;
        try
        {
            myInput =myContext.getAssets().open(DB_NAME);
            // transfer bytes from the inputfile to the
            // outputfile
            myOutput =new FileOutputStream(DB_PATH+ DB_NAME);
            while((length = myInput.read(buffer)) > 0)
            {
                myOutput.write(buffer, 0, length);
            }
            myOutput.close();
            myOutput.flush();
            myInput.close();
            Log.i("Database",
                    "New database has been copied to device!");


        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }

References
https://stackoverflow.com/questions/18805874/copy-database-from-assets-to-databases-folder

Install Realm Object Server on Ubuntu 16.04

// Ubuntu 16.04 (64 bit; 32-bit is not supported)
//It is recommended that you install the server as a normal user.

sudo apt-get update

sudo apt-get install build-essential libssl-dev

sudo apt-get install python

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.4/install.sh | bash

// Force current session to know changes or logout and log back in
source ~/.profile

nvm install --lts

npm install -g node-gyp
npm install -g realm-object-server

References
https://docs.realm.io/server/installation/manual-install

Data Browser for ObjectBox

// ObjectBox browser dependencies must be set before applying ObjectBox plugin so it does not add objectbox-android
// (would result in two conflicting versions, e.g. "Duplicate files copied in APK lib/armeabi-v7a/libobjectbox.so").
dependencies {
    debugCompile "io.objectbox:objectbox-android-objectbrowser:$objectboxVersion"
    releaseCompile "io.objectbox:objectbox-android:$objectboxVersion"
}
<uses-permission android:name="android.permission.INTERNET" />
if (BuildConfig.DEBUG) {
     new AndroidObjectBrowser(boxStore).start(this);
}
adb forward tcp:8090 tcp:8090

References
http://objectbox.io/objectbox-1-1-introduces-data-browser/