This is the second part of the Activity types series, where we will take a look at the Empty activity and the full screen activity, If you wish to work with the simple activities, you can refer to my earlier post here.
3. Empty Activity
As the name suggests, this type of activity is not really an activity type, but a way of working. Empty Activity means, that the wizard will provide us with the files required, but it provides nothing else. It gives an empty implementation of the Activity class.
What do I get from the wizard?
1. We get the standard .java file extending Activity class, but all it contains is the setContentView(<<xml>>) method invocation that puts the view onto the screen.
2. We get one XML file containing the basic single TextView component, nothing more and nothing less. One interesting this that we can notice here is that the way the root tag (in this case RelativeLayout) is configured. For a standard activity the root tag looks like this:
<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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.acitivitydemo.MainActivity" >
while the root tag for an empty activity looks like this:
<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" tools:context="${relativePackage}.${activityClass}" >
It does not talk about any kind of padding to the layout, this is because, there is supposed to be no component added at the time of design. It’s an Empty Activity. If you are wondering what is this “$” sign confusion, rest assured, it is just a way through which the configuration file is letting the runtime understand which Activity class is associated with the layout file.
This is similar to the tools:context in the earlier XML example, where it is explicitly mapped.
3. As always, we also get the strings.xml file for i18n support.
What do I need to do to make it execute?
Nothing extra, this is an empty activity, hence it is not supposed to be having anything, hence just execute it without any modifications.
What will be required to create an application?
Everything, as the wizard provided components do not carry anything, we will have to add the components and write the corresponding Java code.
Where to use it?
Anywhere that you wish to create an activity. This gives you a blank slate that you can use to create whatever it is that you want. It can become a map activity, a sensor activity, a service or a standard UI activity. It is your choice.
My recommendation
I personally feel that this is a useless type of activity as it just replicates what we get by using the blank activity without fragments (explained in the earlier post here).
4. Full Screen Activity
Technology, whichever it may be, is based purely on common sense (this is a theme I will keep on repeating). Full Screen Activity, the name itself suggest what this is all about. It provides us with a UI that uses the entire device screen for rendering the UI components. The idea behind having this activity type is to make the application more immersive, so that the user is not disturbed / sidetracked by the system bars like Action bars etc.
This is the first of the advanced activity types available post KitKat release. Hence, it will require some extra explanation beyond the standard options.
What do I get from the wizard?
1. We get one .java file which is embedded with all the code necessary to build a full screen activity and hence will have lots of pre-built code available.
public class FullscreenActivity extends Activity { /** * Whether or not the system UI should be auto-hidden after predefined time */ private static final boolean AUTO_HIDE = true;
/**
* time used by the AUTO_HIDE in miliseconds
*/
private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
/**
* If set, will toggle the system UI visibility upon interaction.
*/
private static final boolean TOGGLE_ON_CLICK = true;
private static final int HIDER_FLAGS = SystemUiHider.FLAG_HIDE_NAVIGATION;
private SystemUiHider mSystemUiHider;
The variables defined here, will be used to control the behaviour of the screen as to whether it should go into full screen mode after user interaction.
By default the activity will run in a full screen mode, but upon user interaction it will show the system bars depending on the direction in which we swipe the screen. The code which enables the listening of user interaction is to be written in the onCreate() method.
Partial code:
final View controlsView = findViewById(R.id.fullscreen_content_controls); final View contentView = findViewById(R.id.fullscreen_content);
// Set up an instance of SystemUiHider to control the system UI for
// this activity.
mSystemUiHider = SystemUiHider.getInstance(this, contentView,
HIDER_FLAGS);
mSystemUiHider.setup();
mSystemUiHider
.setOnVisibilityChangeListener(new SystemUiHider.OnVisibilityChangeListener() {
// Cached values.
int mControlsHeight;
int mShortAnimTime;
Here we are taking the controls defined in the XML (We will see this shortly), and which correspond to the entire screen. System UI hider class is generated for you by the wizard, and due to it’s inherent complexity, we will not be getting into discussions pertaining to it (maybe at a later date), suffice it to say that this class accepts flags, which will decided which part of UI to hide. Currently it has three possible flags:
- FLAG_LAYOUT_IN_OLDER_DEVICES – this is typically used to make a full screen appear in older devices
- FLAG_FULLSCREEN – used to toggle the visibility of the status bar.
- FLAG_HIDE_NAVIGATION – toggles the visibility of the navigation bar.
These values are defined in the wizard generated SystemUiHider class and we customize it in our activity class.
private static final int HIDER_FLAGS = SystemUiHider.FLAG_HIDE_NAVIGATION;
Using an instance of the SystemUiHider class, we can now associate a visibility change discerning listener, which will perform operations whenever the UI visibility changes, in other words, when a human intervention is encountered.
mSystemUiHider .setOnVisibilityChangeListener(new SystemUiHider.OnVisibilityChangeListener() { // Cached values. int mControlsHeight; int mShortAnimTime;
@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
public void onVisibilityChange(boolean visible) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
// If the ViewPropertyAnimator API is available
// (Honeycomb MR2 and later), use it to animate the
// in-layout UI controls at the bottom of the
// screen.
if (mControlsHeight == 0) {
mControlsHeight = controlsView.getHeight();
}
if (mShortAnimTime == 0) {
mShortAnimTime = getResources().getInteger(
android.R.integer.config_shortAnimTime);
}
controlsView
.animate()
.translationY(visible ? 0 : mControlsHeight)
.setDuration(mShortAnimTime);
} else {
// If the ViewPropertyAnimator APIs aren’t
// available, simply show or hide the in-layout UI
// controls.
controlsView.setVisibility(visible ? View.VISIBLE
: View.GONE);
}
if (visible && AUTO_HIDE) {
// Schedule a hide().
delayedHide(AUTO_HIDE_DELAY_MILLIS);
}
}
});
This seems to be a too complicated code, but you need not focus on the code if you are a fresh entrant to Android, in case you wish to understand what the code does, please focus on the implementation of the onVisibilityChange() method. In this method, depending on the API (Honeycomb has a different way of implementing it) and the visibility status, the visibility of the components is being changed.
You will also be getting readymade functions like onPostCreate(), in which you can customize how the first visibility change should execute. delayedHide() where you can customize the delay of toggling the visibility.
2. We get an XML file in which we define the components for representing the full screen.
<FrameLayout 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" tools:context="com.example.acitivitydemo.FullscreenActivity" > <!-- The primary full-screen view. This can be replaced with whatever view is needed to present your content, e.g. VideoView, SurfaceView, TextureView, etc. We have used a TextView to render a text, but you can have a VideoView, if you are building a video player. Similarly, other components should be used. --> <TextView android:id="@+id/fullscreen_content" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:keepScreenOn="true" android:text="@string/dummy_content" android:textStyle="bold" /> <!-- This FrameLayout insets its children based on system windows using android:fitsSystemWindows. --> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" > <LinearLayout android:id="@+id/fullscreen_content_controls" style="?metaButtonBarStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom|center_horizontal" tools:ignore="UselessParent" > <Button android:id="@+id/dummy_button" style="?metaButtonBarButtonStyle" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/dummy_button" /> </LinearLayout> </FrameLayout> </FrameLayout>
For brevity’s sake, I have removed certain attributed related to text colours, background etc. You can choose it at your discretion.
The screen looks something like this.
3. We get one strings.xml file in which values for i18n are available.
What do I need to do to make it execute?
Again, you need to do nothing, as wizard has done everything for you to execute.
What will be required to create an App?
You will need to replace the default TextView component in the XML with the component of your choice. In the Java code, you will need to integrate this component along with the SystemUiHider so that the activities associated with the user interaction can be handled alongwith the UI hiding.
Where to use it?
This activity type should NOT be used for standard UI / Data entry / Data rendering kind of tasks. The purpose of this activity is to make the user experience immersive so that the user does not get distracted by anything else on the screen. In situations where the content is most important part of the application, this activity can be used.
My Recommendation
I think, this activity is a perfect fit for building an application that deals with multi-media content. For example, a Video player, or a photograph viewer, or a text editor. There are two reasons for such a recommendation:
- The activity demands maximum utilization of available screen space.
- Minimum distraction, while the activity is running.
Summarizing the post:
As always the intricacies of Android does not cease to surprise me, hence instead of tagging on the Login Activity to an already overflowing post, I defer it to the next post.
Blog: |
Musings of a Meandering Mind |
Topics:
|
Mobile, Javaee, Java |