Depending on the layout that your application is currently showing, the UI flow may be different. For example, if your application is in the dual-pane mode, clicking on an item on the left pane will simply display the content on the right pane; if it is
in single-pane mode, the content should be displayed on its own (in a different activity).
Determine the Current Layout
Since your implementation of each layout will be a little different, one of the first things you will probably have to do is determine what layout the user is currently viewing. For example, you might want to know whether the user is in "single pane" mode
or "dual pane" mode. You can do that by querying if a given view exists and is visible:
public class NewsReaderActivity extends FragmentActivity {
boolean mIsDualPane;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
View articleView = findViewById(R.id.article);
mIsDualPane = articleView != null &&
articleView.getVisibility() == View.VISIBLE;
}
}
Notice that this code queries whether the "article" pane is available or not, which is much more flexible than hard-coding a query for a specific layout.
Another example of how you can adapt to the existence of different components is to check whether they are available before performing an operation on them. For example, in the News Reader sample app, there is a button that opens a menu, but that button
only exists when running on versions older than Android 3.0 (because it's function is taken over by theActionBar
on API level 11+). So, to add the event listener for this button, you can do:
Button catButton = (Button) findViewById(R.id.categorybutton);
OnClickListener listener = /* create your listener here */;
if (catButton != null) {
catButton.setOnClickListener(listener);
}
React According to Current Layout
Some actions may have a different result depending on the current layout. For example, in the News Reader sample, clicking on a headline from the headlines list opens the article in the right hand-side pane if the UI is in dual pane mode, but will launch
a separate activity if the UI is in single-pane mode:
@Override
public void onHeadlineSelected(int index) {
mArtIndex = index;
if (mIsDualPane) {
/* display article on the right pane */
mArticleFragment.displayArticle(mCurrentCat.getArticle(index));
} else {
/* start a separate activity */
Intent intent = new Intent(this, ArticleActivity.class);
intent.putExtra("catIndex", mCatIndex);
intent.putExtra("artIndex", index);
startActivity(intent);
}
}
Likewise, if the app is in dual-pane mode, it should set up the action bar with tabs for navigation, whereas if the app is in single-pane mode, it should set up navigation with a spinner widget. So your code should also check which case is appropriate:
final String CATEGORIES[] = { "Top Stories", "Politics", "Economy", "Technology" };
public void onCreate(Bundle savedInstanceState) {
....
if (mIsDualPane) {
/* use tabs for navigation */
actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_TABS);
int i;
for (i = 0; i < CATEGORIES.length; i++) {
actionBar.addTab(actionBar.newTab().setText(
CATEGORIES[i]).setTabListener(handler));
}
actionBar.setSelectedNavigationItem(selTab);
}
else {
/* use list navigation (spinner) */
actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_LIST);
SpinnerAdapter adap = new ArrayAdapter
(this,
R.layout.headline_item, CATEGORIES);
actionBar.setListNavigationCallbacks(adap, handler);
}
}
Reuse Fragments in Other Activities
A recurring pattern in designing for multiple screens is having a portion of your interface that's implemented as a pane on some screen configurations and as a separate activity on other configurations. For example, in the News Reader sample, the news article
text is presented in the right side pane on large screens, but is a separate activity on smaller screens.
In cases like this, you can usually avoid code duplication by reusing the sameFragment
subclass in several activities. For example,ArticleFragment
is used in the dual-pane layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<fragment android:id="@+id/headlines"
android:layout_height="fill_parent"
android:name="com.example.android.newsreader.HeadlinesFragment"
android:layout_width="400dp"
android:layout_marginRight="10dp"/>
<fragment android:id="@+id/article"
android:layout_height="fill_parent"
android:name="com.example.android.newsreader.ArticleFragment"
android:layout_width="fill_parent" />
</LinearLayout>
And reused (without a layout) in the activity layout for smaller screens (ArticleActivity
):
ArticleFragment frag = new ArticleFragment();
getSupportFragmentManager().beginTransaction().add(android.R.id.content, frag).commit();
Naturally, this has the same effect as declaring the fragment in an XML layout, but in this case an XML layout is unnecessary work because the article fragment is the only component of this activity.
One very important point to keep in mind when designing your fragments is to not create a strong coupling to a specific activity. You can usually do that by defining an interface that abstracts all the ways in which the fragment needs to interact with its
host activity, and then the host activity implements that interface:
For example, the News Reader app's HeadlinesFragment
does precisely that:
public class HeadlinesFragment extends ListFragment {
...
OnHeadlineSelectedListener mHeadlineSelectedListener = null;
/* Must be implemented by host activity */
public interface OnHeadlineSelectedListener {
public void onHeadlineSelected(int index);
}
...
public void setOnHeadlineSelectedListener(OnHeadlineSelectedListener listener) {
mHeadlineSelectedListener = listener;
}
}
Then, when the user selects a headline, the fragment notifies the listener specified by the host activity (as opposed to notifying a specific hard-coded activity):
public class HeadlinesFragment extends ListFragment {
...
@Override
public void onItemClick(AdapterView<?> parent,
View view, int position, long id) {
if (null != mHeadlineSelectedListener) {
mHeadlineSelectedListener.onHeadlineSelected(position);
}
}
...
}
This technique is discussed further in the guide to Supporting Tablets and Handsets.
Handle Screen Configuration Changes
If you are using separate activities to implement separate parts of your interface, you have to keep in mind that it may be necessary to react to certain configuration changes (such as a rotation change) in order to keep your interface consistent.
For example, on a typical 7" tablet running Android 3.0 or higher, the News Reader sample uses a separate activity to display the news article when running in portrait mode, but uses a two-pane layout when in landscape mode.
This means that when the user is in portrait mode and the activity for viewing an article is onscreen, you need to detect that the orientation changed to landscape and react appropriately by ending the activity and return to the main activity so the content
can display in the two-pane layout:
public class ArticleActivity extends FragmentActivity {
int mCatIndex, mArtIndex;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCatIndex = getIntent().getExtras().getInt("catIndex", 0);
mArtIndex = getIntent().getExtras().getInt("artIndex", 0);
// If should be in two-pane mode, finish to return to main activity
if (getResources().getBoolean(R.bool.has_two_panes)) {
finish();
return;
}
...
}
分享到:
相关推荐
完整英文版IEC/TS 62775:2016 Application guidelines - Technical and financial processes for implementing asset management systems (应用指南-实施资产管理系统的技术和财务流程)。作为技术规范的IEC TS ...
在微软实施零信任安全模型,Implementing a Zero Trust security model at Microsoft
Implementing QuantLib
Implementing data cube efficiently
《Implementing CIFS》这本书的完整版,英文的,pdf版
本书旨在使编程语言的实现尽可能容易。 它将指导您完成编译器或解释器的设计和实现的所有阶段。
Implementing Qlik Sense 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
Implementing Modern DevOps 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
Implementing Cisco UCS Solutions
With Implementing Domain-Driven Design, Vaughn has made an important contribution not only to the literature of the Domain-Driven Design community, but also to the literature of the broader enterprise...
Title: Implementing Cloud Design Patterns for AWS Author: Marcus Young Length: 234 pages Edition: 1 Language: English Publisher: Packt Publishing Publication Date: 2015-05-15 ISBN-10: 1782177345 ISBN-...
Implementing Enterprise Risk Management is a practical guide to establishing an effective ERM system by applying best practices at a granular level. Case studies of leading organizations including ...
Implementing SAP ERP Sales & Distribution_2008
Implementing Qlik Sense 英文azw3 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
高清彩版 Implementing Azure Cloud Design Patterns
实现函数式编程语言语法分析器的书implementing functional languages
Information Retrieval Implementing and Evaluating Search Engines Stefan B¨uttcher Charles L. A. Clarke Gordon V. Cormack
Implementing Domain-Driven Design 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 查看此书详细信息请在美国亚马逊官网搜索此书
This book mirrors the level of detail ...Implementing Cisco QoS (QOS) 2.3 courses. This content includes coverage of Cisco Unified Communications Manager Express (CUCME) and quality of service topics.
Implementing Domain-Driven Design,比较经典的DDD学习资料,全英文版,爱读原版的应该比较喜欢;