Você está na página 1de 20

UNIT III

User Interface(UI) Architecture Lecture

3.1 Application context

Context:

Its the context of current state of the application/object. It lets newly created objects understand
what has been going on. Typically you call it to get information regarding another part of your
program (activity, package/application)You can get the context by
invoking getApplicationContext(), getContext(), getBaseContext() or this (when in the activity
class).

Things that involve context are


1. Loading a resource.
2. Launching a new activity.
3. Creating views.
4. obtaining system service

Application Context

Application class extends Context class.Every Application has a context, and Android guarantees
that Application context will exist as a instance across your application.Many times you may need to
store the state of your app or a need a variable across multiple Activities,services and other java
classes . Android provides an easy option for doing this – the global application context.

Custom adapters
Android Adapter is a bridge between the View (e.g. ListView) and the underlying data for that view.
An adapter manages the data and adapts the data to the individual rows (listItems) of the view.We
bind the adapter with Android listview via setAdapter method.Once we have a reference to the view,
we can get the data from the data source either in an Array list or a cursor. We can then bind the data
to the view items. All this is done in getView Method.By default, ArrayAdapter expects a Layout
with single TextView. If you want to use more complex views, please avoid ArrayAdapter and use
custom adapter.ArrayAdapter is also an implementation of BaseAdapter
BaseAdapter is a common base class of a general implementation for an Adapter that can be used in
ListView. BaseAdapter can be extended to create a custom Adapter to suit your need of building a
custom listitem.
Understanding Custom Adapter Methods
Methods of the custom adapter.are detailed below.
● getCount() : This method tells the listview the number of rows it will require. This count can
come from your data source. It can be the size of your Data Source. If you have your datasource
as a list of objects, this value will be the size of the list.
● Object getItem(int arg0): We have 2 method implementation of getItem. This method returns an
object. This method helps ListView to get data for each row. The parameter passed is the row
number starting from 0. In our List of Objects, this method will return the object at the passed
index.
● long getItemId(int arg0) : You can ignore this method. It just returns the same value as passed.
This in general helps ListView to map its rows to the data set elements.
● getView : This is the most important method. This method will be called to get the View for
each row. This is the method where we can use our custom listitem and bind it with the data. The
fist argument passed to getView is the listview item position ie row number. The second
parameter is recycled view reference(as we know listview recycles a view, you can confirm
through this parameter). Third parameter is the parent to which this view will get attached to.
Data Source can any custom object(user defined class objects).

http://navinsandroidtutorial.blogspot.com/2014/03/application-context-in-android-tutorial.html

3.2 Intents
An Intent is a messaging object you can use to request an action from another app component.
Although intents facilitate communication between components in several ways, there are three
fundamental use cases:

● Starting an activity
An Activity represents a single screen in an app. You can start a new instance of an Activity by
passing swan Intent to startActivity(). The Intent describes the activity to start and carries any
necessary data.
If you want to receive a result from the activity when it finishes, call startActivityForResult(). Your
activity receives the result as a separate Intent object in your activity's onActivityResult() callback.
For more information, see the Activities guide.
● Starting a service
A Service is a component that performs operations in the background without a user interface. With
Android 5.0 (API level 21) and later, you can start a service with JobScheduler. For more
information about JobScheduler, see its API-reference documentation.
For versions earlier than Android 5.0 (API level 21), you can start a service by using methods of
the Service class. You can start a service to perform a one-time operation (such as downloading a
file) by passing an Intent to startService(). The Intent describes the service to start and carries any
necessary data.
If the service is designed with a client-server interface, you can bind to the service from another
component by passing an Intent to bindService(). For more information, see the Servicesguide.
● Delivering a broadcast
A broadcast is a message that any app can receive. The system delivers various broadcasts for
system events, such as when the system boots up or the device starts charging. You can deliver a
broadcast to other apps by passing an Intent to sendBroadcast() orsendOrderedBroadcast().

The rest of this page explains how intents work and how to use them. For related information,
seeInteracting with Other Apps and Sharing Content.

Intent types

