Sources:
Text Tutorial
Espresso Course
is one screen of an app. In that way the activity is very similar to a window in the Windows operating system. The most specific block of the user interface is the activity. An Android app contains activities, meaning one or more screens. Examples: Login screen, sign up screen, and home screen.
An activity in Android is a specific combination of XML files and JAVA files. It is basically a container that contains the design as well as coding stuff.
XML files provide the design of the screen and JAVA files deal with all coding stuff like handles, what is happening, design files, etc. JAVA files and XML files make your activity complete.
To make an app we need activities that are bound loosely with each other. In the Android manifest we can organize the activities in parent-child relationships to aid navigation. The “main activity” is called the first activity.
Example: In social media, e-commerce, and other apps, you see the main activity whenever you open up that app.
Activities must be declared and their certain attributes must be declared in the manifest so that we can use the activities in our app. Android manifest is a file that will give you information about the application.
is a simple building block of a user interface. It is a small rectangular box that can be TextView, EditText, or even a button. It occupies the area on the screen in a rectangular area and is responsible for drawing and event handling. View is a superclass of all the graphical user interface components.
A View Group is a subclass of the ViewClass and can be considered as a superclass of Layouts. It provides an invisible container to hold the views or layouts. ViewGroup instances and views work together as a container for Layouts. To understand in simpler words it can be understood as a special view that can hold other views that are often known as a child view.
Following are certain commonly used subclasses for ViewGroup:
is a widget that is more flexible and advanced version of GridView and ListView. It is a container for displaying large datasets which can be scrolled efficiently by maintaining limited number of views. You can use RecyclerView widget when you have data collections whose elements change at runtime depend on network event or user action. You supply the data and define how each item looks, and the RecyclerView library dynamically creates the elements when they're needed.
Following are used when recycler view is in place:
Let’s imagine we have a RecyclerView with 30 items on the list, but only 5 of them are visible at first. RecyclerView causes the adapter to run the onCreateViewHolder function to initialize the view and the onBindViewHolder function to bind the data when constructing the showing item view.
When scrolling down the process, item x becomes un-visible on screen and will be stored in the collection of scrapped views. And you have item 6 visible on the screen. A “scrapped” view is a collection view that is still attached to its parent RecyclerView but that has been marked for removal or reuse.
Before item 7 becomes visible when we scroll a second time, the recycler view will take a view from the collection of scrapped views and use the onBindViewHolder function to bind the new data instead of using the onCreateViewHolder function to construct a view. The view which is loaded from scrapped view is called a dirty view.
Layout basically refers to the arrangement of elements on a page these elements are likely to be images, texts or styles. These are a part of Android Jetpack. They define the structure of android user interface in the app, like in an activity. All elements in the layout are built with the help of Views and ViewGroups. These layouts can have various widgets like buttons, labels, textboxes, and many others.
A ViewGroup is a special view that can contain other views. The ViewGroup is the base class for Layouts in android, like LinearLayout, RelativeLayout, FrameLayout etc.
In other words, ViewGroup is generally used to define the layout in which views(widgets) will be set/arranged/listed on the android screen.
ViewGroups acts as an invisible container in which other Views and Layouts are placed. Yes, a layout can hold another layout in it, or in other words a ViewGroup can have another ViewGroup in it.
is a Graphical User Interface component of Android. It resides within the Activities of an Android application. It represents a portion of UI that the user sees on the screen. Android Fragments cannot exist outside an activity. Another name for Fragment can be Sub-Activity as they are part of Activities.
How fragments work
The above image depicts two devices: a Handset and a Tablet.
In tablets, there is only one activity that is Activity 1.
In Activity 1, there are two fragments: Fragment A and Fragment B.
When we select an item from Fragment A, it gets open in Fragment B of the same activity.
In the case of mobiles, there are two activities that are:
Activity 1 with Fragment A and Activity 2 with Fragment B.
When we select an item from Fragment A, it gets open in the Fragment B of Activity 2.
Example of a fragment:
Intents, in general, are used for navigating among various activities within the same (or not same) application, but note, is not limited to one single application.
They can also be utilized for moving from one application to another - e.g. jump from one application to another as a part of the whole process, for example, searching for a location on the browser and witnessing a direct jump into Google Maps or receiving payment links in Messages Application (SMS) and on clicking jumping to PayPal or GPay (Google Pay).
This process of taking users from one application to another is achieved by passing the Intent to the system.
Applications of Intents:
In the beginning of the Android development, developers where using xml files for ui development and had to use “findViewByID” for connecting ui items with application logic.(Button click listeners, setText for TextView and so on.)
and some add-ons to simplify things:
@BindView
and a view ID for Butter Knife to find and automatically cast the corresponding view in your layoutData Binding - to use less repetitve code.It moves UI operations out of the activities and fragments to the XML layout. You assign the attribute to a variable, in the XML layout
View Binding - it generates a binding class for each XML layout file present in that module. With these binding classes we get references to all views that are in xml
is an Android UI toolkit introduced by Google. It improves the way the UI is built in most current Android applications.
An XML interface can be rewritten with Compose with fewer lines of code:
With compose, we define our interfaces as functions.
Run Output:
Name of the Component | How it Works |
---|---|
Column | Inserts item from up to down |
Row | Inserts item from left to right |
Box | Inserts item on top of each other |
Base Espresso Test
launchFragmentInContainer() - is used to launch our desired fragment in an isolated environment (essentially an empty activity that houses that fragment)
The call to launchFragmentInContainer() can also be done with the addition of two arguments:
fragment arguments — to configure fragment behaviour. It’s likely that some of your fragments make use of fragment arguments - to test the behaviour given these conditional values. E.g. movie names in MovideDetailsFragment
fragment factory — allows you to provide a way to depict how the fragment should be instantiated. So that the outcome of this factory can also be tested, this factory can be passed in as an argument.
in the end the code looks like this:
To click an item in a recyclerView we need to use actionOnItemAtPosition
function: actionOnItemAtPosition<{AdaprerName}.{ViewHolder}>({itemToClick}, {action})
Step 1. Preparation
Create a compose rule object which is the main key to testing our composable.
createComposeRule
is required because it provides us access to our composable components. With its help, we can even test our composable in isolation.
In case we want our activity reference in testing then we can create createAndroidComposeRule<MainActivity>()
Step 1.1. Set our composable as content to our compose rule.
Step 2. Test Cases
Let's assume we have an app with 3 states:
Case 1. Verify if all of our views in the default state exist or not.
onNodeWithText
and onNodeWithTag
are of the same purpose but we can use either. We can set a testTag to our modifier so that we can identify the component when testing.
Case 2. Invalid state
If we perform a click action on the Copy button while the input is empty the display text should be an Invalid entry.
Line 3: we first identify our view with text Copy on it. Once identified, we perform a click action on it. Now the onClick block of our button will be called.
Line 5: We know that if the input is invalid it would be displayed as an Invalid entry. So we first identify our view with test tag “Counter Display” where the final output will be displayed. Then we assert if the text on it is “Invalid entry” or not.
Case 3. Valid State
Now, we’ll test if we correctly input an integer and click on the button, do we get the text as “Counter = 1” on the “Display Counter” text component?