Android RecyclerView OnScroll Show Hide Toolbar BottomNavigationView

In the previous tutorial we have seen how to show hide toolbar on scrolling reyclerview , In this tutorial we will see how to show hide both toolbar and bottomnavigationview on scrolling reyclerview . 
Here we will use CoordinatorLayout as the parent layout and place Toolbar , RecyclerView and BottomNavigationView as child view. 
 



CoordinatorLayout:


CoordinatorLayout is a super-powered FrameLayout , CoordinatorLayout is intended for two primary use cases .
  • As a top-level application decor layout .
  • As a container for a specific interaction with one or more child views .


XML Layout


file : activity_main.xml
<androidx.coordinatorlayout.widget.CoordinatorLayout 
    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">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_scrollFlags="scroll|enterAlways" />

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:background="?android:attr/windowBackground"
        app:layout_behavior="com.tutorialsbuzz.recyclerviewbottomnavshowhide.BottomNavigationBehavior"
        app:menu="@menu/bottom_nav_menu" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Specifying Scroll Behaviors


1. For Toolbar widget set the layout scroll flag  
       app:layout_scrollFlags="scroll|enterAlways" .

2. For RecyclerView Set the layout behavior 
   app:layout_behavior="@string/appbar_scrolling_view_behavior" .

3. For BottomNavigationView Set the custom layout behavior 
        app:layout_behavior="pkg.BottomNavigationBehavior" .

Custom Layout Behaviors For BottomNavigationBehavior


file : BottomNavigationBehavior.kt
package com.tutorialsbuzz.recyclerviewbottomnavshowhide

import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.ViewCompat
import kotlin.math.max
import kotlin.math.min

class BottomNavigationBehavior<V : View>(context: Context, attrs: AttributeSet) :
    CoordinatorLayout.Behavior<V>(context, attrs) {

    override fun onStartNestedScroll(
        coordinatorLayout: CoordinatorLayout,
        child: V,
        directTargetChild: View,
        target: View,
        axes: Int,
        type: Int
    ): Boolean {
        return axes == ViewCompat.SCROLL_AXIS_VERTICAL
    }

    override fun onNestedPreScroll(
        coordinatorLayout: CoordinatorLayout,
        child: V,
        target: View,
        dx: Int,
        dy: Int,
        consumed: IntArray,
        type: Int
    ) {
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)
        child.translationY = max(0f, min(child.height.toFloat(), child.translationY + dy))
    }
}


Setting Up RecyclerView


1. XML Layout for RecyclerView Row Item 
 
file : row_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/txt"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="8dp"
    android:paddingTop="16dp"
    android:paddingRight="8dp"
    android:paddingBottom="16dp"
    android:textSize="20sp" />

2. Data class 

file : Model.kt
package com.tutorialsbuzz.recyclerviewbottomnavshowhide

data class Model(val name: String) {}

3. ViewHolder Adapter for RecyclerView 

file : CustomAdapter.kt
package com.tutorialsbuzz.recyclerviewbottomnavshowhide

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.row_item.view.*

class CustomAdapter(val modelList: List<Model>, val context: Context) :
    RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        (holder as ViewHolder).bind(modelList.get(position));
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        return ViewHolder(layoutInflater.inflate(R.layout.row_item, parent, false))
    }

    override fun getItemCount(): Int {
        return modelList.size
    }

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(model: Model): Unit {
            itemView.txt.text = model.name
        }
    }

}

Style


Add the below style property for the Activity theme in which your implementing scroll behavior
 <item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>

And call setSupportActionBar(toolbar) inside activity onCreate by passing toolbar reference.

Activity


In MainActivity we will initialize and set adapter to reyclerview . 

file : MainActivity.kt  
package com.tutorialsbuzz.recyclerviewbottomnavshowhide

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.activity_main.*
import java.util.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)

        recyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
        recyclerView.addItemDecoration(SimpleDividerItemDecoration(this))

        val adapter = CustomAdapter(getCountries(), this)
        recyclerView.adapter = adapter;

    }

    private fun getCountries(): MutableList<Model> {
        val mdList = mutableListOf<Model>()
        for (countryISO in Locale.getISOCountries()) {
            val locale = Locale("", countryISO)
            if (!locale.displayCountry.isEmpty()) {
                mdList.add(Model(locale.displayCountry + "  " + counrtyFlag(countryISO)) )
            }
        }
        return mdList
    }

    private fun counrtyFlag(countryCode: String): String {
        val flagOffset = 0x1F1E6
        val asciiOffset = 0x41
        val firstChar = Character.codePointAt(countryCode, 0) - asciiOffset + flagOffset
        val secondChar = Character.codePointAt(countryCode, 1) - asciiOffset + flagOffset
        val flag =
            (String(Character.toChars(firstChar)) + String(Character.toChars(secondChar)))

        return flag
    }

}

No comments:

Post a Comment