There are two types of intents:

● Explicit intents specify which application will satisfy the intent, by supplying either the target app's
package name or a fully-qualified component class name. You'll typically use an explicit intent to
start a component in your own app, because you know the class name of the activity or service you
want to start. For example, you might start a new activity within your app in response to a user
action, or start a service to download a file in the background.
● Implicit intents do not name a specific component, but instead declare a general action to perform,
which allows a component from another app to handle it. For example, if you want to show the user
a location on a map, you can use an implicit intent to request that another capable app show a
specified location on a map.

Figure 1 shows how an intent is used when starting an activity. When the Intent object names a
specific activity component explicitly, the system immediately starts that component.

Figure 1. How an implicit intent is delivered through the system to start another activity:

[1] Activity Acreates an Intent with an action description and passes it to startActivity().
[2] The Android System searches all apps for an intent filter that matches the intent. When a match
is found,

[3] the system starts the matching activity (Activity B) by invoking its onCreate() method and
passing it the Intent.

When you use an implicit intent, the Android system finds the appropriate component to start by
comparing the contents of the intent to the intent filters declared in the manifest file of other apps on
the device. If the intent matches an intent filter, the system starts that component and delivers it
the Intent object. If multiple intent filters are compatible, the system displays a dialog so the user can
pick which app to use.

An intent filter is an expression in an app's manifest file that specifies the type of intents that the
component would like to receive. For instance, by declaring an intent filter for an activity, you make
it possible for other apps to directly start your activity with a certain kind of intent. Likewise, if you
do not declare any intent filters for an activity, then it can be started only with an explicit intent.

Building an intent

An Intent object carries information that the Android system uses to determine which component to
start (such as the exact component name or component category that should receive the intent), plus
information that the recipient component uses in order to properly perform the action (such as the
action to take and the data to act upon).

The primary information contained in an Intent is the following:

Component name

The name of the component to start.

This is optional, but it's the critical piece of information that makes an intent explicit,
meaning that the intent should be delivered only to the app component defined by the
component name. Without a component name, the intent is implicit and the system decides
which component should receive the intent based on the other intent information (such as the
action, data, and category—described below). If you need to start a specific component in
your app, you should specify the component name.

This field of the Intent is a ComponentName object, which you can specify using a fully
qualified class name of the target component, including the package name of the app, for
example, com.example.ExampleActivity. You can set the component name
with setComponent(), setClass(), setClassName(), or with the Intent constructor.

Action

A string that specifies the generic action to perform (such as view or pick).

In the case of a broadcast intent, this is the action that took place and is being reported. The
action largely determines how the rest of the intent is structured—particularly the
information that is contained in the data and extras.

You can specify your own actions for use by intents within your app (or for use by other apps
to invoke components in your app), but you usually specify action constants defined by
the Intent class or other framework classes. Here are some common actions for starting an
activity:
ACTION_VIEW

Use this action in an intent with startActivity() when you have some information that an
activity can show to the user, such as a photo to view in a gallery app, or an address to view
in a map app.

ACTION_SEND

Also known as the share intent, you should use this in an intent with startActivity()when you
have some data that the user can share through another app, such as an email app or social
sharing app.

See the Intent class reference for more constants that define generic actions. Other actions are
defined elsewhere in the Android framework, such as in Settings for actions that open
specific screens in the system's Settings app.

You can specify the action for an intent with setAction() or with an Intent constructor.

If you define your own actions, be sure to include your app's package name as a prefix, as
shown in the following example:

KOTLINJAVA

const val ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL"

Data

The URI (a Uri object) that references the data to be acted on and/or the MIME type of that
data. The type of data supplied is generally dictated by the intent's action. For example, if the
action is ACTION_EDIT, the data should contain the URI of the document to edit.

When creating an intent, it's often important to specify the type of data (its MIME type) in
addition to its URI. For example, an activity that's able to display images probably won't be
able to play an audio file, even though the URI formats could be similar. Specifying the
MIME type of your data helps the Android system find the best component to receive your
intent. However, the MIME type can sometimes be inferred from the URI—particularly
when the data is a content:URI. A content: URI indicates the data is located on the device
and controlled by aContentProvider, which makes the data MIME type visible to the system.

