Android Transition animations between activities

MainActivity.java

public class MainActivity extends AppCompatActivity {

    Button buttonShow;

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

        buttonShow= (Button) findViewById(R.id.buttonShow);

        buttonShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(MainActivity.this,AnimatedActivity.class);

                startActivity(intent);
                overridePendingTransition(R.anim.activity_back_in,R.anim.activity_back_out);
            }
        });
    }
}

 

AnimatedActivity.java

public class AnimatedActivity extends AppCompatActivity {

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

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        overridePendingTransition(R.anim.activity_back_in,R.anim.activity_back_out);
    }
}

 

References
https://github.com/mhdr/AndroidSamples/tree/master/059
https://developer.android.com/training/animation/cardflip.html

Android Working with Snackbar

build.gradle

compile 'com.android.support:appcompat-v7:25.3.0'

MainActivity.java

public class MainActivity extends AppCompatActivity {

    Button buttonShow;

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

        buttonShow= (Button) findViewById(R.id.buttonShow);

        buttonShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Snackbar.make(v,"Hello World",Snackbar.LENGTH_LONG).show();
            }
        });
    }
}

Snackbar Actions

public void showSnackbar(View view, String message, int duration)
{
    // Create snackbar
    final Snackbar snackbar = Snackbar.make(view, message, duration);

    // Set an action on it, and a handler
    snackbar.setAction("DISMISS", new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            snackbar.dismiss();
        }
    });

    snackbar.show();
}

References
https://github.com/mhdr/AndroidSamples/tree/master/058
https://spin.atomicobject.com/2017/07/10/android-snackbar-tutorial/

Android Working with Floating Action Button

build.gradle

compile 'com.android.support:design:25.3.0'

/res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.mahmood.a057.MainActivity">

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/floatingActionButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_margin="8dp"
        android:visibility="visible"
        app:elevation="8dp"
        app:fabSize="normal"
        app:backgroundTint="#FF0000"
        app:srcCompat="@drawable/ic_backup" />

</RelativeLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    FloatingActionButton floatingActionButton;

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

        floatingActionButton= (FloatingActionButton) findViewById(R.id.floatingActionButton);
        floatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this,"Hello World",Toast.LENGTH_LONG).show();
            }
        });
    }
}

Refereneces
https://github.com/mhdr/AndroidSamples/tree/master/057
https://www.youtube.com/watch?v=nt31X9RaHQU&index=3&list=PLBA5zvAwnCrAG1ghh1XRsTN-Fqh3uKpli

Android Floating Label with TextInputLayout

build.gralde

compile 'com.android.support:design:25.3.0'

/res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.mahmood.a056.MainActivity">

    <android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/editTextUserName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="text"
            android:hint="UserName"/>

    </android.support.design.widget.TextInputLayout>


    <android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <EditText
            android:id="@+id/editTextPassword"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textPassword"
            android:hint="Password"/>
    </android.support.design.widget.TextInputLayout>


</LinearLayout>

References
https://github.com/mhdr/AndroidSamples/tree/master/056

Tuning the Linux kernel for better shadowsocks network throughput

add these lines to /etc/sysctl.conf :

# max open files
fs.file-max = 51200
# max read buffer
net.core.rmem_max = 67108864
# max write buffer
net.core.wmem_max = 67108864
# default read buffer
net.core.rmem_default = 65536
# default write buffer
net.core.wmem_default = 65536
# max processor input queue
net.core.netdev_max_backlog = 250000
# max backlog
net.core.somaxconn = 4096
# resist SYN flood attacks
net.ipv4.tcp_syncookies = 1
# reuse timewait sockets when safe
net.ipv4.tcp_tw_reuse = 1
# turn off fast timewait sockets recycling
# net.ipv4.tcp_tw_recycle = 0
# short FIN timeout
net.ipv4.tcp_fin_timeout = 30
# short keepalive time
net.ipv4.tcp_keepalive_time = 1200
# outbound port range
net.ipv4.ip_local_port_range = 10000 65000
# max SYN backlog
net.ipv4.tcp_max_syn_backlog = 8192
# max timewait sockets held by system simultaneously
net.ipv4.tcp_max_tw_buckets = 5000
# turn on TCP Fast Open on both client and server side
net.ipv4.tcp_fastopen = 3
# TCP receive buffer
net.ipv4.tcp_rmem = 4096 87380 67108864
# TCP write buffer
net.ipv4.tcp_wmem = 4096 65536 67108864
# turn on path MTU discovery
net.ipv4.tcp_mtu_probing = 1

net.ipv4.tcp_timestamps=1
net.ipv4.ip_no_pmtu_disc = 1
net.ipv4.tcp_mem = 25600 51200 102400
net.ipv4.ip_default_ttl=129
sysctl -p /etc/sysctl.conf

