DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Introduction to Android App Development With Kotlin: Input Validation and Navigation (Part 5)

Introduction to Android App Development With Kotlin: Input Validation and Navigation (Part 5)

Learn more about input validation and navigation in Kotlin.

Łukasz Mądrzak user avatar by
Łukasz Mądrzak
CORE ·
Feb. 22, 19 · Tutorial
Like (6)
Save
Tweet
Share
16.66K Views

Join the DZone community and get the full member experience.

Join For Free

Most apps must implement some form of navigation. Whenever we want to do something in an app, it’s quite normal that we must navigate to another screen. Also, when an app takes in user input, it should be validated so that we don’t end up with blank records in a database. Those are the two things that we’ll be discussing in today’s episode of our journey towards effective Android app development.

Lesson 5

Input Validation

Before we accept user input, we must set the rules. For example:

  • The input may be either optional or required,
  • It may not consist of just empty spaces,
  • It must be of a certain length, minimum 1 character and maximum of say 20,
  • It may be either numeric or alphabetical,
  • It must be an email,
  • And so forth.

Because we are only accepting movie titles in our app for the moment, we’ll set the rules as follows:

  • A title is required
  • Minimum length of the input is 1 character
  • Maximum length of the input is 30 characters
  • Title consisting only out of whitespaces will not be accepted

If either one of the above rules is not satisfied, we’ll prompt the user with an appropriate message.

In the NewMovieFragment, inside our button listener, let’s assign user input to a read-only variable.

val input = editText.text.toString()


Let’s check if it’s empty, and if it is, we’ll let the user know that that’s not good enough. The code below will make sure that the first two rules are satisfied.

if (input.isEmpty()) {
    Toast.makeText(activity, "Title required", Toast.LENGTH_SHORT).show()
    return@setOnClickListener
}


Next, let’s make sure that the input is not longer than 30 characters.

if (input.length > 30) {
    Toast.makeText(activity, "Title too long", Toast.LENGTH_SHORT).show()
    return@setOnClickListener
}


We’re almost there. We stopped users from trying to submit empty titles as well as titles that are too long. However, there’s still a weakness in our validation method. If the user types in a few empty spaces, they bypass our rigorous set of rules, which is not desirable. This is where the trim() method comes to our rescue. We'll call it on the string fetched fromeditText. Here’s the official description of the trim() method.

“Returns a string having leading and trailing whitespace removed.”
val input = editText.text.toString().trim()


If the user tries to input “ “ (4 whitespaces), they will now be greeted by a “Title required” message.

This is what our complete listener looks like:

button.setOnClickListener {
    val input = editText.text.toString().trim()

    if (input.isEmpty()) {
        Toast.makeText(activity, "Title required", Toast.LENGTH_SHORT).show()
        return@setOnClickListener
    }

    if (input.length > 30) {
        Toast.makeText(activity, "Title too long", Toast.LENGTH_SHORT).show()
        return@setOnClickListener
    }


    Toast.makeText(activity, "$input entered", Toast.LENGTH_SHORT).show()
}


Now that we’ve successfully validated the user input, we should store it in a database. We won’t do that now, but we’ll come back to do it once we cover some basics about Room, which is coming up in one of the next few lessons.

Navigation

For now, let’s pretend that we have successfully stored the user input. What should happen next? In my opinion, the app should take the user to a screen listing all of their movie title entries. That means that we need a fragment that will list all of the items in the database. Again, there is no database yet, so for now, we’ll just create the fragment.


Create MovieListFragment in the same fashion as previously and let’s clean it up by removing arguments but keeping the listener. You should be left with the same as below:

class MovieListFragment : Fragment() {

    private var listener: OnFragmentInteractionListener? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_movie_list, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        btnAdd.setOnClickListener {
            listener?.goToNewMovieFragment()
        }
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        if (context is OnFragmentInteractionListener) {
            listener = context
        } else {
            throw RuntimeException(context.toString() + " must implement OnFragmentInteractionListener")
        }
    }

    override fun onDetach() {
        super.onDetach()
        listener = null
    }


    interface OnFragmentInteractionListener {
        fun goToNewMovieFragment()
    }

    companion object {

        @JvmStatic
        fun newInstance() = MovieListFragment()
    }
}


Notice that addBtn has a click listener attached to it, and when called, it triggers theOnFragmentInteractionListener method, goToNewMovieFragment(). Naturally, our MainActivity must implement this method. We’ll do that in a second.

Let’s adjust the layout file to make it clear what fragment we’re looking at when the app is running. This new fragment will use RelativeLayout instead of LinearLayout. The reason for it is that RelativeLayout gives us access to attributes such as layout_alignParentBottom, which allows us to put a button on the bottom of the screen, regardless of its height.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:padding="12dp"
                tools:context=".MovieListFragment">

    <TextView android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:textSize="30sp"
              android:text="Movie List"
    />


    <Button android:id="@+id/btnAdd"
            android:text="Add new movie"
            android:layout_alignParentBottom="true"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

</RelativeLayout>


Let’s head to the NewMovieFragment to update the OnFragmentInteractionListener method, so its name is more appropriate, i.e. goToMovieListFragment() with no arguments.

interface OnFragmentInteractionListener {
    fun goToMovieListFragment()
}


Now, open the MainActivity as we have some refactoring to do and navigation code to write!

MainActivitymust now implement two interfaces

class MainActivity : AppCompatActivity(), NewMovieFragment.OnFragmentInteractionListener,
    MovieListFragment.OnFragmentInteractionListener {


We must refactor the code in the onCreate method. Move it to its own method called goToNewMovieFragment().

override fun goToNewMovieFragment() {
        val manager = supportFragmentManager
        val transaction = manager.beginTransaction()
        transaction.replace(R.id.flContent, NewMovieFragment.newInstance())
        transaction.commit()
    }


We will also require a goToMovieListFragment()method, which will be called upon successful storage of user input.

override fun goToMovieListFragment() {
    val manager = supportFragmentManager
    val transaction = manager.beginTransaction()
    transaction.replace(R.id.flContent, MovieListFragment.newInstance())
    transaction.commit()
}


Let’s call this method in the onCreate, as presumably, our users would like to see the list of their movies in the app upon startup.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)


    if (savedInstanceState == null) {
        goToMovieListFragment()
    }
}


Run the app and freely navigate between the screens! Make sure to test our validation code.

Conclusion

We’ve covered a lot of ground today. You now understand how to implement navigation between multiple screens and how to do basic input validation.

The complete working code can be found in my GitHub account here.

app Android (robot) Kotlin (programming language)

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • How To Create and Edit Excel XLSX Documents in Java
  • A Brief Overview of the Spring Cloud Framework
  • How To Check Docker Images for Vulnerabilities
  • How Observability Is Redefining Developer Roles

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: