編輯:Android開發實例
Android 4.0 系統定義了一系列的高效導航方式 (Effective Navigation), 主要包括標簽、下拉列表、以及向上和返回等, 本文介紹如何用 Mono for Android 實現這些的導航方式。
准備 Android 4.0 ICS 項目
新建 Android ICS 項目
打開 MonoDevelop , 新建一個 Mono for Android 項目, 並在項目的屬性頁將 Target Framework 設置為 Android 4.0.3 (Ice Cream Sandwich)
, 如下圖所示:
添加 Mono.Android.Support.v4 引用項
在解決方案窗口, 選中項目的引用節點, 右擊選擇編輯引用, 添加對 Mono.Android.Support.v4.dll
的引用, 如圖所示:
在項目中新建一個目錄 SupportLib , 並添加對 android-support-v4.jar 文件(位於 android-sdk/extras/android/support/v4 目錄, 如果沒有, 需要用 SDK Manager 安裝)的引用, 並將 jar 文件的編譯動作 (BuildAction) 設置為 AndroidJavaLibrary , 如下圖所示:
本文提到的導航都是根據 Android 4.0 設計規范中推薦的 ActionBar 實現的, 因此整個應用程序啟用帶 ActionBar 的主題, 如果使用 Java 的話, 需要手工編輯 AppManifest.xml 文件的設置, 而用 Mono for Android 的話, 基本上不需要手工編輯這個文件。
Mono for Android 的做法是, 新建一個 App 類, 繼承自 Android.App.Application
類, 並添加 Android.App.ApplicationAttribute
標記, 在編譯時, Mono for Android 會根據這些標記自動生成一個 AppManifest.xml 文件並打包到最終的 apk 文件中。
App 類的代碼如下:
代碼如下:
[Application(Label = "@string/AppName", Icon = "@drawable/ic_launcher",
Theme = "@android:style/Theme.Holo.Light.DarkActionBar")]
public class App : Application {
public App(IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer) {
}
}
添加這個類之後, 項目中的每個 Activity 將默認都是用這個主題, 如果有 Activity 要使用其它的主題, 才需要添加自己的主題屬性。
標簽導航
Android 的標簽用 ActionBar 實現, 用戶既可以點擊標簽切換視圖, 也可以水平滑動切換視圖, 如下圖所示:
用戶既可以點擊上面的 ‘SECTION 0'、 ‘SECTION 1'、 ‘SECTION 2' 標簽切換視圖, 也可以在視圖上水平拖動切換視圖, 同時標簽選中項也要同步選中, 實現的代碼如下:
代碼如下:
[Activity (Label = "@string/AppName", Icon = "@drawable/ic_launcher", MainLauncher = true)]
public class MainActivity : FragmentActivity {
/// <summary>
/// AppSectionsPagerAdapter 提供要顯示的視圖, 繼承自
/// Mono.Android.Support.V4.View.PagerAdapter, 所有加載過視圖都保存在內存中,
/// 如果視圖占用內存過多, 考慮替換成 FragmentStatePagerAdapter 。
/// </summary>
AppSectionsPagerAdapter _appSectionsPagerAdapter;
/// <summary>
/// 用 ViewPager 來顯示視圖三個主視圖, 每次只顯示一個。
/// </summary>
ViewPager _viewPager;
protected override void OnCreate(Bundle bundle) {
base.OnCreate(bundle);
this.SetContentView(Resource.Layout.MainActivity);
// 創建 Adapter
this._appSectionsPagerAdapter = new AppSectionsPagerAdapter(this.SupportFragmentManager);
// 設置 ActionBar
var actionBar = this.ActionBar;
// 首頁不需要向上的 Home 按鈕
actionBar.SetHomeButtonEnabled(false);
// 設置標簽導航模式
actionBar.NavigationMode = ActionBarNavigationMode.Tabs;
// 設置 ViewPager 的 Adapter , 這樣用戶就可以水平滑動切換視圖了
this._viewPager = this.FindViewById<ViewPager>(Resource.Id.Pager);
this._viewPager.Adapter = this._appSectionsPagerAdapter;
// 當水平滑動切換視圖時, 設置選中的標簽
this._viewPager.PageSelected += delegate(object sender, ViewPager.PageSelectedEventArgs e) {
actionBar.SetSelectedNavigationItem(e.P0);
};
// 依次添加三個標簽, 並添加標簽的選中事件處理函數, 設置當前的視圖。
for (var i = 0; i < this._appSectionsPagerAdapter.Count; i++) {
var tab = actionBar.NewTab().SetText(this._appSectionsPagerAdapter.GetPageTitle(i));
tab.TabSelected += delegate(object sender, Android.App.ActionBar.TabEventArgs e) {
this._viewPager.CurrentItem = tab.Position;
};
actionBar.AddTab(tab);
}
}
}
左右導航
標簽導航並不適合所有的場景, 有時僅僅需要顯示視圖的標題即可, 但是同樣可以水平滑動切換視圖, 如下圖所示:
這種導航方式相當於標簽式導航的簡化版, 用戶只可以左右滑動切換視圖, 實現的代碼如下:
代碼如下:
protected override void OnCreate(Bundle bundle) {
base.OnCreate(bundle);
this.SetContentView(Resource.Layout.CollectionDemoActivity);
// 創建 Adapter
this._demoCollectionPagerAdapter = new DemoCollectionPagerAdapter(this.SupportFragmentManager);
// 設置 ViewPager 的 Adapter
this._viewPager = this.FindViewById<ViewPager>(Resource.Id.Pager);
this._viewPager.Adapter = this.mDemoCollectionPagerAdapter;
}
因為要顯示標題, 所以這個 Activity 的 Layout 添加了一個 PagerTitleStrip , Layout 源代碼如下:
代碼如下:
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/Pager"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!--
PaterTitleStrip 即可顯示選中頁面的標題, 也顯示臨近選中的幾個視圖的標題
-->
<android.support.v4.view.PagerTitleStrip android:id="@+id/PagerTitleStrip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#33b5e5"
android:textColor="#fff"
android:paddingTop="4dp"
android:paddingBottom="4dp" />
</android.support.v4.view.ViewPager>
下拉列表
下拉列表導航是在 ActionBar 中顯示一個下拉列表 (Spinner), 就像一個菜單, 只顯示選中的菜單項對應的視圖, 如下圖所示:
將 ActionBar 設置為下拉列表導航時, 一般不顯示 Activity 自身的標題, 因此需要將 Activity 的 Label 標記為空字符串, 並且 Activity 需要實現接口 ActionBar.IOnNavigationListener
, ListNavigationActivity 的部分實現代碼如下:
代碼如下:
[Activity (Label = "")]
public class ListNavigationActivity
: FragmentActivity, ActionBar.IOnNavigationListener {
ListNavSectionsPagerAdapter _navSectionsPagerAdapter;
protected override void OnCreate(Bundle bundle) {
base.OnCreate(bundle);
/* 其他代碼省略 … */
// 設置 ActionBar
var actionBar = this.ActionBar;
// 將 Home 設置為向上
actionBar.SetDisplayHomeAsUpEnabled(true);
// 設置 ActionBar 的導航模式為下拉列表
actionBar.NavigationMode = ActionBarNavigationMode.List;
var titles = new string[this._navSectionsPagerAdapter.Count];
for (var i = 0; i < titles.Length; i++) {
titles[i] = this._navSectionsPagerAdapter.GetPageTitle(i);
}
// 設置列表導航的回調參數
actionBar.SetListNavigationCallbacks(
new ArrayAdapter(
actionBar.ThemedContext,
Resource.Layout.ListNavigationActivityActionbarListItem,
Android.Resource.Id.Text1,
titles
),
this
);
// 設置 ViewPager
this._viewPager = this.FindViewById<ViewPager>(Resource.Id.Pager);
this._viewPager.Adapter = this._navSectionsPagerAdapter;
// 當 ViewPager 的選中頁切換時, 同步 actionBar 的選中項。
this._viewPager.PageSelected += delegate(object sender, ViewPager.PageSelectedEventArgs e) {
actionBar.SetSelectedNavigationItem(e.P0);
};
}
// ActionBar.IOnNavigationListener
public bool OnNavigationItemSelected(int itemPosition, long itemId) {
this._viewPager.CurrentItem = itemPosition;
return true;
}
}
向上導航
所謂的向上導航, 就是在 Activity 的圖標上顯示一個向左的箭頭, 點擊圖標返回應用程序的上一級 Activity , 注意是上一級 Activity , 不是上一個 Activity , 關於向上與返回的區別, 可以看看 Android SDK 中的 Providing Ancestral and Temporal Navigation 一文, 將向上和返回講解的非常清楚, 在這裡只討論 Mono for Android 的實現方式。
要顯示向上導航的按鈕, 需要在 OnCreate
方法中對 ActionBar 做如下設置:
代碼如下:
// 設置 ActionBar
var actionBar = this.ActionBar;
// 將 Home 按鈕顯示為向上, 提示用戶點擊這個按鈕可以返回應用程序的上一級。
actionBar.SetDisplayHomeAsUpEnabled(true);同時還需要重寫 OnOptionsItemSelected 方法, 當用戶點擊 Home 按鈕時, 做相應的處理, 實現向上導航的代碼如下:
public override bool OnOptionsItemSelected(Android.Views.IMenuItem item) {
// 作為示例, 只處理用戶點擊 Home 按鈕的情況。
if (item.ItemId == Android.Resource.Id.Home) {
// 當 Home 按鈕被點擊時會調用到這裡
// 創建啟動上級 Activity 的 Intent
var upIntent = new Intent(this, typeof(MainActivity));
// 使用 Suport Package 中的 NavUtils 來正確處理向上導航
if (NavUtils.ShouldUpRecreateTask(this, upIntent)) {
// 上級 Activity 沒有起動過, 需要創建一個新的導航棧道
TaskStackBuilder.Create(this)
// If there are ancestor activities, they should be added here.
.AddNextIntent(upIntent)
.StartActivities();
this.Finish();
}
else {
// 上級 Activity 已經創建過了, 直接導航就行。
NavUtils.NavigateUpTo(this, upIntent);
}
return true;
}
return base.OnOptionsItemSelected(item);
}
總結
Android 系統的導航與 iOS 相比復雜很多, 實現起來也相對麻煩一些, 好在有 Google 的 Support Package 已經多大部分操作提供了比較好的封裝, 還是比較容易掌握的。 文中的完整的源代碼已經提交的 Github 上, 地址是 https://github.com/beginor/MonoDroid/tree/master/EffectiveNavigation 。
JSON代表JavaScript對象符號。它是一個獨立的數據交換格式,是XML的最佳替代品。本章介紹了如何解析JSON文件,並從中提取所需的信息。Android提供了四個
登錄應用程序的屏幕,詢問憑據登錄到一些特定的應用。可能需要登錄到Facebook,微博等本章介紹了,如何創建一個登錄界面,以及如何管理安全問題和錯誤嘗試。首先,必須定義兩
登錄應用程序的屏幕,詢問憑據登錄到一些特定的應用。可能需要登錄到Facebook,微博等本章介紹了,如何創建一個登錄界面,以及如何管理安全問題和錯誤嘗試。首先,必須定義兩
作為Android應用開發者,不得不面對一個尴尬的局面,就是自己辛辛苦苦開發的應用可以被別人很輕易的就反編譯出來。Google似乎也發現了這個問題,從SDK2.3