References
https://shadowsocks.org/en/config/advanced.html
https://linode.com/docs/networking/vpn/create-a-socks5-proxy-server-with-shadowsocks-on-ubuntu-and-centos7/
https://maxlv.net/optimize-a-shadowsocks-server/

Tuning the Linux kernel for better network throughput

add these lines to /etc/sysctl.conf :

fs.file-max = 100000
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_syncookies = 1
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.core.rmem_default=65536
net.core.wmem_default=65536
net.ipv4.route.flush=1

and then :

sysctl -p /etc/sysctl.conf

References
http://www.techrepublic.com/blog/linux-and-open-source/tuning-the-linux-kernel-for-more-aggressive-network-throughput/
https://wwwx.cs.unc.edu/~sparkst/howto/network_tuning.php
https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Web_Platform/5/html/Administration_And_Configuration_Guide/jgroups-perf-udpbuffer.html
http://www.nateware.com/linux-network-tuning-for-2013.html
http://www.slashroot.in/linux-network-tcp-performance-tuning-sysctl

Android Animating ListView with LayoutTransition

MainActivity.java

public class MainActivity extends AppCompatActivity {

    ArrayList<String> listViewItems = new ArrayList<>();
    ArrayAdapter<String> adapter;
    int count = 0;

    Button buttonAdd;
    Button buttonDelete;
    ListView listView;

    LayoutTransition itemLayoutTransition;

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

        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listViewItems);

        buttonAdd = (Button) findViewById(R.id.buttonAdd);
        buttonDelete = (Button) findViewById(R.id.buttonDelete);
        listView = (ListView) findViewById(R.id.listView);

        Animator scaleUp = ObjectAnimator.ofPropertyValuesHolder((Object) null, PropertyValuesHolder.ofFloat(View.SCALE_X, 0, 1), PropertyValuesHolder.ofFloat(View.SCALE_Y, 0, 1));
        final Animator scaleDown = ObjectAnimator.ofPropertyValuesHolder((Object) null, PropertyValuesHolder.ofFloat(View.SCALE_X, 1, 0), PropertyValuesHolder.ofFloat(View.SCALE_Y, 1, 0));

        itemLayoutTransition = new LayoutTransition();

        itemLayoutTransition.enableTransitionType(LayoutTransition.CHANGING);

        //itemLayoutTransition.setAnimateParentHierarchy(false);

        //itemLayoutTransition.disableTransitionType(LayoutTransition.CHANGE_APPEARING);
        //itemLayoutTransition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
        //itemLayoutTransition.disableTransitionType(LayoutTransition.APPEARING);
        //itemLayoutTransition.disableTransitionType(LayoutTransition.DISAPPEARING);


/*        itemLayoutTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, scaleUp);
        itemLayoutTransition.setDuration(LayoutTransition.CHANGE_APPEARING,1000);
        itemLayoutTransition.setInterpolator(LayoutTransition.CHANGE_APPEARING,new OvershootInterpolator());*/

        itemLayoutTransition.setAnimator(LayoutTransition.APPEARING, scaleUp);
        itemLayoutTransition.setDuration(LayoutTransition.APPEARING,1000);
        itemLayoutTransition.setInterpolator(LayoutTransition.APPEARING,new OvershootInterpolator());

/*        itemLayoutTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, scaleDown);
        itemLayoutTransition.setDuration(LayoutTransition.CHANGE_DISAPPEARING,1000);
        itemLayoutTransition.setInterpolator(LayoutTransition.CHANGE_DISAPPEARING,new OvershootInterpolator());*/

        itemLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING, scaleDown);
        itemLayoutTransition.setDuration(LayoutTransition.DISAPPEARING,1000);
        itemLayoutTransition.setInterpolator(LayoutTransition.DISAPPEARING,new OvershootInterpolator());

        listView.setLayoutTransition(itemLayoutTransition);

        itemLayoutTransition.addTransitionListener(transitionListener);
        listView.setAdapter(adapter);

        buttonAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                count++;

                String item = String.format("Item %d", count);
                listViewItems.add(item);

                adapter.notifyDataSetChanged();
            }
        });

        buttonDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listViewItems.size() > 0) {
                    itemLayoutTransition.removeChild(listView, listView.getChildAt(0));
                }
            }
        });
    }

    LayoutTransition.TransitionListener transitionListener=new LayoutTransition.TransitionListener() {
        @Override
        public void startTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) {
            listView.setHasTransientState(true);
        }

        @Override
        public void endTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) {
            if (transitionType == LayoutTransition.DISAPPEARING) {
                if (listViewItems.size() > 0) {
                    listViewItems.remove(0);
                    adapter.notifyDataSetChanged();

                    listView.getChildAt(0).setScaleX(1f);
                    listView.getChildAt(0).setScaleY(1f);
                }
            }

            listView.setHasTransientState(false);
        }
    };
}

