Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Fragment(碎片)(1)

Fragment(碎片)(1)

編輯:關於Android編程

Fragment

碎片(Fragment)是一種可以嵌入在活動當中的UI片段,它能讓程序更加合理和充分地利用大屏幕的空間,因而在平板上應用的非常廣泛。

碎片是什麼

這是《第一行代碼》書中的介紹
  想象我們正在開發一個新聞應用,其中一個界面使用ListView展示了一組新聞的標題,當點擊了其中一個標題,就打開另一個界面顯示新聞的詳細內容。如果是在手機中設計,我們可以將新聞標題列表放在一個活動中,將新聞的詳細內容放在另一個活動中,如圖所示。

這裡寫圖片描述

可是如果在平板上也這麼設計,那麼新聞標題列表將會被拉長至填充滿整個平板的屏幕,而新聞的標題一般都不會太長,這樣將會導致界面上有大量的空白區域,如圖所示。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPjxpbWcgYWx0PQ=="這裡寫圖片描述" src="/uploadfile/Collfiles/20160827/20160827093239539.png" title="\" />

因此,更好的設計方案是將新聞標題列表界面和新聞詳細內容界面分別放在兩個碎片中,然後在同一個活動裡引入這兩個碎片,這樣就可以將屏幕空間充分地利用起來了,如圖所示。

這裡寫圖片描述

Fragment的出現就是為了解決屏幕適配問題。你可以把Fragment當成Activity的一個界面的一個組成部分,甚至Activity的界面可以完全有不同的Fragment組成,而且Fragment擁有自己的生命周期和接收、處理用戶的事件,這樣就不必在Activity寫一堆控件的事件處理的代碼了。更為重要的是,你可以動態的添加、替換和移除某個Fragment。

Fragment的簡單使用

Fragment必須依附Activity的存在,通過Activity來加載Fragment

定義一個類繼承Fragment

import android.support.v4.app.Fragment;
....
public class Fragment3 extends Fragment {
    @Nullable
    //重寫onCreateView方法
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    //通過打氣筒加載Fragment的布局
        View view = inflater.inflate(R.layout.fragment3,null);
        return view;
    }
}

導入Fragment包的選擇

support.v4.app.Fragment;

import android.support.v4.app.Fragment;

android.app.Fragment3.0之後才有的,支持的版本太高
選擇v4包,是為了可以兼容到1.6的版本的手機,但會影響到獲取FragmentManager方式的不同
而且非常非常重要的是包含Fragment的Activity必須繼承FragmentActivity
否則你就等著報錯吧

android.app.Fragment;

import android.app.Fragment;

導入這個包則不需修改Activity


Fragment3的布局文件




    

activity的布局文件




    
        
        
        

MainActivity記得繼承FragmentActivity

import android.support.v4.app.FragmentActivity;
...
public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

}

結果
這裡寫圖片描述

Fragment的動態使用1

首先給出程序運行成功的gif圖

這裡寫圖片描述

這是一個橫豎屏切換時,切換Activity裡的Fragment的效果
這裡分別定義一個橫屏的Fragment和一個豎屏的Fragment

橫屏 Fragment1
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * Created by Peng on 2016/8/4.
 */
public class Fragment1 extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment1, null);
        return view;
    }
}
橫屏 Fragment1 布局



    

豎屏 Fragment2
public class Fragment2 extends Fragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment2,null);

        return view;
    }
}
豎屏 Fragment2布局



    


MainActivity
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.view.WindowManager;

public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //獲取手機的分辨率
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        int width = wm.getDefaultDisplay().getWidth();
        int height = wm.getDefaultDisplay().getHeight();

        /**
         * 如果使用的不是v4包的Fragment,就要用getFragmentManager()的到管理者
         * 而且FragmentManager也是用android.app.FragmentManager包
         *  FragmentManager fragmentManager = getFragmentManager();
         */

        //獲取fragment的管理者 通過上下文獲取
        FragmentManager fragmentManager = getSupportFragmentManager();
        //開啟事物
        android.support.v4.app.FragmentTransaction beginTrasaction = fragmentManager.beginTransaction();

        //判斷橫豎
        if (height > width) {
            //豎屏 android.R.id.content 代表當前手機的窗體
            beginTrasaction.replace(android.R.id.content, new Fragment1());
        } else {
            //橫屏
            beginTrasaction.replace(android.R.id.content, new Fragment2());

        }
        //最後一步
        beginTrasaction.commit();
    }
}

Activity的布局文件裡並不需要設置,Fragment的布局會和activity共同顯示在Activity上
你可以在Activity裡寫一些內容,內容會一直顯示出來


Fragment的動態使用2

首先程序運行的效果

