Android新特徵爲了兼容老版本,改變了很多東西,這裏先對幾個重要的特徵進行研究。
第一,系統生成工程出現一個v7的東西,這個是兼容包,很多人覺得很不爽,忘了他把,這個是必要的,不能刪除,工程要用到裏面的v7擴展包和主題資源什麼的,而且你用到fragment的話就必須要那個包裏的主題!測試可以直接點中你要的工程進行測試就可以了,無需其他操作,和之前的一樣!
第二:系統默認的佈局變成了兩個,一個是main_activity和fragment_activity兩個。這個是什麼原因,main的佈局默認是<fragment>根節點,fragment的佈局是默認相對佈局的,這個你可以隨便改,線性佈局,幀佈局的都可以用,和我們之前用的main_activity是一樣的,那他們有什麼關係呢,其實這裏要說一點,對於fragment有兩種裝載方式: 第一是佈局裝載,直接在佈局中寫入fragment節點,如下:
<?xmlversion="1.0"encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:name="com.example.news.ArticleListFragment" android:id="@+id/list" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <fragment android:name="com.example.news.ArticleReaderFragment" android:id="@+id/viewer" android:layout_weight="2" android:layout_width="0dp" android:layout_height="match_parent"/> </LinearLayout>
這個fragment節點必須要有id,這樣代碼才能針對不同的id進行不同的裝載。
第二是代碼裝載,就是官方提供的默認裝載,如下:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="walleeva.android4_4_frame.MainActivity" tools:ignore="MergeRootFrame" />
然後通過framelayout 的id進行代碼裝載,目測兩種其實有不同,一個是針對一個頁面多個fragment分塊顯示,一個是一個頁面顯示一個fragment,然後通過裝載來切換!
這裏我們簡單總結一下fragment和一activity的區別:
Activity的佈局是一個容器,好比一個房間的整個空間,fragment好比是對其進行裝修,你可以一個裝修風格佈滿整個房間,也可以分開很多塊分別專修,可以通過不同時候,顯示不同燈光效果達到參觀者(用戶)看到不同表現。
既然谷歌選擇默認後一種,我們就從這種開始研究,首先,我們看到MainActivity,發現大問題,不是繼承了Activity,而是ActionBarActivity,這裏又有新知識,(我是對fragment和actionbar不熟悉的,所以我覺得是新知識),actionbaractivity和activity有什麼區別呢?
百度是這樣回答的:AndroidBarActivity是支持庫裏的類可以兼容2.x版本 activity提供的actionbar只有在3.0以上纔可以用.
顯然這個答案太抽象,現在我們先完成fragment的顯示切換,然後在修改使得他通過actionbar進行切換。
完成fragment佈局切換:
1,在manifest文件中的application節點修改主題:
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/Theme.AppCompat.Light" >
貌似都要用appcompat下的主題才行!當然你可以針對activity節點進行修改,我這樣一勞永逸。
2,新建多一個fragment_main佈局,內容可以隨意,
3,新建兩個類,你可以將系統默認裏面生產的類拷貝出來,然後在新建類中粘帖上去,把原來mainactivity中的內部類刪除,這些類都是繼承import android.support.v4.app.Fragment;
至於fragment的類要怎麼寫,先給出fragment的生命週期
你可以右鍵空白處,source,然後Override選項查看有那些可覆寫的方法,這個給個例子
public class PlaceholderFragment extends Fragment { public TextView text; SendDateToActivity sdta; public PlaceholderFragment() { } @Override public void onAttach(Activity activity) { super.onAttach(activity); try{ //這裏進行綁定實現,如果activity沒有實現對應辦法,則會出錯! sdta=(SendDateToActivity)activity; }catch(ClassCastException e){ } } @Override public void onStart() { //所有在frame佈局中定義的控件都需要在oncreateview這個方法執行後實例 //化,最好在這裏就可以了,否則死了都不知道什麼回事! text=(TextView)getActivity().findViewById(R.id.fragment1t1); //這裏進行調用 text.setText(sdta.setEditText()); super.onStart(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //這個方法進行裝載fragment, View rootView = inflater.inflate(R.layout.fragment_main,container,false); return rootView; } //這是一個接口,對應的實現寫在activity中,實現對應的方法,這樣,這裏就可以調用activity中的方法,實現數據傳遞。 public interface SendDateToActivity{ public String setEditText(); } }
這裏是mainactivity的源代碼,一起貼出來
public class MainActivity extends ActionBarActivity implements SendDateToActivity,SendDateToActivity2{ public String edittext; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); if (savedInstanceState == null) { //這裏預先裝載了一個fragment進行顯示。 getSupportFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment2()).commit(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { //這裏定義了兩個按鈕 MenuInflater menuInflater = getMenuInflater(); menuInflater.inflate(R.menu.main, menu); MenuItem menuItem = menu.findItem(R.id.action_search); MenuItem findItem = menu.findItem(R.id.action_compose); MenuItemCompat.setShowAsAction(menuItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); MenuItemCompat.setShowAsAction(findItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); return true; } //這裏進行按鈕選擇 @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_compose) { getSupportFragmentManager().beginTransaction().replace(R.id.container, new PlaceholderFragment()).commit(); return true; }else if(id == R.id.action_search){ getSupportFragmentManager().beginTransaction().replace(R.id.container, new PlaceholderFragment2()).commit(); return true; } return super.onOptionsItemSelected(item); } }
菜單佈局如下:
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context="walleeva.android4_4_frame.MainActivity"> <item android:id="@+id/action_search" android:icon="@drawable/abc_ic_clear" android:title="@string/action_settings"/> <item android:id="@+id/action_compose" android:icon="@drawable/abc_ic_go" android:title="@string/abc_activity_chooser_view_see_all"/> </menu>
這樣就實現了按菜單按鈕實現fragment切換,按fragment2中的按鈕可以實現參數傳遞到另一個fragment進行顯示,
這裏完成了fragment切換及其參數傳遞的功能,這樣面對新的默認佈局,我們也能從容面對了。
可是還有一個問題就actionbar,首先明白actionbar是什麼,顧名思義就是action的一個bar,也就是動作的點擊按鈕之類的!可以這麼理解吧!Csdn有人這麼歸納:
通過查資料,最後實現了通過actionbar進行頁面切換,下拉導航,標籤頁切換fragment,第四第五個還不知道什麼意思,畢竟也是初次接觸。大神請忽略這篇文檔!
其實要實現actionbar,需要做以下幾件事,
1,就是你的activity必須是以android:theme="@style/Theme.AppCompat.Light"爲主題,或者繼承它的自定義主題
2,必須要顯示標題欄,不可設置爲無標題欄顯示狀態,網上有方法說可以解決,但是試過不行,有待研究,
3,如果要在底部出現菜單欄請在對於的activity節點中加入如下: android:uiOptions="splitActionBarWhenNarrow"
4,對於要顯示的item一般和系統的meun寫法一樣,只不過多一個android:showAsAction="never" 建議這個屬性用代碼實現,因爲很容易出現沒效果的,如之前onCreateOptionsMenu方法中的代碼所示
5,對於MenuItemCompat.SHOW_AS_ACTION_ALWAYS,後面的爲參數有5,6種類型,可以直接百度,具體是用來控制bar顯示還是隱藏的相關屬性,不同屬性有不同表現方式!
6,對於顯示下拉列表功能則是通過如下代碼實現
PopupMenu mPopupMenu=null; case R.id.myselfitem: //這個爲監聽的按鈕,也可是一個bar if (mPopupMenu == null) { mPopupMenu = new PopupMenu(this, findViewById(R.id.myselfitem)); //這個id爲按鈕id mPopupMenu.inflate(R.menu.mymeun); //此時所在類要實現OnMenuItemClickListener,然後在接口中獲取item的id,根據id //進行響應即可 mPopupMenu.setOnMenuItemClickListener(this); } mPopupMenu.show(); return true;
對應佈局很簡單
和系統的meun寫法一樣的!自己去定義,
7,標籤頁現在應該都是統一用actionbar來實現了,而不是用之前的tabhost,actionbar完成可以通過控制不同的fragment顯示,具體代碼如下:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_theme_holo); getActionBar().setDisplayHomeAsUpEnabled(true); getActionBar().setHomeButtonEnabled(true); final ActionBar actionBar = getSupportActionBar(); //提示getActionBar方法一定在setContentView後面 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); actionBar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE); Fragment artistsFragment = new PlaceholderFragment(); actionBar.addTab(actionBar.newTab().setText("first").setTabListener( new MyTabListener(artistsFragment))); Fragment albumsFragment = new PlaceholderFragment2(); actionBar.addTab(actionBar.newTab().setText("second").setTabListener( new MyTabListener(albumsFragment))); }
在對於的activity中的oncreate函數中如上代碼,然後寫一個tablistener的內部類
private class MyTabListener implements ActionBar.TabListener { private Fragment mFragment; public MyTabListener(Fragment fragment) { mFragment = fragment; } @Override public void onTabSelected(Tab tab, FragmentTransaction ft) { ft.add(R.id.container2, mFragment, null); } @Override public void onTabUnselected(Tab tab, FragmentTransaction ft) { ft.remove(mFragment); } @Override public void onTabReselected(Tab tab, FragmentTransaction ft) { } } @Override public boolean onMenuItemClick(MenuItem arg0) { int id=arg0.getItemId(); if(id==R.id.action_search2){ System.out.println("search2"); }else if(id==R.id.action_compose2){ System.out.println("action_compose2"); } return false; }
即可實現標籤頁的效果!