To set only the data URI, call setData(). To set only the MIME type, call setType(). If
necessary, you can set both explicitly with setDataAndType().

Category

A string containing additional information about the kind of component that should handle
the intent. Any number of category descriptions can be placed in an intent, but most intents
do not require a category. Here are some common categories:

CATEGORY_BROWSABLE

The target activity allows itself to be started by a web browser to display data referenced by a
link, such as an image or an e-mail message.

CATEGORY_LAUNCHER
The activity is the initial activity of a task and is listed in the system's application launcher.

See the Intent class description for the full list of categories.

You can specify a category with addCategory().

These properties listed above (component name, action, data, and category) represent the defining
characteristics of an intent. By reading these properties, the Android system is able to resolve which
app component it should start. However, an intent can carry additional information that does not
affect how it is resolved to an app component. An intent can also supply the following information:

Extras

Key-value pairs that carry additional information required to accomplish the requested
action. Just as some actions use particular kinds of data URIs, some actions also use
particular extras.

You can add extra data with various putExtra() methods, each accepting two parameters: the
key name and the value. You can also create a Bundle object with all the extra data, then
insert the Bundle in the Intent with putExtras().

For example, when creating an intent to send an email with ACTION_SEND, you can
specify the to recipient with the EXTRA_EMAIL key, and specify the subject with
the EXTRA_SUBJECT key.

The Intent class specifies many EXTRA_* constants for standardized data types. If you need
to declare your own extra keys (for intents that your app receives), be sure to include your
app's package name as a prefix, as shown in the following example:

KOTLINJAVA

const val EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS"

Flags

Flags are defined in the Intent class that function as metadata for the intent. The flags may
instruct the Android system how to launch an activity (for example, which task the activity
should belong to) and how to treat it after it's launched (for example, whether it belongs in
the list of recent activities).

For more information, see the setFlags() method.

Example explicit intent

An explicit intent is one that you use to launch a specific app component, such as a particular
activity or service in your app. To create an explicit intent, define the component name for
the Intent object—all other intent properties are optional.

For example, if you built a service in your app, named DownloadService, designed to download a
file from the web, you can start it with the following code:

KOTLINJAVA
// Executed in an Activity, so 'this' is the Context
// The fileUrl is a string URL, such as "http://www.example.com/image.png"
val downloadIntent = Intent(this, DownloadService::class.java).apply {
data = Uri.parse(fileUrl)
}
startService(downloadIntent)

The Intent(Context, Class) constructor supplies the app Context and the component a Classobject.
As such, this intent explicitly starts the DownloadService class in the app.

For more information about building and starting a service, see the Services guide.

Example implicit intent

An implicit intent specifies an action that can invoke any app on the device able to perform the
action. Using an implicit intent is useful when your app cannot perform the action, but other apps
probably can and you'd like the user to pick which app to use.

For example, if you have content that you want the user to share with other people, create an intent
with the ACTION_SEND action and add extras that specify the content to share. When you
callstartActivity() with that intent, the user can pick an app through which to share the content..

KOTLINJAVA

// Create the text message with a string


val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, textMessage)
type = "text/plain"
}

// Verify that the intent will resolve to an activity


if (sendIntent.resolveActivity(packageManager) != null) {
startActivity(sendIntent)
}

When startActivity() is called, the system examines all of the installed apps to determine which ones
can handle this kind of intent (an intent with the ACTION_SEND action and that carries "text/plain"
data). If there's only one app that can handle it, that app opens immediately and is given the intent. If
multiple activities accept the intent, the system displays a dialog such as the one shown in Figure 2,
so the user can pick which app to use.

Using a pending intent

A PendingIntent object is a wrapper around an Intent object. The primary purpose of


a PendingIntent is to grant permission to a foreign application to use the contained Intent as if it were
executed from your app's own process.

Major use cases for a pending intent include the following:

