Android Navigation in Kotlin

By pjain      Published Dec. 16, 2019, 8:13 a.m. in blog Programming   

Navigation to App Level and User Interaction

GUI Layout Flow, Responsive

User Interaction, Engagement, Toasts


  • Toast import android.widget.Toast .. Toast.makeText(this,"Option : " + selectedOption,Toast.LENGTH_SHORT).show()



Views, Decorated Animated

Prefs, User Personalization, User Settings

Preferences UI

Shared Prefs persistence

  • In radiobutton example Anko below, expands "RED" to .. to vertical layout HOW TO HANDLE ROTATE config: when the BG current is lost? - save & restore BGcolor-cur when activity is recreated o Red o Black * White o Blue ..

    val PREFS_FILENAME = "com.teamtreehouse.colorsarefun.prefs" val BACKGROUND_COLOR = "background_color" var prefs: SharedPreferences? = null

    override fun onCreate(savedInstanceState: Bundle?) { .. prefs = this.getSharedPreferences(PREFS_FILENAME, 0) val bgColor = prefs!!.getInt(BACKGROUND_COLOR, Color.BLACK) verticalLayout {..} // anko dynamically generates color key-string and COLOR.XXX value } private fun selectColor(view: View, color: Int) { // on click on o ColorName .. sets bg AND saves prefs .. view.backgroundColor = color val editor = prefs!!.edit() editor.putInt(BACKGROUND_COLOR, color) editor.apply() }




r Dialogs

Dialogs EX: within above class

// AlertDialogEx trap on back pressed to confirm dialog Are you sure! // ~wmkt/AlertDialogExample Do you want to close the app? // import android.content.DialogInterface import onCreate.. override fun onBackPressed() { val builder = AlertDialog.Builder(this) builder.setTitle("Are you sure!") builder.setMessage("Do you want to close the app?") builder.setPositiveButton("Yes",{ dialogInterface: DialogInterface, i: Int -> finish() }) builder.setNegativeButton("No",{ dialogInterface: DialogInterface, i: Int -> }) }

// ~wmkt/CustomAlertDialog WITH VALIDATION on number and > 5 digits, else toast error shown //- uxd - on boot alert is shown right away - not connected to button .. // Note: how to do the automatic view binding for inflated dialog? see popup Window example for this! // ImageView // _et_______ //

import android.content.DialogInterface

    val dialog = AlertDialog.Builder(this)
    val dialogView = layoutInflater.inflate(R.layout.custom_dialog,null)
    val et_number = dialogView.findViewById<EditText>(

    dialog.setPositiveButton("validate",{ dialogInterface: DialogInterface, i: Int -> })
    val customDialog = dialog.create()
        if (et_number.text.length > 5)
            Toast.makeText(baseContext, "Number not valid", Toast.LENGTH_SHORT).show()

// custom_dialog.xml  -- inflated into dialog builder .. 
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android=""
    android:layout_width="match_parent" android:layout_height="match_parent">
    <ImageView android:id="@+id/iv_icon" android:src="@mipmap/ic_launcher"
        android:layout_width="64dp" android:layout_height="64dp" android:layout_centerHorizontal="true"/>
    <EditText android:id="@+id/et_number" android:inputType="number" 
        android:layout_width="match_parent" android:layout_height="wrap_content"
        android:layout_below="@+id/iv_icon" android:layout_marginTop="10dp" />

ProgressDialog in popup that goes away

// ~wmkt/ProgressDialog

Main - _tv hello_
progress_dialog.xml LLh  OOOOOOO------  message
    <ProgressBar android:layout_width="48dp" android:layout_height="48dp" android:layout_margin="16dp"/>

    val builder = AlertDialog.Builder(this)
    val dialogView = layoutInflater.inflate(R.layout.progress_dialog,null)
    val message = dialogView.findViewById<TextView>(
    message.text = "Downloading..."
    val dialog = builder.create()



Sliding Drawer

Nav, Toolbars, User Interaction

Toolbars AB

EX: Java Toolbar Ex with Search Action



TB - can be anywhere on screen - flex layout - app icon, title - nav menu are regular res/menu/tbmenu.xml - each

ACTION VIEWS - for any item (usually visible icons) - tapping will expand to in-toolbar ACTION VIEW - for example search .. event handling are processed .. for search by a searchview/searchmanager

1 Theme has to be one that has NoActionBar.. in res->values->styles.xml vv--was--> Theme.AppCompat.Light.DarkActionBar

2 Now add Toolbar is EXLICIT part of activity

3 Configure Toolbar in onCreate .. set title and set as Action Bar replacement

onCreate .. 
    toolbar.setTitle("My title")

4 Menu setup Sequence - onCreateOptionsMenu, onOptionsItemSelected(

override fun onCreateOptionsMenu(Menu menu) : boolean {
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate(, menu);
    return true;
override fun onOptionsItemSelected(MenuItem item): boolean {
    when(item.getItemId())    -> Toast.makeText(this, "You clicked about", Toast.LENGTH_SHORT).show() -> Toast.makeText(this, "You clicked settings", Toast.LENGTH_SHORT).show()   -> Toast.makeText(this, "You clicked logout", Toast.LENGTH_SHORT).show()
    return true;
  1. Search on the Toolbar - add icon, handle click in onCreateOptionsMenu

    onCreateOptionsMenu - java way .. ... MenuItem searchViewItem = menu.findItem(; SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); final SearchView searchView = (SearchView) searchViewItem.getActionView(); searchView.setQueryHint("Search Tutorials..."); searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); //true we are making it iconified so the search input will show up after taping the search iconified //false: if you want to make it visible all the time searchView.setIconifiedByDefault(true); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { return false; //do the search here .. eg like recyclerview filter example .. } @Override public boolean onQueryTextChange(String newText) { return false; } });


Bottom Sheet

EX: Bottom Tabs Navigation

  • Uxd - message hmico tab2 tab3 <- menu/navigation.xml below .

onCreate <-- set setOnClickListener message.text = "Press Bottom to set text here" navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)

 private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item -&gt;
        when (item.itemId) {
   -&gt; {
                return@OnNavigationItemSelectedListener true
   -&gt; {
                return@OnNavigationItemSelectedListener true
   -&gt; {
                return@OnNavigationItemSelectedListener true

Fab Buttons


Option Item Menus, Popups, Context Menus

Option Item Menus

// Simple ~wmkt/MenuExample uxd AboutUsico : <-- note default is don't show & order in occurence so dont put order# // Help Item1 Item2 Item3

&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;menu xmlns:android=""xmlns:app=""&gt;
    &lt;item android:title="About Us" android:id="@+id/about_us" android:icon="@mipmap/ic_launcher" app:showAsAction="always"/&gt;
    &lt;item android:title="Help" android:id="@+id/help"/&gt;
    &lt;group android:id="@+id/menu_items"&gt;
        &lt;item android:title="Item 1" android:id="@+id/item_1"/&gt;
        &lt;item android:title="Item 2" android:id="@+id/item_2"/&gt;
        &lt;item android:title="Item 3"android:id="@+id/item_3"/&gt;

import android.view.Menu
import android.view.MenuItem
// inside activity
override fun onCreateOptionsMenu(menu: Menu?): Boolean { // inflate menu - can dynamically create menu here :)
    return true
    // Mainly used to enable disable .. here index arg 2, 3 is lame .. 0:About 1:Help 2:item1, 3:Item2 
override fun onPrepareOptionsMenu(menu: Menu?): Boolean { // menu clicked - the getItem(2) seems bad practice to hardwire!
    menu?.getItem(3)?.isVisible = false
    return super.onPrepareOptionsMenu(menu)
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
    var selectedOption = ""
    when(item?.itemId){ -&gt; selectedOption ="About Us" -&gt; selectedOption ="Help" -&gt; selectedOption ="Item 1" -&gt; selectedOption ="Item 2" -&gt; selectedOption ="Item 3"
    Toast.makeText(this,"Option : " + selectedOption,Toast.LENGTH_SHORT).show()
    return super.onOptionsItemSelected(item)

Context Menus


  • ~wmkt/PopupMenuAndWindow
  • Ex1 popup menu inflated here import android.widget.PopupMenu

onCreate() { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main) val popup = PopupMenu(this,btn_show_popup) popup.inflate( popup.setOnMenuItemClickListener { Toast.makeText(this, "Item : " + it.title,Toast.LENGTH_SHORT).show() true //return true? } } // activity_main.xml has a button constraintLayout > <Button id:btn_show_popup text="show popup"

// menu/testpopup.xml - inflaed above.. 
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;menu xmlns:android=""&gt;
    &lt;item android:title="Item 1" android:id="@+id/menu_item_1"/&gt;
    &lt;item android:title="Item 2" android:id="@+id/menu_item_2"/&gt;
    &lt;item android:title="Item 3" android:id="@+id/menu_item_3"/&gt;
  • Ex2 popup window with image inflated here import android.widget.PopupWindow

    onCreate() { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main) btn_show_popup.setOnClickListener { val window = PopupWindow(this) //Create an empty window .. val view = layoutInflater.inflate(R.layout.layout_popup,null) window.contentView = view // replace contentview of window with layout val imageView = view.findViewById( imageView.setOnClickListener { // dismisses on click window.dismiss() } window.showAsDropDown(btn_show_popup) // } }

    // layout_popup.xml is in res/layout .. as a regular view <?xml version="1.0" encoding="utf-8"?>




There are no comments yet

Add new comment

Similar posts

Serverless Computing

Android Layouts Design 101

Drawing, Canvas in Kotlin

Custom Views