References
https://github.com/mhdr/AndroidSamples/tree/master/055

Android Working with Property Animation

/res/animator/fade_in.xml

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially" >
    <objectAnimator
        android:duration="1000"
        android:propertyName="alpha"
        android:valueFrom="0.0"
        android:valueTo="1.0"
        android:interpolator="@android:anim/accelerate_interpolator"/>
</set>

/res/animator/fade_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <objectAnimator
        android:duration="1000"
        android:propertyName="alpha"
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:interpolator="@android:anim/accelerate_interpolator"/>
</set>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    Button buttonFadeIn,buttonFadeOut,buttonBlink,buttonZoomIn,buttonZoomOut,buttonRotate,buttonMove,buttonSlideUp,
    buttonSlideDown,buttonBounce;
    TextView textViewFadeIn,textViewFadeOut,textViewBlink,textViewZoomIn,textViewZoomOut,textViewRotate,textViewMove,textViewSlideUp,
    textViewSlideDown,textViewBounce;

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


        buttonFadeIn= (Button) findViewById(R.id.buttonFadeIn);
        buttonFadeOut= (Button) findViewById(R.id.buttonFadeOut);
        buttonBlink= (Button) findViewById(R.id.buttonBlink);
        buttonZoomIn= (Button) findViewById(R.id.buttonZoomIn);
        buttonZoomOut= (Button) findViewById(R.id.buttonZoomOut);
        buttonRotate= (Button) findViewById(R.id.buttonRotate);
        buttonMove= (Button) findViewById(R.id.buttonMove);
        buttonSlideUp= (Button) findViewById(R.id.buttonSlideUp);
        buttonSlideDown= (Button) findViewById(R.id.buttonSlideDown);
        buttonBounce= (Button) findViewById(R.id.buttonBounce);

        textViewFadeIn= (TextView) findViewById(R.id.textViewFadeIn);
        textViewFadeOut= (TextView) findViewById(R.id.textViewFadeOut);
        textViewBlink= (TextView) findViewById(R.id.textViewBlink);
        textViewZoomIn= (TextView) findViewById(R.id.textViewZoomIn);
        textViewZoomOut= (TextView) findViewById(R.id.textViewZoomOut);
        textViewRotate= (TextView) findViewById(R.id.textViewRotate);
        textViewMove= (TextView) findViewById(R.id.textViewMove);
        textViewSlideUp= (TextView) findViewById(R.id.textViewSlideUp);
        textViewSlideDown= (TextView) findViewById(R.id.textViewSlideDown);
        textViewBounce= (TextView) findViewById(R.id.textViewBounce);


        buttonFadeIn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(MainActivity.this,
                        R.animator.fade_in);
                set.setTarget(textViewFadeIn);
                set.start();
            }
        });

        buttonFadeOut.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(MainActivity.this,
                        R.animator.fade_out);
                set.setTarget(textViewFadeOut);
                set.start();
            }
        });

        buttonBlink.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(textViewBlink,View.ALPHA,0f,1f);
                objectAnimator.setDuration(600);
                objectAnimator.setRepeatMode(ValueAnimator.REVERSE);
                objectAnimator.setRepeatCount(ValueAnimator.INFINITE);
                objectAnimator.setInterpolator(new AccelerateInterpolator());
                objectAnimator.start();
            }
        });

        buttonZoomIn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                PropertyValuesHolder propertyValuesHolder1=PropertyValuesHolder.ofFloat(View.SCALE_X,1f,2f);
                PropertyValuesHolder propertyValuesHolder2=PropertyValuesHolder.ofFloat(View.SCALE_Y,1f,2f);

                ObjectAnimator objectAnimator=ObjectAnimator.ofPropertyValuesHolder(textViewZoomIn,
                        propertyValuesHolder1,propertyValuesHolder2);

                objectAnimator.setDuration(1000);
                objectAnimator.start();
            }
        });


        buttonZoomOut.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                ValueAnimator valueAnimator1=ValueAnimator.ofFloat(1f,0.5f);
                valueAnimator1.setDuration(1000);
                valueAnimator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        textViewZoomOut.setScaleX((Float) animation.getAnimatedValue());
                    }
                });


                ValueAnimator valueAnimator2=ValueAnimator.ofFloat(1f,0.5f);
                valueAnimator2.setDuration(1000);
                valueAnimator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        textViewZoomOut.setScaleY((Float) animation.getAnimatedValue());
                    }
                });


                AnimatorSet animatorSet=new AnimatorSet();
                animatorSet.playTogether(valueAnimator1,valueAnimator2);
                animatorSet.start();
            }
        });

        buttonRotate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // to perform rotate on center of the element
                // by default : pivotX=50 and pivotY=50
                textViewRotate.setPivotX(50);
                textViewRotate.setPivotY(50);

                ValueAnimator valueAnimator1=ValueAnimator.ofFloat(0,360);
                valueAnimator1.setDuration(600);
                valueAnimator1.setInterpolator(new CycleInterpolator(0.25f));
                valueAnimator1.setRepeatMode(ValueAnimator.RESTART);
                valueAnimator1.setRepeatCount(ValueAnimator.INFINITE);
                valueAnimator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        textViewRotate.setRotation((Float) animation.getAnimatedValue());
                    }
                });

                valueAnimator1.start();
            }
        });

        buttonMove.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ValueAnimator valueAnimator1=ValueAnimator.ofFloat(0f,150f);
                valueAnimator1.setDuration(1000);
                valueAnimator1.setRepeatMode(ValueAnimator.REVERSE);
                valueAnimator1.setRepeatCount(ValueAnimator.INFINITE);
                valueAnimator1.setInterpolator(new AccelerateInterpolator());

                valueAnimator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        textViewMove.setTranslationX((Float) animation.getAnimatedValue());
                    }
                });

                valueAnimator1.start();
            }
        });

        buttonSlideUp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                textViewSlideUp.setPivotY(0);

                ValueAnimator valueAnimator1=ValueAnimator.ofFloat(1f,0f);
                valueAnimator1.setDuration(1000);
                valueAnimator1.setInterpolator(new AccelerateInterpolator());

                valueAnimator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        textViewSlideUp.setScaleY((Float) animation.getAnimatedValue());
                    }
                });

                valueAnimator1.start();
            }
        });

        buttonSlideDown.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textViewSlideDown.setPivotY(0);

                ValueAnimator valueAnimator1=ValueAnimator.ofFloat(0f,1f);
                valueAnimator1.setDuration(1000);
                valueAnimator1.setInterpolator(new AccelerateInterpolator());

                valueAnimator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        textViewSlideDown.setScaleY((Float) animation.getAnimatedValue());
                    }
                });

                valueAnimator1.start();
            }
        });

        buttonBounce.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                ValueAnimator valueAnimator1=ValueAnimator.ofFloat(0f,1f);
                valueAnimator1.setDuration(1000);
                valueAnimator1.setInterpolator(new BounceInterpolator());

                valueAnimator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        textViewBounce.setScaleY((Float) animation.getAnimatedValue());
                    }
                });

                valueAnimator1.start();
            }
        });
    }
}