● Declaring an intent to be executed when the user performs an action with your Notification (the
Android system's NotificationManager executes the Intent).
● Declaring an intent to be executed when the user performs an action with your App Widget (the
Home screen app executes the Intent).
● Declaring an intent to be executed at a specified future time (the Android
system's AlarmManager executes the Intent).

Just as each Intent object is designed to be handled by a specific type of app component (either
an Activity, a Service, or a BroadcastReceiver), so too must a PendingIntent be created with the
same consideration. When using a pending intent, your app doesn't execute the intent with a call
such as startActivity(). Instead, you must declare the intended component type when you create
the PendingIntent by calling the respective creator method:

● PendingIntent.getActivity() for an Intent that starts an Activity.


● PendingIntent.getService() for an Intent that starts a Service.
● PendingIntent.getBroadcast() for an Intent that starts a BroadcastReceiver.

Unless your app is receiving pending intents from other apps, the above methods to create
a PendingIntent are probably the only PendingIntent methods you'll ever need.

https://developer.android.com/guide/components/intents-filters

3.3 Activity life cycle


Android Activity Lifecycle is controlled by 7 methods of android.app.Activity class. The
android Activity is the subclass of ContextThemeWrapper class.

An activity is the single screen in android. It is like window or frame of Java.

By the help of activity, you can place all your UI components or widgets in a single screen.

The 7 lifecycle method of Activity describes how activity will behave at different states.

Android Activity Lifecycle methods


Let's see the 7 lifecycle methods of android activity.

Method Description

onCreate called when activity is first created.

onStart called when activity is becoming visible to the user.

onResume called when activity will start interacting with the user.

onPause called when activity is not visible to the user.

onStop called when activity is no longer visible to the user.

onRestart called after your activity is stopped, prior to start.


onDestroy called before the activity is destroyed.

File: activity_main.xml
1. <?xml version="1.0" encoding="utf-8"?>
2. <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.co
m/apk/res/android"
3. xmlns:app="http://schemas.android.com/apk/res-auto"
4. xmlns:tools="http://schemas.android.com/tools"
5. android:layout_width="match_parent"
6. android:layout_height="match_parent"
7. tools:context="example.javatpoint.com.activitylifecycle.MainActivity">
8.
9. <TextView
10. android:layout_width="wrap_content"
11. android:layout_height="wrap_content"
12. android:text="Hello World!"
13. app:layout_constraintBottom_toBottomOf="parent"
14. app:layout_constraintLeft_toLeftOf="parent"
15. app:layout_constraintRight_toRightOf="parent"
16. app:layout_constraintTop_toTopOf="parent" />
17.
18. </android.support.constraint.ConstraintLayout>

Android Activity Lifecycle Example


It provides the details about the invocation of life cycle methods of activity. In this example, we
are displaying the content on the logcat.

File: MainActivity.java
1. package example.javatpoint.com.activitylifecycle;
2.
3. import android.app.Activity;
4. import android.os.Bundle;
5. import android.util.Log;
6.
7. public class MainActivity extends Activity {
8.
9. @Override
10. protected void onCreate(Bundle savedInstanceState) {
11. super.onCreate(savedInstanceState);
12. setContentView(R.layout.activity_main);
13. Log.d("lifecycle","onCreate invoked");
14. }
15. @Override
16. protected void onStart() {
17. super.onStart();
18. Log.d("lifecycle","onStart invoked");
19. }
20. @Override
21. protected void onResume() {
22. super.onResume();
23. Log.d("lifecycle","onResume invoked");
24. }
25. @Override
26. protected void onPause() {
27. super.onPause();
28. Log.d("lifecycle","onPause invoked");
29. }
30. @Override
31. protected void onStop() {
32. super.onStop();
33. Log.d("lifecycle","onStop invoked");
34. }
35. @Override
36. protected void onRestart() {
37. super.onRestart();
38. Log.d("lifecycle","onRestart invoked");
39. }
40. @Override
41. protected void onDestroy() {
42. super.onDestroy();
43. Log.d("lifecycle","onDestroy invoked");
44. }
45. }

Output:

You will not see any output on the emulator or device. You need to open logcat.

https://www.javatpoint.com/android-life-cycle-of-activity

3.4 Supporting multiple screen sizes

Android devices come in all shapes and sizes, so your app's layout needs to be flexible. That is,
instead of defining your layout with rigid dimensions that assume a certain screen size and aspect
ratio, your layout should gracefully respond to different screen sizes and orientations.

By supporting as many screens as possible, your app can be made available to the greatest number of
users with different devices, using a single APK. Additionally, making your app flexible for
different screen sizes ensures that your app can handle window configuration changes on the device,
such as when the user enables multi-window mode.

This page shows you how to support different screen sizes with the following techniques:
● Use view dimensions that allow the layout to resize
● Create alternative UI layouts according to the screen configuration
● Provide bitmaps that can stretch with the views

But be aware that adapting to different screen sizes doesn't necessarily make your app compatible
with all Android form factors. You should take additional steps to support Android Wear, TV, Auto,
and Chrome OS devices.

For design guidelines for building UI for different screens, see the material guidelines for responsive
UI.

Create a flexible layout

No matter what hardware profile you want to support first, you need to create a layout that is
responsive to even small variations in screen size.

Use ConstraintLayout

The best way to create a responsive layout for different screen sizes is to use ConstraintLayout as the
base layout in your UI. ConstraintLayout allows you to specify the position and size for each view
according to spatial relationships with other views in the layout. This way, all the views can move
and stretch together as the screen size changes.

The easiest way to build a layout with ConstraintLayout is to use the Layout Editor in Android
Studio. It allows you to drag new views to the layout, attach their constraints to the parent view and
other sibling views, and edit the view's properties, all without editing any XML by hand (see figure
1).
Figure 1. The Layout Editor in Android Studio showing a ConstraintLayout file

But ConstraintLayout won't solve every layout scenario (especially for dynamically-
loaded lists, for which you should use RecyclerView), but no matter what layout you use,
you should always avoid hard-coding layout sizes (see the next section).

