Tải bản đầy đủ (.pdf) (7 trang)

Lập trình Androi part 53 ppsx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (339.06 KB, 7 trang )

CHAPTER 36: Handling Multiple Screen Sizes
346

Figure 36–44. EU4You, original version, QVGA
Fixing the Fonts
The first problem that should be fixed is the font size. As you can see, with a fixed 20-
pixel size, the font ranges from big to tiny, depending on screen size and density. For a
WVGA screen, the font may be rather difficult to read.
We could put the dimension as a resource (res/values/dimens.xml) and have different
versions of that resource based on screen size or density. However, it is simpler to just
specify a density-independent size, such as 5mm, as seen in the ScreenSizes/EU4You_2
project:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="2dip"
android:minHeight="?android:attr/listPreferredItemHeight"
>
<ImageView android:id="@+id/flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|left"
android:paddingRight="4px"
/>
<TextView android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|right"
android:textSize="5mm"
/>


</LinearLayout>
CHAPTER 36: Handling Multiple Screen Sizes
347
Figures 36–5, 36–6, and 36–7 shows the results on HVGA, WVGA, and QVGA screens.

Figure 36–5. EU4You, 5mm font version, HVGA

Figure 36–6. EU4You, 5mm font version, WVGA (800x480 pixels)
CHAPTER 36: Handling Multiple Screen Sizes
348

Figure 36–7. EU4You, 5mm font version, QVGA
Now our font is a consistent size and large enough to match the flags.
Fixing the Icons
So, what about those icons? They should be varying in size as well, since they are the
same for all three emulators.
However, Android automatically scales bitmap resources, even with <supports-screens>
and its attributes set to true. On the plus side, this means you may not need to do
anything with these bitmaps. However, you are relying on a device to do the scaling,
which definitely costs CPU time (and, hence, battery life). Also, the scaling algorithms
that the device uses may not be optimal, compared to what you can do with graphics
tools on your development machine.
The ScreenSizes/EU4You_3 project creates res/drawable-ldpi and res/drawable-hdpi,
putting in smaller and larger renditions of the flags, respectively. This project also
renames res/drawable to res/drawable-mdpi. Android will use the flags for the
appropriate screen density, depending on what the device or emulator needs.
Using the Space
While the activity looks fine on WVGA in portrait mode, it really wastes a lot of space in
landscape mode, as shown in Figure 36–8.
CHAPTER 36: Handling Multiple Screen Sizes

349

Figure 36–8. EU4You, landscape WVGA (800x480 pixels)
We can put that to better use by having the Wikipedia content appear directly on the
main activity when in large-screen landscape mode, instead of needing to spawn a
separate browser activity.
To do this, we first must clone the main.xml layout into a res/layout-large-land
rendition that incorporates a WebView widget, as seen in ScreenSizes/EU4You_4:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
/>
<WebView
android:id="@+id/browser"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
/>
</LinearLayout>
Then we need to adjust our activity to look for that WebView and use it when found;
otherwise, it will default to launching a browser activity:
@Override
public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.main);

browser=(WebView)findViewById(R.id.browser);

setListAdapter(new CountryAdapter());
}

@Override
CHAPTER 36: Handling Multiple Screen Sizes
350
protected void onListItemClick(ListView l, View v,
int position, long id) {
String url=getString(EU.get(position).url);

if (browser==null) {
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse(url)));
}
else {
browser.loadUrl(url);
}
}
This gives us a more space-efficient edition of the activity, as shown in Figure 36–9.

Figure 36–9. EU4You, landscape WVGA (800x480 pixels), set for normal density, and showing the embedded
WebView
When the user clicks a link in the Wikipedia page, a full browser opens, for easier surfing.
Note that to test this version of the activity, and see this behavior, requires a bit of extra
emulator work. By default, Android sets up WVGA devices as being high-density,

meaning WVGA is not large in terms of resource sets, but rather normal. You will need to
create a different emulator AVD that is set for normal (medium) density, which will result in
a large screen size.
What If It’s Not a Browser?
Of course, EU4You does cheat a bit. The second activity is a browser (or WebView in the
embedded form), not some activity of your own creation. Things get slightly more
complicated if the second activity is some activity of yours, with many widgets in a
CHAPTER 36: Handling Multiple Screen Sizes
351
layout, and you want to use it both as an activity (for smaller screens) and have it
embedded in your main activity UI (for larger screens).
Here is one pattern to deal with this scenario:
1. Initially develop and test the second activity as an activity.
2. Have all of the second activity’s life-cycle methods delegate their logic
to an inner class. Move all data members of the activity that are needed
by only the inner class to that inner class, and ensure that still works.
3. Pull the inner class out into a separate public class, and ensure that still
works.
4. For your first (or main) activity, create a separate layout for large screens
and use the <include> directive to blend in the contents of your second
activity’s layout into the proper spot in the large-screen first activity’s
layout.
5. In the first activity, if it finds the second activity’s layout has been
inflated as part of its own (e.g., by checking for the existence of some
widget via findViewById()), create an instance of the public class you
created in step 3 and have it deal with all of those widgets. Adjust your
code to reference that class directly, rather than start the second activity
as shown in the previous section.
In short, use a public class and reusable layout to keep your code and resources in one
place, yet use them from both a stand-alone activity and as part of a large-screen

version of the main activity.
What Are a Few Bugs Among Friends?
The Motorola DROID, which shipped with Android 2.0, had two bugs of relevance for
screen sizes:
 It had incorrect values for the screen density, both horizontal and
vertical. This means it incorrectly scaled dimensions based on physical
sizes: pt, mm, and in.
 It had Android 2.0 as API level 6 instead of level 5, so version-specific
resource directories need to use the -v6 suffix instead of -v5
Both of these bugs are fixed in Android 2.0.1 and later, and no other devices should ship
with Android 2.0 or be affected by these bugs.
CHAPTER 36: Handling Multiple Screen Sizes
352

×