GeekHub - Android

Report 8 Downloads 49 Views
GeekHub - Android Season 3 (2013/2014)

Overview of Screens Support Terms and concepts Screen size

Screen density

Orientation

Actual physical size, measured as the screen's diagonal. Groups: small, normal, large, and extra large.

The quantity of pixels within a physical area of the screen; usually referred to as dpi (dots per inch). Groups: low, medium, high, and extra high.

The orientation of the screen from the user's point of view. This is either landscape or portrait, meaning that the screen's aspect ratio is either wide or tall, respectively.

● ●

Density-independent pixel (dp) A virtual pixel unit that you should use when defining UI layout, to express layout dimensions or position in a density-independent way. 1dp = 1px (160dpi) px = dp * (dpi / 160)

A set of four generalized sizes: small, normal, large, and xlarge (deprecated from Android 3.2+) A set of four generalized densities: ldpi (low), mdpi (medium), hdpi (high), and xhdpi (extra high)

How to Support Multiple Screens ● Explicitly declare in the manifest which screen sizes your application supports (<supports-screens>) ● Provide different layouts for different screen sizes (swdp, e.g. layout-sw600dp/) ● Provide different bitmap drawables for different screen densities (ldpi (low), mdpi (medium), hdpi (high), and xhdpi (extra high), e.g. drawable-hdpi/, drawable, drawable-nodpi/) http://developer.android.com/guide/practices/screens_support.html#qualifiers http://developer.android.com/guide/practices/screens_support. html#DeclaringTabletLayouts

Configuration examples Typical screen widths: ● ● ● ●

320dp: a typical phone screen (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc). 480dp: a tweener tablet like the Streak (480x800 mdpi). 600dp: a 7” tablet (600x1024 mdpi). 720dp: a 10” tablet (720x1280 mdpi, 800x1280 mdpi, etc).

Resources examples: 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)

res/layout-sw720dp/main_activity.xml

# For 10” tablets (720dp wide and bigger)

The "smallest width" qualifier, swdp, regardless of the device's current orientation. res/layout/main_activity.xml

# For handsets (smaller than 600dp available width)

res/layout-w600dp/main_activity.xml more)

# Multi-pane (any screen with 600dp available width or

The "available width" qualifier, wdp, depending on the orientation of the screen. res/drawable-mdpi/my_icon.png

# bitmap for medium density

res/drawable-hdpi/my_icon.png

# bitmap for high density

res/drawable-xhdpi/my_icon.png

# bitmap for extra high density

Building a Flexible UI

Add a Fragment to an Activity at Runtime res/layout/news_articles.xml: 1. 2. 3. 4.



1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28.