Avoid hard-coded layout sizes


To ensure that your layout is flexible and adapts to different screen sizes, you should
use "wrap_content" and "match_parent" for the width and height of most view
components, instead of hard-coded sizes.

"wrap_content" tells the view to set its size to whatever is necessary to fit the content
within that view.

"match_parent" makes the view expand to as much as possible within the parent view.

For example:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/lorem_ipsum" />

Although the actual layout for this view depends on other attributes in its parent view and
any sibling views, this TextView intends to set its width to fill all available space
(match_parent) and set its height to exactly as much space is required by the length of the
text (wrap_content). This allows the view to adapt to different screen sizes and different
lengths of text.

Figure 2 shows how the width of the text view using "match_parent" adjusts as the screen
width changes with device orientation.

Figure 2. A flexible text view

If you're using a LinearLayout, you can also expand the child views with layout weight so
that each view fills the remaining space proportional to their weight value. However, using
weights in a nested LinearLayout requires the system to perform multiple layout passes
to determine the size for each view, slowing your UI performance.
Fortunately, ConstraintLayout can achieve nearly all layouts possible
with LinearLayout without the performance impacts, so you should try converting your
layout to ConstraintLayout. Then, you can define weighted layouts with constraint chains.

Note: When using ConstraintLayout, you should not use match_parent. Instead, set the
dimension to 0dp to enable a special behavior called "match constraints," which is generally the
same as what you expect from match_parent. For more information, see how to adjust the view
size in ConstraintLayout.

Create alternative layouts


Although your layout should always respond to different screen sizes by stretching the
space within and around its views, that might not provide the best user experience for every
screen size. For example, the UI you designed for a phone, probably doesn't offer a good
experience on a tablet. Therefore, your app should also provide alternative layout
resources to optimize the UI design for certain screen sizes.
Figure 3. The same app on different screen sizes uses a different layout for each

You can provide screen-specific layouts by creating additional res/layout/ directories—