References
https://github.com/mhdr/AndroidSamples/tree/master/054

Android Working with BottomNavigationView

/res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="iterator.ir.a053.MainActivity">

    <android.support.design.widget.BottomNavigationView
        android:id="@+id/bottomNavigationView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        app:itemBackground="@android:color/holo_green_light"
        app:itemIconTint="@android:color/white"
        app:itemTextColor="@android:color/black"
        app:menu="@menu/navigation_menu">

    </android.support.design.widget.BottomNavigationView>

</RelativeLayout>

/res/menu/navigation_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/itemAdd"
        android:checkable="false"
        android:enabled="true"
        android:icon="@drawable/ic_add"
        android:title="Add"
        android:visible="true"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/itemEdit"
        android:checkable="false"
        android:enabled="true"
        android:icon="@drawable/ic_edit"
        android:title="Edit"
        android:visible="true"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/itemDelete"
        android:checkable="false"
        android:enabled="true"
        android:icon="@drawable/ic_delete"
        android:title="Delete"
        android:visible="true"
        app:showAsAction="ifRoom" />
</menu>

/res/drawable/nav_item_color_state.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/white" android:state_enabled="true" />
    <item android:drawable="@color/gray" android:state_enabled="false" />
</selector>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    BottomNavigationView bottomNavigationView;

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

        bottomNavigationView= (BottomNavigationView) findViewById(R.id.bottomNavigationView);

        bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {

                item.setChecked(true);

                switch (item.getItemId())
                {
                    case R.id.itemAdd:
                        Toast.makeText(MainActivity.this,"Add",Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.itemEdit:
                        Toast.makeText(MainActivity.this,"Edit",Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.itemDelete:
                        Toast.makeText(MainActivity.this,"Delete",Toast.LENGTH_SHORT).show();
                        break;
                }

                return true;
            }
        });
    }
}

References
https://github.com/mhdr/AndroidSamples/tree/master/053
https://www.youtube.com/watch?v=wcE7IIHKfRg
https://developer.android.com/reference/android/support/design/widget/BottomNavigationView.html
https://medium.com/@hitherejoe/exploring-the-android-design-support-library-bottom-navigation-drawer-548de699e8e0#.8sgxtnkhb