import android.os.Bundle; import android.support.v4.app.FragmentActivity ; public class MainActivity extends FragmentActivity { @Override public void onCreate(Bundle savedInstanceState ) { super.onCreate(savedInstanceState ); setContentView (R.layout.news_articles ); // Check that the activity is using the layout version with // the fragment_container FrameLayout if (findViewById (R.id.fragment_container ) != null) { // However, if we're being restored from a previous state, // then we don't need to do anything and should return or else // we could end up with overlapping fragments. if (savedInstanceState != null) { return; } // Create a new Fragment to be placed in the activity layout HeadlinesFragment firstFragment = new HeadlinesFragment (); // In case this activity was started with special instructions from // an Intent, pass the Intent's extras to the fragment as arguments firstFragment .setArguments (getIntent().getExtras()); // Add the fragment to the 'fragment_container' FrameLayout getSupportFragmentManager ().beginTransaction () .add(R.id.fragment_container , firstFragment ).commit(); } } }

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.

import import import import

android.os.Bundle; android.support.v4.app.Fragment; android.view.LayoutInflater ; android.view.ViewGroup;

public class HeadlinesFragment extends Fragment { @Override public View onCreateView (LayoutInflater inflater, ViewGroup container , Bundle savedInstanceState ) { // Inflate the layout for this fragment return inflater.inflate(R.layout.article_view , container , false); // return inflater.inflate(R.layout.article_view, null); } }

Replace One Fragment with Another 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.

// Create fragment and give it an argument specifying the article it should show ArticleFragment newFragment = new ArticleFragment (); Bundle args = new Bundle(); args.putInt(ArticleFragment .ARG_POSITION , position); newFragment .setArguments (args); FragmentTransaction transaction = getSupportFragmentManager (). beginTransaction (); // Replace whatever is in the fragment_container view with this fragment, // and add the transaction to the back stack so the user can navigate back transaction .replace(R.id.fragment_container , newFragment ); transaction .addToBackStack (null); // Commit the transaction transaction .commit();

Supporting Tablets and Handsets Basic Guidelines ● Build your activity designs based on fragments that you can reuse in different combinations - in multi-pane layouts on tablets and single-pane layouts on handsets. ● Use the action bar (ActionBarCompat). ● Implement flexible layouts.

Creating Single-pane and Multi-pane Layouts

On a tablet-sized screen, the Activity A layout contains both Fragment A and Fragment B. On a handset-sized screen, the Activity A layout contains only Fragment A (the list view). In order to show the details in Fragment B, Activity B must open.

Multi-pane Layouts pattern implementation Depending on the screen size, the system applies a different main.xml layout file: res/layout/main.xml for handsets: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.



Multi-pane Layouts pattern implementation How the application responds when a user selects an item from the list depends on whether Fragment B is available in the layout: ● ●

If Fragment B is in the layout, Activity A notifies Fragment B to update itself. If Fragment B is not in the layout, Activity A starts Activity B (which hosts Fragment B).

You should follow two guidelines: ● ●

Do not manipulate one fragment directly from another. Keep all code that concerns content in a fragment inside that fragment, rather than putting it in the host activity's code.

To avoid directly calling one fragment from another, define a callback interface in each fragment class that it can use to deliver events to its host activity, which implements the callback interface. When the activity receives a callback due to an event (such as the user selecting a list item), the activity responds appropriately based on the current fragment configuration.

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.

public class MainActivity extends Activity implements TitlesFragment . OnItemSelectedListener { ... /** This is a callback that the list fragment (Fragment A) calls when a list item is selected */ public void onItemSelected (int position) { DisplayFragment displayFrag = (DisplayFragment ) getFragmentManager () .findFragmentById (R.id.display_frag ); if (displayFrag == null) { // DisplayFragment (Fragment B) is not in the layout (handset layout), // so start DisplayActivity (Activity B) // and pass it the info about the selected item Intent intent = new Intent(this, DisplayActivity .class); intent .putExtra("position" , position); startActivity (intent); } else { // DisplayFragment (Fragment B) is in the layout (tablet layout), // so tell the fragment to update displayFrag .updateContent (position); } } }

Using the Action Bar ●







When setting a menu item to be an action item, avoid using the "always" value. In your menu resource, use "ifRoom" for the android:showAsAction attribute if you'd like the menu item to appear in the action bar. However, you might need "always" when an action view does not provide a default action for the overflow menu (that is, it must appear as an action view). When adding action items to the action bar with a text title, also provide an icon, when appropriate, and declare showAsAction="ifRoom|withText". This way, if there's not enough room for the title, but there is enough room for the icon, then only the icon may be used. Always provide a title for your action items, even if you don't enable "withText", because users can view the title as a "tool-tip" by performing a "long click" on the item—the title text appears momentarily in a toast message. Avoid using custom navigation modes when possible.

Using the Action Bar

Using split action bar

To enable split action bar, simply add uiOptions="splitActionBarWhenNarrow" to your or manifest element. If you'd like to hide the main action bar at the top, because you're using the built-in navigation tabs along with the split action bar, call setDisplayShowHomeEnabled(false) to disable the application icon in the action bar.

Home Studying 1. 2. 3. 4.

Supporting Multiple Screens http://developer.android.com/guide/practices/screens_support.html Building a Flexible UI http://developer.android.com/training/basics/fragments/fragment-ui.html Supporting Tablets and Handsets http://developer.android.com/guide/practices/tablets-and-handsets.html Android Design for UI Developers http://youtu.be/Jl3-lzlzOJI

Hometask Реализовать в вашем приложении Multi-pane Layouts pattern.