one for each screen configuration that requires a different layout—and then append a
screen configuration qualifier to the layout directory name (such as layout-w600dp for
screens that have 600dp of available width).

These configuration qualifiers represent the visible screen space available for your app UI.
The system takes into account any system decorations (such as the navigation bar) and
window configuration changes (such as when the user enables multi-window mode) when
selecting the layout from your app.

To create an alternative layout in Android Studio (using version 3.0 or higher), proceed as
follows:

1. Open your default layout and then click Orientation for Preview in the toolbar.
2. In the drop-down list, click to create a suggested variant such as Create Landscape Variant or
click Create Other.
3. If you selected Create Other, the Select Resource Directory appears. Here, select a screen
qualifier on the left and add it to the list of Chosen qualifiers. When you're done adding qualifiers,
click OK. (See the following sections for information about screen size qualifiers.)

This creates a duplicate layout file in the appropriate layout directory so you can begin
customizing the layout for that screen variant.

Use the smallest width qualifier


The "smallest width" screen size qualifier allows you to provide alternative layouts for
screens that have a minimum width measured in density-independent pixels(dp or dip).

By describing the screen size as a measure of density-independent pixels, Android allows


you to create layouts that are designed for very specific screen dimensions while avoiding
any concerns you might have about different pixel densities.
For example, you can create a layout named main_activity that's optimized for handsets
and tablets by creating different versions of the file in directories as follows:
res/layout/main_activity.xml # For handsets (smaller than 600dp
available width)
res/layout-sw600dp/main_activity.xml # For 7” tablets (600dp wide and
bigger)

The smallest width qualifier specifies the smallest of the screen's two sides, regardless of
the device's current orientation, so it's a simple way to specify the overall screen size
available for your layout.

Here's how other smallest width values correspond to typical screen sizes:

● 320dp: a typical phone screen (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc).
● 480dp: a large phone screen ~5" (480x800 mdpi).
● 600dp: a 7” tablet (600x1024 mdpi).
● 720dp: a 10” tablet (720x1280 mdpi, 800x1280 mdpi, etc).

Figure 4 provides a more detailed view of how different screen dp widths generally
correspond to different screen sizes and orientations.

Figure 4. Recommended width breakpoints to support different screen sizes

Remember that all the figures for the smallest width qualifier are density-independent
pixels, because what matters is the amount of screen space available after the system
accounts for pixel density (not the raw pixel resolution).
Note: The sizes that you specify using these qualifiers are not the actual screen sizes. Rather,
the sizes are for the width or height in dp units that are available to your activity's window. The
Android system might use some of the screen for system UI (such as the system bar at the bottom
of the screen or the status bar at the top), so some of the screen might not be available for your
layout. If your app is used in multi-window mode then your app only has access to the size of that
window. When the window is resized, it triggers a configuration change with the new window size
so the system can select the appropriate layout file. Thus, the sizes you declare should be
specifically about the sizes needed by your activity—the system accounts for any space used by
system UI when declaring how much space it provides for your layout.

Use the available width qualifier


Instead of changing the layout based on the smallest width of the screen, you might want to
change your layout based on how much width or height is currently available. For example,
if you have a two-pane layout, you might want to use that whenever the screen provides at
least 600dp of width, which might change depending on whether the device is in landscape
or portrait orientation. In this case, you should use the "available width" qualifier as follows:
res/layout/main_activity.xml # For handsets (smaller than 600dp
available width)
res/layout-w600dp/main_activity.xml # For 7” tablets or any screen with
600dp
# available width (possibly landscape
handsets)

If the available height is a concern for you, then you can do the same using the "available
height" qualifier. For example, layout-h600dp for screens with at least 600dp of screen
height.

Add orientation qualifiers


Although you may be able to support all size variations using only combinations of the
"smallest width" and "available width" qualifiers, you might also want to change the user
experience when the user switches between portrait and landscape orientations.

For that you can add the port or land qualifiers to your resource directory names. Just be
sure these come after the other size qualifiers. For example:
res/layout/main_activity.xml # For handsets
res/layout-land/main_activity.xml # For handsets in landscape
res/layout-sw600dp/main_activity.xml # For 7” tablets
res/layout-sw600dp-land/main_activity.xml # For 7” tablets in landscape

