作爲一個Android開發人員,應該沒有誰不知道Fragment!其重要性可想而知了!不多說,先上圖
實例一(使用ListFragment和Fragment結合實現):
實例二(Fragment結合RadioButton)
Fragment的特徵:
Fragment必須嵌入到Activity中使用。因此,即使Fragment擁有自己的生命週期,也會收到它所在的Activity的生命週期的控制。當Activity暫停時,Activity中所有的Fragment都會暫停;當Activity被銷燬時,其中所有的Fragment將會被銷燬;只有Activity處於活動狀態時,程序員纔可以通過方法獨立地操作Fragment。
Fragment總是作爲Activity界面組成部分。Fragment可調用getActivity()方法獲取它所在的Activity。Activity可調用 FragmentManager的findFragmentById()或者findFragmentBuTag()方法來獲取Fragment
在Activity運行過程中,可調用FragmentManager的add(),remove(),replace()方法動態添加,移除,修改。
一個Activity可以同時擁有多個Fragment,一個Fragment也可以被多個Activity複用。
- Fragment可以響應自己的輸入事件,並擁有自己的生命週期,但生命週期被所屬的Activity的生命週期控制。
Fragment常用知識點:
Fragment和所屬Activity的通訊如何處理!
Activity向Fragment傳遞數據:在Activity中創建Bundle數據包,並調用Fragment的setArgument(Bundle bundle)方法將Bundle數據傳遞給Fragment.
Fragment向Activity傳遞數據:Fragment中定義一個內部回調接口,再讓包含該Fragment的Activity實現該回掉接口,這樣就能將Fragment的數據傳給Activity了!
如何將Fragment添加到Activity中:
在佈局文件中使用<fragment…/>元素添加Fragment,<fragment…/>元素的android:name屬性指定Fragment的實現類
在Java代碼中通過FragmentTransaction對象的add()方法來添加Fragment.
Activity獲取它包含的Fragment:用Fragment的getActivity();
Fragment獲取它所在的Activity:調用關聯的FragmentMangager的findFragmentById(int id)或者fingFragmentByTag(String tag)方法即可獲取Fragment。
Fragment管理
FragmentManager可以實現以下幾方面的功能:
- 使用 findFragmentById(int id)或fingFragmentByTag(String tag)方法來獲取指定的Fragment。
- 調用popBackStack()方法將Fragment從後臺中彈出(模擬用戶按下Back鍵)
- 調用addOnBackStackChangeListener()註冊一個監聽器,用於監聽後臺棧的變化。
Fragment事務
如果需要添加,刪除,替換Fragment,則需要藉助於FragmentTransaction對象,FragmentTransaction代表Activity對Fragment執行多個改變
*
Fragment的生命週期
這裏就不再手打贅述,直接從官網上覆制最原始的解釋給大家!多囉嗦一句,學習任何語言,官方文檔一定要看。
The core series of lifecycle methods that are called to bring a fragment up to resumed state (interacting with the user) are:
onAttach(Activity) :called once the fragment is associated with its activity.
onCreate(Bundle): called to do initial creation of the fragment.
onCreateView(LayoutInflater, ViewGroup, Bundle) :creates and returns the view hierarchy associated with the fragment.
onActivityCreated(Bundle) :tells the fragment that its activity has completed its own Activity.onCreate().
onViewStateRestored(Bundle) :tells the fragment that all of the saved state of its view hierarchy has been restored.
onStart(): makes the fragment visible to the user (based on its containing activity being started).
onResume(): makes the fragment begin interacting with the user (based on its containing activity being resumed).
As a fragment is no longer being used, it goes through a reverse series of callbacks:
onPause(): fragment is no longer interacting with the user either because its activity is being paused or a fragment operation is modifying it in the activity.
onStop(): fragment is no longer visible to the user either because its activity is being stopped or a fragment operation is modifying it in the activity.
onDestroyView(): allows the fragment to clean up resources associated with its View.
onDestroy(): called to do final cleanup of the fragment’s state.
onDetach() :called immediately prior to the fragment no longer being associated with its activity.
創建Fragment
通常來說,創建Fragment只需要實現如下三個方法:
onCreat();
onCreatView();
onPause();
按需求可重寫其他方法。
實例一:
MainActivity.java:用於對整個進程的控制
FoodContent:實體類
FoodListFragment:顯示食品列表的Fragment
FoodDetailFragment:顯示食品詳細信息的Fragment
activity_main.xml:佈局文件
……
MainActivity代碼:
public class MainActivity extends AppCompatActivity implements FoodListFragment.Callbacks{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void onItemSelected(Integer id) {
// 創建Bundle,準備向Fragment傳入參數
Bundle arguments = new Bundle();
arguments.putInt(FoodDetailFragment.ITEM_ID, id);
// 創建FoodDetailFragment對象
FoodDetailFragment fragment = new FoodDetailFragment();
// 向Fragment傳入參數
fragment.setArguments(arguments);
// 使用fragment替換book_detail_container容器當前顯示的Fragment
getFragmentManager().beginTransaction()
.replace(R.id.food_detail_container, fragment)
.commit();
}
}
FoodContent.java
public class FoodContent {
// 定義一個內部類,作爲系統的業務對象
public static class Food
{
public Integer id;
public String name;
public String desc;
public Food(Integer id, String name, String desc)
{
this.id = id;
this.name = name;
this.desc = desc;
}
@Override
public String toString()
{
return name;
}
}
// 使用List集合記錄系統所包含的Food對象
public static List<Food> ITEMS = new ArrayList<Food>();
// 使用Map集合記錄系統所包含的Food對象
public static Map<Integer, Food> ITEM_MAP
= new HashMap<Integer, Food>();
static
{
// 使用靜態初始化代碼,將Food對象添加到List集合、Map集合中
addItem(new Food(1, "土豆"
, "馬鈴薯(學名:Solanum tuberosum),屬茄科多年生草本植物,塊莖可供食用,是全球第四大重要的糧食作物,僅次於小麥、稻穀和玉米。馬鈴薯又稱地蛋、土豆 、洋山芋等,茄科植物的塊莖。與小麥、稻穀、玉米、高粱併成爲世界五大作物。"));
addItem(new Food(2, "紅薯"
, "[1]紅薯(英文: sweet potato)原名番薯(學名:Ipomoea batatas (L.) Lam.),又名紅芋、甘薯、蕃薯、大米、番芋、地瓜(北方)、紅苕、線苕、白薯、金薯、甜薯、朱薯、枕薯、番葛、白芋、茴芋地瓜等。 "
));
addItem(new Food(3, "黃瓜", "黃瓜,(學名Cucumis sativus Linn,英文名Cucumber),葫蘆科黃瓜屬植物。也稱胡瓜、青瓜、刺瓜。果實顏色呈油綠或翠綠,表面有柔軟的小刺。 中國各地普遍栽培,現廣泛種植於溫帶和熱帶地區。"));
addItem(new Food(4, "茄子", "茄(學名:Solanum melongena)常稱茄子,吳越人沿用宋代叫法稱爲落蘇,廣東人稱爲矮瓜,是茄科茄屬一年生草本植物,熱帶爲多年生。其結出的果實可食用,顏色多爲紫色或紫黑色,也有淡綠色或白色品種,形狀上也有圓形,橢圓,梨形等各種。茄子是一種典型的蔬菜,根據品種的不同,食用方法多樣。"));
addItem(new Food(5, "蘿蔔", "蘿蔔(學名:Raphanus sativus)。別名萊菔、菜頭,十字花科草本植物。蘿蔔的根部是最常見的蔬菜之一,但實際上整株植物都是可喫的。種子稱爲萊菔子,是常用的中藥。"));
addItem(new Food(6, "韭菜", "山韭(拉丁學名:Allium senescens L.),是百合科蔥屬植物,產黑龍江、吉林、遼寧、河北、山西、內蒙古、甘肅(東部)、新疆(西北部)和河南、(西北部)。"));
addItem(new Food(7, "白菜", "白菜原產於我國北方,是十字花科蕓薹屬一年生、二年生草本植物。通常指大白菜;也包括小白菜以及由甘藍的栽培變種結球甘藍,即“圓白菜”或“洋白菜”。引種南方,南北各地均有栽培。"));
addItem(new Food(8, "冬瓜", "冬瓜,一年生草本植物,莖上有卷鬚,能爬蔓,葉子大,開黃花。果實球形或長圓柱形,表面有毛和白粉,皮深綠色,是普通蔬菜。皮和種子可入藥。"));
addItem(new Food(9, "青菜", "青菜(Brassica chinensis var chinensis),中國東北稱油菜,爲一年生草本,蕓薹屬,顏色深綠,莖、葉用蔬菜。"));
addItem(new Food(10, "玉米", "玉米(拉丁學名:Zea mays L.)是禾本科玉米屬一年生草本植物。別名:玉蜀黍、棒子、包穀、包米、玉茭、苞米、珍珠米、苞蘆、大蘆粟,潮汕話稱幼米仁,粵語稱爲粟米,閩南語稱作番麥。"));
addItem(new Food(11, "辣椒", "辣椒(學名:Capsicum annuum),又叫牛角椒、長辣椒、番椒、番姜、海椒、辣子、辣角、秦椒等,是一種茄科辣椒屬植物。原產於中南美洲熱帶地區。"));
}
private static void addItem(Food Food)
{
ITEMS.add(Food);
ITEM_MAP.put(Food.id, Food);
}
}
FoodListFragment.java
public class FoodListFragment extends ListFragment {
private Callbacks mCallbacks;
// 定義一個回調接口,該Fragment所在Activity需要實現該接口
// 該Fragment將通過該接口與它所在的Activity交互
public interface Callbacks
{
public void onItemSelected(Integer id);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 爲該ListFragment設置Adapter
setListAdapter(new ArrayAdapter<FoodContent.Food>(getActivity(),
android.R.layout.simple_list_item_activated_1,
android.R.id.text1, FoodContent.ITEMS));
}
// 當該Fragment被添加、顯示到Activity時,回調該方法
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
// 如果Activity沒有實現Callbacks接口,拋出異常
if (!(activity instanceof Callbacks))
{
throw new IllegalStateException(
"FoodListFragment所在的Activity必須實現Callbacks接口!");
}
// 把該Activity當成Callbacks對象
mCallbacks = (Callbacks)activity;
}
// 當該Fragment從它所屬的Activity中被刪除時回調該方法
@Override
public void onDetach()
{
super.onDetach();
// 將mCallbacks賦爲null。
mCallbacks = null;
}
// 當用戶單擊某列表項時激發該回調方法
@Override
public void onListItemClick(ListView listView
, View view, int position, long id)
{
super.onListItemClick(listView, view, position, id);
// 激發mCallbacks的onItemSelected方法
mCallbacks.onItemSelected(FoodContent
.ITEMS.get(position).id);
}
public void setActivateOnItemClick(boolean activateOnItemClick)
{
getListView().setChoiceMode(
activateOnItemClick ? ListView.CHOICE_MODE_SINGLE
: ListView.CHOICE_MODE_NONE);
}
}
FoodDetailFragment.java
public class FoodDetailFragment extends Fragment {
public static final String ITEM_ID = "item_id";
// 保存該Fragment顯示的Food對象
FoodContent.Food food;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 如果啓動該Fragment時包含了ITEM_ID參數
if (getArguments().containsKey(ITEM_ID))
{
food = FoodContent.ITEM_MAP.get(getArguments()
.getInt(ITEM_ID));
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View ret = inflater.inflate(R.layout.fragment_food_detail, container, false);
if (food != null) {
// 讓food_title文本框顯示food對象的title屬性
((TextView) ret.findViewById(R.id.food_title))
.setText(food.name);
// 讓food_desc文本框顯示food對象的desc屬性
((TextView) ret.findViewById(R.id.food_desc))
.setText(food.desc);
}
return ret;
}
}
main.xml代碼:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.dejasen.fragmenttest.MainActivity">
<fragment
android:name="com.dejasen.fragmenttest.FoodListFragment"
android:id="@+id/food_list"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"/>
<FrameLayout
android:id="@+id/food_detail_container"
android:layout_weight="3"
android:layout_width="0dp"
android:layout_height="match_parent"/>
</LinearLayout>
實例二:
幾個知識點:
- 用style寫公用的屬性
- radioButton和Fragment的連動
MainActivity代碼:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
RadioGroup group = (RadioGroup) findViewById(R.id.main_tab_bar);
if (group != null) {
group.setOnCheckedChangeListener(this);
}
mOneFragment = new OneFragment();
mTwoFragment = new TwoFragment();
mThreeFragment = new ThreeFragment();
mFourFragment = new FourFragment();
group.check(R.id.main_tab_item_send);
}
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
switch (checkedId){
case R.id.main_tab_item_send:
ft.replace(R.id.fragment_container,mOneFragment);
break;
case R.id.main_tab_item_cam:
ft.replace(R.id.fragment_container,mTwoFragment);
break;
case R.id.main_tab_item_tel:
ft.replace(R.id.fragment_container,mThreeFragment);
break;
case R.id.main_tab_item_dat:
ft.replace(R.id.fragment_container,mFourFragment);
break;
}
ft.commit();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.jasen.fragmenthomework.MainActivity"
android:weightSum="1">
<!--<fragment
android:id="@+id/radioGroup"
class="com.jasen.fragmenthomework.Fragment.RadioFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>-->
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:background="#cccccc"
android:layout_height="0dp"
android:layout_weight="1"
>
</FrameLayout>
<RadioGroup
android:id="@+id/main_tab_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
>
<RadioButton
android:id="@+id/main_tab_item_send"
style="@style/rb_style"
android:drawableTop="@android:drawable/ic_menu_send"
android:text="發送"
/>
<RadioButton
android:id="@+id/main_tab_item_cam"
style="@style/rb_style"
android:drawableTop="@android:drawable/ic_menu_camera"
android:text="相機"
/>
<RadioButton
android:id="@+id/main_tab_item_tel"
style="@style/rb_style"
android:drawableTop="@android:drawable/ic_menu_call"
android:text="電話"
/>
<RadioButton
android:id="@+id/main_tab_item_dat"
style="@style/rb_style"
android:drawableTop="@android:drawable/ic_menu_agenda"
android:text="日程"
/>
</RadioGroup>
</LinearLayout>
styles.xml代碼:
<style name="rb_style">
<item name="android:gravity">center</item>
<item name="android:layout_weight">1</item>
<item name="android:layout_gravity">bottom</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:button">@null</item>
<item name="android:textColor">@color/cb_color_sel</item>
<item name="android:drawableTint">@color/cb_color_sel</item>
</style>
選擇器代碼:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="#4b93f1"/>
<item android:color="#000"/>
</selector>