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

Toasts

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

Snackbar

Alerts

Views, Decorated Animated

Prefs, User Personalization, User Settings

Preferences UI

Shared Prefs persistence

  • In radiobutton example Anko below, expands "RED" to COLOR.red .. 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() }

Settings

Perms

Dialogs

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 android.support.v7.app.AlertDialog 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 -> }) builder.show() }

// ~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
import android.support.v7.app.AlertDialog


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

    dialog.setCancelable(false)
    dialog.setPositiveButton("validate",{ dialogInterface: DialogInterface, i: Int -> })
    val customDialog = dialog.create()
    customDialog.show()
    customDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener({
        if (et_number.text.length > 5)
            customDialog.dismiss()
        else
            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="http://schemas.android.com/apk/res/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" />
</RelativeLayout>

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"/>

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

    Handler().postDelayed({dialog.dismiss()},5000)

Drawers

Sliding Drawer

Nav, Toolbars, User Interaction

Toolbars AB

EX: Java Toolbar Ex with Search Action

  • https://www.simplifiedcoding.net/android-toolbar-example/

THEORY

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")
    setSupportActionBar(toolbar)

4 Menu setup Sequence - onCreateOptionsMenu, onOptionsItemSelected(

override fun onCreateOptionsMenu(Menu menu) : boolean {
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate(R.menu.menu, menu);
    return true;
}
override fun onOptionsItemSelected(MenuItem item): boolean {
    when(item.getItemId())
        R.id.menuAbout    -> Toast.makeText(this, "You clicked about", Toast.LENGTH_SHORT).show()
        R.id.menuSettings -> Toast.makeText(this, "You clicked settings", Toast.LENGTH_SHORT).show()
        R.id.menuLogout   -> 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(R.id.menuSearch); 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; } });

Bottombar

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) {
            R.id.navigation_home -&gt; {
                message.setText(R.string.title_home)
                return@OnNavigationItemSelectedListener true
            }
            R.id.navigation_dashboard -&gt; {
                message.setText(R.string.title_dashboard)
                return@OnNavigationItemSelectedListener true
            }
            R.id.navigation_notifications -&gt; {
                message.setText(R.string.title_notifications)
                return@OnNavigationItemSelectedListener true
            }
        }
        false
}

Fab Buttons

r

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="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"&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;
    &lt;/group&gt;
&lt;/menu&gt;

import android.view.Menu
import android.view.MenuItem
// inside activity
override fun onCreateOptionsMenu(menu: Menu?): Boolean { // inflate menu - can dynamically create menu here :)
    super.onCreateOptionsMenu(menu)
    menuInflater.inflate(R.menu.main,menu)
    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(2)?.setEnabled(false)
    menu?.getItem(3)?.isVisible = false
    return super.onPrepareOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
    var selectedOption = ""
    when(item?.itemId){
        R.id.about_us -&gt; selectedOption ="About Us"
        R.id.help -&gt; selectedOption ="Help"
        R.id.item_1 -&gt; selectedOption ="Item 1"
        R.id.item_2 -&gt; selectedOption ="Item 2"
        R.id.item_3 -&gt; selectedOption ="Item 3"
    }
    Toast.makeText(this,"Option : " + selectedOption,Toast.LENGTH_SHORT).show()
    return super.onOptionsItemSelected(item)
}

Context Menus

EX: CONTEXT MENU

  • ~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(R.menu.testpopup) popup.setOnMenuItemClickListener { Toast.makeText(this, "Item : " + it.title,Toast.LENGTH_SHORT).show() true //return true? } popup.show() } // 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="http://schemas.android.com/apk/res/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;
&lt;/menu&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(R.id.imageView) 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"?>

Engage

Intro


0 comments

There are no comments yet

Add new comment

Similar posts

SOA Api Metadata

Serverless Computing

Android Layouts Design 101

Drawing, Canvas in Kotlin