fragment切換


Activity的布局 activity_main.xml




    
    

    
    



bottom.xml




    

Fragment,這裡用的是android.app.Fragment的包,沒有用v4
的包,注意一下

import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * Created by Peng on 2016/8/4.
 */
public class ContactFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view =inflater.inflate(R.layout.fragment_contact,null);
        return  view;
    }
}

四個Fragment的布局,這裡只寫一個,都是類似的



    


MainActivity

import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private LinearLayout llLayout;
    private Button btnWx;
    private Button btnContact;
    private Button btnDiscover;
    private Button btnMe;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        llLayout = (LinearLayout) findViewById(R.id.ll_layout);

        //四個按鈕 微信 通訊錄 發現 我
        btnWx = (Button) findViewById(R.id.btn_wx);
        btnContact = (Button) findViewById(R.id.btn_contact);
        btnDiscover = (Button) findViewById(R.id.btn_discover);
        btnMe = (Button) findViewById(R.id.btn_me);

        //設置事件
        btnWx.setOnClickListener(this);
        btnContact.setOnClickListener(this);
        btnDiscover.setOnClickListener(this);
        btnMe.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        //獲取fragment的管理者
        FragmentManager fragmentManager = getFragmentManager();
        //開啟事物
        FragmentTransaction beginTrasaction = fragmentManager.beginTransaction();

        //具體判斷點擊那個按鈕
        switch (view.getId()) {
            case R.id.btn_wx://點擊的是微信
                beginTrasaction.replace(R.id.ll_layout, new WxFragment());

                break;
            case R.id.btn_contact://點擊的是聯系人
                beginTrasaction.replace(R.id.ll_layout, new ContactFragment());

                break;
            case R.id.btn_discover://點擊的是發現
                beginTrasaction.replace(R.id.ll_layout, new DiscoverFragment());

                break;
            case R.id.btn_me://點擊的是我
                beginTrasaction.replace(R.id.ll_layout, new MeFragment());

                break;
        }
        beginTrasaction.commit();

    }
}

用replace切換顯示的Fragment,這種方法非常方便,但是這種方法不是最完美的, 下面-FragmentTransaction的方法-裡關於它的介紹

在Fragment中模擬返回棧

當我們通過點擊按鈕添加了一個碎片之後,這時按下Back鍵程序就會直接退出。如果這裡我們想模仿類似於返回棧的效果,按下Back鍵可以回到上一個碎片,該如何實現呢?
其實很簡單,FragmentTransaction中提供了一個addToBackStack()方法,可以用於將一個事務添加到返回棧中,修改MainActivity中的代碼,

public class MainActivity extends Activity implements OnClickListener {
    ……
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.button:
            AnotherRightFragment fragment = new AnotherRightFragment();
            FragmentManager fragmentManager = getFragmentManager();
            FragmentTransaction transaction = fragmentManager. beginTransaction();
            transaction.replace(R.id.right_layout, fragment);
            //加上這句
            transaction.addToBackStack(null);
            transaction.commit();
            break;
        default:
            break;
        }
    }
}

FragmentTransaction的方法


transaction.add()     往Activity中添加一個Fragment

transaction.remove()     從Activity中移除一個Fragment,如果被移除的Fragment沒有添加到回退棧,這個Fragment實例將會被銷毀。

transaction.replace()    使用另一個Fragment替換當前的,實際上就是remove()然後add()

transaction.hide()   隱藏當前的Fragment,僅僅是設為不可見,並不會銷毀

transaction.show()    顯示之前隱藏的Fragment

detach()    會將view從UI中移除,和remove()不同,此時fragment的狀態依然由FragmentManager維護。

attach()    重建view視圖,附加到UI上並顯示。

transatcion.commit()   提交一個事務


Fragment進階使用

先上程序運行效果

這裡寫圖片描述

程序裡用到了RadioGroup作為底部欄 ,selector背景選擇器用於點擊時更換背景,FragmentTransaction切換四個Fragment.
FrameLayout作為載體,顯示四個Fragment
先把幾個重要的文件貼上,這個程序比較復雜,建議下載後學習
頁面下方有源碼">源碼下載


四個Fragment都是類似,這裡給出一個

public class Me_Fragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view =inflater.inflate(R.layout.fragment_me,null);
        return  view;
    }
}

Fragment布局,這裡給出奪寶這個




    

    
        
    


這裡寫圖片描述


activity_main.xml




    <framelayout android:id="@+id/main_fragment" android:layout_height="0dp" android:layout_weight="1" android:layout_width="match_parent"></framelayout>




底部欄bottom.xml




    

        

        

        

        

        
    

這裡寫圖片描述