For more information about all the screen configuration qualifiers, see table 2 in the guide
to Providing Resources.

Modularize UI components with fragments


When designing your app for multiple screen sizes you want to make sure you aren't
needlessly duplicating your UI behavior across your activities. So you should
use fragments to extract your UI logic into separate components. Then, you can then
combine fragments to create multi-pane layouts when running on a large screen or place in
separate activities when running on a handset.
For example, a news app on a tablet might show a list of articles on the left side and a full
article on the right side—selecting an article on the left updates the article view on the right.
On a handset, however, these two components should appear on separate screens—
selecting an article from a list changes the entire screen to show that article.

To learn more, see Building a Dynamic UI with Fragments.

Support Android 3.1 with legacy size qualifiers


If your app supports Android 3.1 (API level 12) or lower, you need to use the legacy size
qualifiers in addition to the smallest/available width qualifiers from above.

From the example above, if you want a two pane layout on larger devices you need to use
the "large" configuration qualifier to support version 3.1 and lower. So, to implement these
layouts on those older versions, you might have the following files:
res/layout/main_activity.xml # For handsets (smaller than 640dp x
480dp)
res/layout-large/main_activity.xml # For small tablets (640dp x 480dp and
bigger)
res/layout-xlarge/main_activity.xml # For large tablets (960dp x 720dp and
bigger)

Use layout aliases

When supporting both pre- and post-3.2 Android versions you have to use both the
smallest-width and large qualifiers for your layouts. So, you would have a file
named res/layout-large/main.xmlwhich might be identical to res/layout-
sw600dp/main.xml.

To avoid this duplication of the same file, you can use alias files. For example, you can
define the following layouts:
res/layout/main.xml # single-pane layout
res/layout/main_twopanes.xml # two-pane layout

And add these two files:

● res/values-large/layout.xml:
<resources>
<item name="main" type="layout">@layout/main_twopanes</item>
</resources>

● res/values-sw600dp/layout.xml:
<resources>
<item name="main" type="layout">@layout/main_twopanes</item>
</resources>

These two files have identical content, but they don’t actually define the layout. They
merely set up main to be an alias to main_twopanes. Since these files
have large and sw600dp selectors, they are applied to large screens regardless of Android
version (pre-3.2 tablets and TVs match large, and post-3.2 will match sw600dp).
Create stretchable nine-patch bitmaps
If you use a bitmap as the background in a view that changes size, you will notice Android
scales your images as the view grows or shrinks based on the size of the screen or content
in the view. This often leads to visible blurring or other scaling artifacts. The solution is
using nine-patch bitmaps, which are specially formatted PNG files that indicate which areas
can and cannot be stretched.

A nine-patch bitmap is basically a standard PNG file, but with an extra 1px border that
indicates which pixels should be stretched (and with a .9.png extension instead of
just .png). As shown in figure 5, the intersection between the black lines on the left and top
edge is the area of the bitmap that can be stretched.

Optionally, you can also define the safe region where content should go inside the view by
similarly adding lines on the right and bottom edges.

Figure 5. A nine-patch image (button.9.png)

When you apply a nine-patch as the background to a view, the framework stretches the
image correctly to accommodate the size of the button.

For help creating a nine-patch image from a bitmap, see Create Resizable Bitmaps.

Test on all screen sizes


It's important to test your app on a variety of screen sizes so you can ensure your UI scales
correctly. If you don't have access to physical devices for all the different screen sizes, you
can use the Android Emulator to emulate any screen size.

If you would rather test on a physical device, but don't want to buy the devices, you can
use Firebase Test Lab to access devices in a Google data center.
Declare specific screen size support
If you decide that you don't want your app to run at certain screen sizes, you can set limits
for you much your screen should resize or even restrict which devices can install your app
based on their screen configuration.

https://developer.android.com/training/multiscreen/screensizes

Você também pode gostar