Different colors for selected tab in BottomNavigationView in Android Kotlin(Programmatically)

Many times we need to use different colors for the selected tab in BottomNavigationView, displayed in the picture below.

Different colors for selected tab in BottomNavigationView in Android
Different colors for selected tab in BottomNavigationView in Android

Currently you can set only on color for selected tab from xml layout like this, using these 2 properties: app:itemIconTint and app:itemTextColor

<com.google.android.material.bottomnavigation.BottomNavigationView
  android:id="@+id/bnv"
  android:layout_width="0dp"
  android:layout_height="wrap_content"
  android:background="@android:color/white"
  app:itemIconTint="@color/color_bnv1"
  app:itemTextColor="@color/color_bnv1"
  app:labelVisibilityMode="labeled"
  app:layout_constraintBottom_toBottomOf="parent"
  app:layout_constraintEnd_toEndOf="parent"
  app:layout_constraintStart_toStartOf="parent"
  app:menu="@menu/menu_bottom_navigation_view" />

Here you can see we use @color/color_bnv1 for both property which is a color state selector from res/color directory. Here is the implementation for that.

<!-- res/color/color_bnv1.xml -->
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:color="@color/colorTab1" android:state_checked="true" />
  <!-- @color/colorTab1 = #006064 //define this in your res/values/color.xml or change the color directly here -->
  <item android:color="@android:color/darker_gray" android:state_checked="false" />
</selector>

Now for the above code, you see the result like this,

BottomNavigationView in Android
BottomNavigationView in Android

Now we need to apply different app:itemIconTint and app:itemTextColor when each tab is selected. So we apply both of these properties to the BottomNavigationView programmatically at runtime in our activity file in Kotlin.

For that we need use setOnNavigationItemSelectedListener from BottomNavigationView, which will give us the event when any tab is selected by user.

bnv.setOnNavigationItemSelectedListener {
  when (it.itemId) {
    R.id.action_tab1 -> {
      
    }
    R.id.action_tab2 -> {
      
    }
    R.id.action_tab3 -> {
      
    }
  }
  true
}

We will use the same file @color/color_bnv1 here. But here, we need to create 3 such different files for the colors we need. So we will create @color/color_bnv2 and @color/color_bnv3 in res/color, which should looks like this.

<!-- res/color/color_bnv2.xml -->
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:color="@color/colorTab2" android:state_checked="true" />
  <!-- @color/colorTab2 = #BF360C //define this in your res/values/color.xml or change the color directly here -->
  <item android:color="@android:color/darker_gray" android:state_checked="false" />
</selector>
<!-- res/color/color_bnv3.xml -->
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:color="@color/colorTab3" android:state_checked="true" />
  <!-- @color/colorTab3 = #4A148C //define this in your res/values/color.xml or change the color directly here -->
  <item android:color="@android:color/darker_gray" android:state_checked="false" />
</selector>

Now here we will set both properties using its Kotlin syntax which is itemIconTintList and itemTextColor for BottomNavigationView. We use the same @color/color_bnv1, @color/color_bnv2 and @color/color_bnv3 for each of the tab selected.

bnv.setOnNavigationItemSelectedListener {
  when (it.itemId) {
    R.id.action_tab1 -> {
      tv.text = getString(R.string.str_bnv_tab1) //"Tab 1"
      tv.setTextColor(ContextCompat.getColor(this, R.color.colorTab1))
      bnv.itemIconTintList = ContextCompat.getColorStateList(this, R.color.color_bnv1)
      bnv.itemTextColor = ContextCompat.getColorStateList(this, R.color.color_bnv1)
    }
    R.id.action_tab2 -> {
      tv.text = getString(R.string.str_bnv_tab2) //"Tab 2"
      tv.setTextColor(ContextCompat.getColor(this, R.color.colorTab2))
      bnv.itemIconTintList = ContextCompat.getColorStateList(this, R.color.color_bnv2)
      bnv.itemTextColor = ContextCompat.getColorStateList(this, R.color.color_bnv2)
    }
    R.id.action_tab3 -> {
      tv.text = getString(R.string.str_bnv_tab3) //"Tab 3"
      tv.setTextColor(ContextCompat.getColor(this, R.color.colorTab3))
      bnv.itemIconTintList = ContextCompat.getColorStateList(this, R.color.color_bnv3)
      bnv.itemTextColor = ContextCompat.getColorStateList(this, R.color.color_bnv3)
    }
  }
  true
}

