Android中如何使用Fragment打造出炫酷效果

作爲一個Android開發人員,應該沒有誰不知道Fragment!其重要性可想而知了!不多說,先上圖

實例一(使用ListFragment和Fragment結合實現):
Fragment

實例一源代碼代碼下載地址

實例二(Fragment結合RadioButton)
Fragment

實例二源代碼下載地址

Fragment

Fragment文件下載地址

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的通訊如何處理!

    1. Activity向Fragment傳遞數據:在Activity中創建Bundle數據包,並調用Fragment的setArgument(Bundle bundle)方法將Bundle數據傳遞給Fragment.

    2. Fragment向Activity傳遞數據:Fragment中定義一個內部回調接口,再讓包含該Fragment的Activity實現該回掉接口,這樣就能將Fragment的數據傳給Activity了!

  • 如何將Fragment添加到Activity中:

    1. 在佈局文件中使用<fragment…/>元素添加Fragment,<fragment…/>元素的android:name屬性指定Fragment的實現類

    2. 在Java代碼中通過FragmentTransaction對象的add()方法來添加Fragment.

  • Activity獲取它包含的Fragment:用Fragment的getActivity();

  • Fragment獲取它所在的Activity:調用關聯的FragmentMangager的findFragmentById(int id)或者fingFragmentByTag(String tag)方法即可獲取Fragment。

  • Fragment管理

    FragmentManager可以實現以下幾方面的功能:

    1. 使用 findFragmentById(int id)或fingFragmentByTag(String tag)方法來獲取指定的Fragment。
    2. 調用popBackStack()方法將Fragment從後臺中彈出(模擬用戶按下Back鍵)
    3. 調用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:

  1. onAttach(Activity) :called once the fragment is associated with its activity.

  2. onCreate(Bundle): called to do initial creation of the fragment.

  3. onCreateView(LayoutInflater, ViewGroup, Bundle) :creates and returns the view hierarchy associated with the fragment.

  4. onActivityCreated(Bundle) :tells the fragment that its activity has completed its own Activity.onCreate().

  5. onViewStateRestored(Bundle) :tells the fragment that all of the saved state of its view hierarchy has been restored.

  6. onStart(): makes the fragment visible to the user (based on its containing activity being started).

  7. 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:

  1. 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.

  2. 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.

  3. onDestroyView(): allows the fragment to clean up resources associated with its View.

  4. onDestroy(): called to do final cleanup of the fragment’s state.

  5. 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>

實例二:

幾個知識點:

  1. 用style寫公用的屬性
  2. 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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章