編輯:關於Android編程
Action Bar是app應用頂部的一個方形區域,不一定總會顯示(如全屏Theme時),它屬於窗口的一部分,有點類似於windows的窗口的標題欄,如下圖所示:
如上圖所示,標題欄一般會有三類按鈕:
1、可以稱為home區,這裡有一個標識app的按鈕,這個按鈕默認不被激活,圖片顯示默認跟app的圖標一致
2、可以稱為按鈕區,顯示在按鈕區的多個標題欄按鈕
3、“更多”按鈕,點擊可以下拉出隱藏的標題欄按鈕,俗稱:overflow
需要明確的一點是:
ActionBar的API最早是在Android 3.0(API Level 11)的時候加入Android中的,但是我們也可以在Android 2.1(API Level 7)以上的版本使用它,只是需要加入支持包,也就是通常說的 v4 support library和 v7 support library
一般來說,為了兼容性考慮,在寫應用的時候,都會使用兼容性包裡的ActionBar相關API,而不會去使用系統自帶的,所以後面的部分默認都是基於V4和V7包中的內容來介紹。
在導入要使用兼容性包中的ActionBar,我們的MainActivity或者其他XxxActivity就不能在繼承自Activity了,需要換成:ActionBarActivity,然後還需要在清單文件中,換成AppCompat主題或者其子主題,關於主題可以看這一篇ActionBar主題顏色:
public class MainActivity extends ActionBarActivity
ActionBar mActionBar = getSupportActionBar();
然後可以調用下面兩句,讓整個actionBar顯示或者隱藏:
mActionBar.hide(); mActionBar.show();
mActionBar.setHomeButtonEnabled(true); mActionBar.setDisplayShowHomeEnabled(true);//這兩句就可以讓actionBar的圖標可以響應點擊事件 mActionBar.setDisplayHomeAsUpEnabled(true);//這一句主要用於後面返回效果,後面會講
上面的按鈕區,則需要使用一個表示menu的xml文件,一般存放在res/menu/下,然後重寫onCreateOptionsMenu()方法來設置,res/menu/main_activity_actions.xml文件如下:
看到上面使用了一個自定義屬性:showAsAction,這個屬性用於表示按鈕的顯示方式一般常用的有:ifRoom(表示有空間就會顯示出來),withText(表示帶名字,但不一定會顯示,一般會文字會顯示在”更多“按鈕下),never(從不直接顯示在ActionBar上,意味著這個按鈕一直會顯示在”更多“按鈕的下拉菜單上),要注意的是,”更多“按鈕不一定會顯示,如果沒有足夠的空間或者有never屬性的按鈕,則會顯示,否則不會顯示。stackoverflow上有研究過怎麼讓更多一直顯示,感興趣可以看看:http://stackoverflow.com/questions/20444596/how-to-force-action-bar-overflow-icon-to-show
除此之外,上面的xml中還制定了按鈕的id和圖片和title屬性。
然後,可以通過重寫 onCreateOptionsMenu()
方法來讓這些圖標都顯示出來:
@Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu items for use in the action bar MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_activity_actions, menu); return super.onCreateOptionsMenu(menu); }
通過重寫onOptionsItemSelected()方法可以達到目的,但是需要注意的一點是,對於ActionBar圖標,也就是那個app的圖標,它的id是:android.R.id.home。
@Override public boolean onOptionsItemSelected(MenuItem item) { int itemId = item.getItemId(); switch (itemId) { case android.R.id.home: Toast.makeText(this, home, 0).show(); break; case R.id.action_search: Toast.makeText(this, search, 0).show(); break; default: Toast.makeText(this, itemId= + itemId, 1).show(); break; } return super.onOptionsItemSelected(item); }
完成上面的部分,就可以得到一個類似於下面的界面了
在寫App的時候,經常會想需要這樣一個功能,從任意一個Activity返回初始/首頁的activity;這個功能可以很容易的使用ActionBar按鈕來完成。
有兩種實現方式:xml清單文件配置方式 和 java代碼方式。
兩種方式都需要設置上面提到的一個屬性:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_details); ActionBar actionBar = getSupportActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); ... }
假如兩個Activity:A和B,B要返回A,則要在清單文件B的位置,以meta-data的方式,設置android.support.PARENT_ACTIVITY為A的全類名,如下面代碼所示。
... ...
getSupportParentActivityIntent()
和 onCreateSupportNavigateUpTaskStack()
方法。實際上這兩種方法不一定都要重寫,getSupportParentActivityIntent()用於本app內部的activity跳轉,onCreateSupportNavigateUpTaskStack()用於跳轉到其他app的activity,就比較復雜,這裡不做討論,可以查看http://developer.android.com/guide/topics/ui/actionbar.html#ActionViewCollapsing
getSupportParentActivityIntent()返回一個要跳轉的Intent,所以這裡只需要返回一個指向我們想要跳轉到的Activity的Intent對象即可實現跳轉。
相對而言,代碼方式更加靈活。
值得注意的是,上述兩種方法只能應用於Activity之間的跳轉,如果想要應用於Fragment之間,需要使用 onSupportNavigateUp()
和popBackStack()方法。
首先需要在上面的menu的xml文件中的對應item,比如上面的action_search所在的item中,添加一個自定義屬性來為這個按鈕添加一個SearchView:
然後需要在onCreateOptionsMenu方法中,把這個SearchView創建出來:
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main_activity_actions, menu); MenuItem searchItem = menu.findItem(R.id.action_search); SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem); // Configure the search info and add any event listeners ... return super.onCreateOptionsMenu(menu); }
在添加了之後點擊搜索按鈕,就會有對應的搜索欄顯示出來:
但是現在這樣還不太爽。。。一沒有搜索提示文字,二沒有真正能搜索的功能,下面就來做這兩步:
搜索提示文字(hint):
這裡需要一個寫一個searchable的xml文件到res/xml/文件夾下:
res/xml/searchable.xml
接下來,就要將這個searchable.xml與我們要展示搜索結果的那個activity在清單文件中關聯起來,這裡也需要使用到meta-data,注意這裡位置是要顯示搜索結果的那個activity,而不一定是當前activity:
...
然後,我們還需要將搜索的輸入框默認與對應的搜索activity掛鉤,也要使用meta-data,但是需要在application內或者別的要搜索的activity內配置,這裡以卸載application內為例:
...
這裡配置好之後,我們就要在這個要顯示搜索結果的activity中的onCreate方法中,接收發來的Intent對象,然後判斷這個Intent對象是不是要請求搜索:Intent.ACTION_SEARCH
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.search); // Get the intent, verify the action and get the query Intent intent = getIntent(); if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); doSearching(query); } }
private void doSearching(String query) { System.out.println(做一些搜索的耗時操作....); }
下面把返回功能和搜索放到一起,效果如圖:
1. Fragment概述Fragment從Android v3.0版本開始引入隨著界面布局的復雜化,處理起來也更加的復雜,引入Fragment可以把activity拆分
我們常用context.startService()來啟動一個service,下面來分析一下這個service的啟動過程,下圖是service啟動的序列圖: st
一、開發背景:我目前在做的是一個3年左右的老項目,項目開始的時候okhttp還不像現在這麼火,基本上使用HttpURLConnection類來實現所有的HTTP請求,當時
ContentProvider,從字面意義上理解,內容提供者,這個類目的就是一個橋梁的作用,讓一個應用的數據(SQLiteDatabase, SharedPreferen