When the user opens the app for the first time, you can use the following code that will preselect the desired tab and will execute the listener for that.

bnv.selectedItemId = R.id.action_tab1

You can find the whole code in my github repo: https://github.com/dakshbhatt21/a-computer-engineer

Draw line on Canvas in Android

You can draw different type of line on Canvas in Android. You can change it’s color, stroke, effect, etc. Here we will see the basics of drawing line on Canvas.

Checkout the basics of Canvas if you are new to Canvas: Draw Canvas on ImageView

Here is the example of different parameters you can apply to draw a line on Canvas in Android.

device-2016-08-23-003351
Draw line on Canvas
//simple line
Paint p1 = new Paint();
p1.setAntiAlias(true);
p1.setColor(Color.BLACK);
p1.setStrokeWidth(10);
canvas.drawLine(10, 40, 400, 40, p1);

//line with color
Paint p2 = new Paint();
p2.setAntiAlias(true);
p2.setColor(Color.RED);
p2.setStrokeWidth(10);
canvas.drawLine(10, 80, 400, 80, p2);

//line with round ends
Paint p3 = new Paint();
p3.setAntiAlias(true);
p3.setColor(Color.BLUE);
p3.setStrokeWidth(10);
p3.setStrokeCap(Paint.Cap.ROUND);
canvas.drawLine(10, 120, 400, 120, p3);

//slanted line
Paint p4 = new Paint();
p4.setAntiAlias(true);
p4.setColor(Color.GREEN);
p4.setStrokeWidth(10);
canvas.drawLine(10, 160, 400, 200, p4);

Here we use AntiAlias flag to true to remove distortion in the lines.

Extract colors from image(bitmap) using Palette in Android

When open the profile page of any person or group in Whatsapp, you will find that the color of the toolbar at top uses the color from the DP of the user or group. It looks good when you use extracted colors from image in your layout. Your layout will blend with the image and other content.

So here we can extract different colors from any image(bitmap) used in our application and use those colors effectively in our app throughout.

Screenshot_1468609451
Main Color Profiles

First of all there are main 6 type of color profiles in the image that we can extract.

  • Vibrant
  • Vibrant Dark
  • Vibrant Light
  • Muted
  • Muted Dark
  • Muted Light

Most used profile from above are Vibrant and Vibrant Dark. The reason is, vibrant colors are pure, bright, intense, saturated and high chroma color. They stand out in the image and easy to point out. Now if we use those colors in the layout along with the image, it will give a great look. Whatsapp is the best example of it as we discussed earlier.

Every profile(swatch) gives us following information that we can use in the application.

  • population of that color in image
  • hue, saturation, lightness
  • body text color with sufficient contrast with the main color
  • title text color with sufficient contrast with the main color

Now we look at the code to get the Palette from bitmap.

Bitmap b = null;
b = BitmapFactory.decodeResource(getResources(), R.drawable.img1);
Palette p = Palette.from(b).generate();

Here we get the Palette from image(bitmap). Now we extract main 6 different kind of color profile(swatch) from it.

Palette.Swatch psVibrant = p.getVibrantSwatch();
Palette.Swatch psVibrantLight = p.getLightVibrantSwatch();
Palette.Swatch psVibrantDark = p.getDarkVibrantSwatch();
Palette.Swatch psMuted = p.getMutedSwatch();
Palette.Swatch psMutedLight = p.getLightMutedSwatch();
Palette.Swatch psMutedDark = p.getDarkMutedSwatch();

Now we will extract 4 different values from these swatch as described earlier in the article. Here we will take psVibrant as an example.

int color = psVibrant.getRgb();
int population = psVibrant.getPopulation();
float[] hsl = psVibrant.getHsl();
int bodyTextColor = psVibrant.getBodyTextColor();
int titleTextColor = psVibrant.getTitleTextColor();

You can also get other colors from image other than above 6 by following code snippet.

List&lt;Palette.Swatch&gt; pss;
pss = p.getSwatches();
for(int j = 0; j &lt; pss.size(); j++) {
  Palette.Swatch ps = pss.get(j);
  int color = ps.getRgb();
  int population = ps.getPopulation();
  float[] hsl = ps.getHsl();
  int bodyTextColor = ps.getBodyTextColor();
  int titleTextColor = ps.getTitleTextColor();
}
Screenshot_1468609457
Other Color Profiles