選擇器selected_ic_home.xml
選擇器的相關知識看我另一篇博文點這裡



    
    

MainActivity

package com.peng.fragement_826;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.FrameLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;

import com.peng.fragement_826.fragment.Discover_Fragment;
import com.peng.fragement_826.fragment.Doubao_Fragment;
import com.peng.fragement_826.fragment.List_Fragment;
import com.peng.fragement_826.fragment.Me_Fragment;

public class MainActivity extends AppCompatActivity {
    private FrameLayout mainFragment;
    private RadioGroup mainRg;
    private RadioButton mainDb;
    private RadioButton mainFx;
    private RadioButton mainQd;
    private RadioButton mainMe;

    //四個fragment頁面
    private Doubao_Fragment duobaofragment;
    private Discover_Fragment discoverFragment;
    private List_Fragment listFragment;
    private Me_Fragment meFragment;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mainFragment = (FrameLayout) findViewById(R.id.main_fragment);

        inintView();


    }
     //頁面底部四個按鈕的點擊 顯示不同的fragment
    private void inintView() {
        //底部四個按鈕 奪寶 發現 清單 我的
        mainDb = (RadioButton) findViewById(R.id.main_db);
        mainFx = (RadioButton) findViewById(R.id.main_fx);
        mainQd = (RadioButton) findViewById(R.id.main_qd);
        mainMe = (RadioButton) findViewById(R.id.main_me);

        duobaofragment = new Doubao_Fragment();
        getFragmentManager().beginTransaction().replace(R.id.main_fragment, duobaofragment).commit();

        //RadioGroup的點擊事件 分別打開不同的fragment
        mainRg = (RadioGroup) findViewById(R.id.main_rg);
        mainRg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int checkedId) {
                //獲取fragment的管理者
                android.app.FragmentManager fragmentManager = getFragmentManager();
                //開啟事物
                android.app.FragmentTransaction beginTrasaction = fragmentManager.beginTransaction();

                switch (checkedId) {
                    case R.id.main_db:
                        if (duobaofragment == null) {
                            duobaofragment = new Doubao_Fragment();
                            beginTrasaction.add(R.id.main_fragment, duobaofragment);
                            Log.d("peng","--->>>add-one");
                        }
                        if (discoverFragment != null){
                            beginTrasaction.hide(discoverFragment);
                        Log.d("peng","--->>>hide-two");}
                        if (listFragment != null){
                            beginTrasaction.hide(listFragment);
                        Log.d("peng","--->>>hide-three");}
                        if (meFragment != null) {
                            beginTrasaction.hide(meFragment);
                            Log.d("peng","--->>>hide-four");
                        }
                        beginTrasaction.show(duobaofragment);
                        Log.d("peng","--->>>show-one");
                        beginTrasaction.commit();

                        break;
                    case R.id.main_fx:
                        if (discoverFragment == null) {
                            discoverFragment = new Discover_Fragment();
                            beginTrasaction.add(R.id.main_fragment, discoverFragment);
                            Log.d("peng","--->>>add-two");
                        }
                        if (duobaofragment != null){
                            beginTrasaction.hide(duobaofragment);
                        Log.d("peng","--->>>hide-one");}
                        if (listFragment != null){
                            beginTrasaction.hide(listFragment);
                        Log.d("peng","--->>>hide-three");
                        }
                        if (meFragment != null){
                            beginTrasaction.hide(meFragment);
                            Log.d("peng","--->>>hide-four");
                        }
                        beginTrasaction.show(discoverFragment);
                        Log.d("peng","--->>>show-two");
                        beginTrasaction.commit();

                        break;
                    case R.id.main_qd:
                        if (listFragment == null) {
                            listFragment = new List_Fragment();
                            beginTrasaction.add(R.id.main_fragment, listFragment);
                        }
                        if (duobaofragment != null)
                            beginTrasaction.hide(duobaofragment);
                        if (discoverFragment != null)
                            beginTrasaction.hide(discoverFragment);
                        if (meFragment != null)
                            beginTrasaction.hide(meFragment);
                        beginTrasaction.show(listFragment);
                        beginTrasaction.commit();
                        break;

                    case R.id.main_me:

                        if (meFragment == null) {
                            meFragment = new Me_Fragment();
                            beginTrasaction.add(R.id.main_fragment, meFragment);
                        }
                        if (duobaofragment != null)
                            beginTrasaction.hide(duobaofragment);
                        if (listFragment != null)
                            beginTrasaction.hide(listFragment);
                        if (discoverFragment != null)
                            beginTrasaction.hide(discoverFragment);
                        beginTrasaction.show(meFragment);
                        beginTrasaction.commit();
                        break;
                    default:
                        break;
                }
            }
        });
    }

}
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved