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

Android Layouts(Fragment)詳解

編輯:關於Android編程

目錄:
1.Fragment概述
2.Fragment的生命周期
3.Fragment靜態添加使用
4.Fragment的動態添加使用
5.Fragment之間的通信
6.Fragment與Activity的通信
6.1 簡單方法
6.2 接口實現
6.3 Intent實現
6.4 其他

1.Fragment概述
Fragment(碎片)是在android3.0(API 11)推出的一款非常類似於Activity的控件,他的設計初衷在於解決aplication在不同平台的靈活UI顯示,例如:手機與平板,手機顯示一個Activity可能看起來比較漂亮,可是如果換到大屏的平板上就不那麼美麗了,所以Fragment的出現,為大屏顯示更多的View提供了很好的支持,換句話說Fragment就是把Activity這個“大房間”隔開為自定義的“小房間”,而在不同的房間可以實現不同的功能,各個“小房間”獨立互不干擾,也可進行通信,同時生命周期與“大房間”是關聯的。除此之外,Fragment也具備可復用性和對UI進行分組管理作用。

2.Fragment的生命周期
2.1)下面用代碼和Log演示一下Fragment與Activity的生命周期的關系以及各個回調方法的執行順序操作順序:啟動->menu鍵返回->再次啟動->back退出
1)Log輸出如下:
08-21 04:47:16.169 1164-1164/com.example.fragment I/MainActivity: MainActivity->onCreate()
08-21 04:47:16.173 1164-1164/com.example.fragment D/fragment1: fragment1->onAttach()
08-21 04:47:16.173 1164-1164/com.example.fragment D/fragment1: fragment1->onCreate()
08-21 04:47:16.173 1164-1164/com.example.fragment D/fragment1: fragment1->onCreateView()
08-21 04:47:16.173 1164-1164/com.example.fragment I/MainActivity: MainActivity->onStart()
08-21 04:47:16.173 1164-1164/com.example.fragment D/fragment1: fragment1->onActivityCreated()
08-21 04:47:16.173 1164-1164/com.example.fragment D/fragment1: fragment1->onStart()
08-21 04:47:16.185 1164-1164/com.example.fragment I/MainActivity: MainActivity->onResume()
08-21 04:47:16.185 1164-1164/com.example.fragment D/fragment1: fragment1->onResume()
08-21 04:47:22.177 1164-1164/com.example.fragment I/MainActivity: MainActivity->onPause()
08-21 04:47:22.177 1164-1164/com.example.fragment D/fragment1: fragment1->onPause()
08-21 04:47:22.777 1164-1164/com.example.fragment I/MainActivity: MainActivity->onStop()
08-21 04:47:22.777 1164-1164/com.example.fragment D/fragment1: fragment1->onStop()
08-21 04:47:26.149 1164-1164/com.example.fragment I/MainActivity: MainActivity->onRestart()
08-21 04:47:26.149 1164-1164/com.example.fragment I/MainActivity: MainActivity->onStart()
08-21 04:47:26.149 1164-1164/com.example.fragment D/fragment1: fragment1->onStart()
08-21 04:47:26.149 1164-1164/com.example.fragment I/MainActivity: MainActivity->onResume()
08-21 04:47:26.149 1164-1164/com.example.fragment D/fragment1: fragment1->onResume()
08-21 04:47:28.401 1164-1164/com.example.fragment I/MainActivity: MainActivity->onPause()
08-21 04:47:28.401 1164-1164/com.example.fragment D/fragment1: fragment1->onPause()
08-21 04:47:28.877 1164-1164/com.example.fragment I/MainActivity: MainActivity->onStop()
08-21 04:47:28.877 1164-1164/com.example.fragment D/fragment1: fragment1->onStop()
08-21 04:47:28.877 1164-1164/com.example.fragment I/MainActivity: MainActivity->onDestroy()
08-21 04:47:28.877 1164-1164/com.example.fragment D/fragment1: fragment1->onDestroyView()
08-21 04:47:28.877 1164-1164/com.example.fragment D/fragment1: fragment1->onDestroy()
08-21 04:47:28.877 1164-1164/com.example.fragment D/fragment1: fragment1->onDetach()

2)activity_main.xml









3)fragment1.xml







4)MainActivity.java
    
package com.example.fragment;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {
    private final String Tag="MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(Tag, "MainActivity->onCreate()");
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onStart() {
        Log.i(Tag, "MainActivity->onStart()");
        super.onStart();
    }

    @Override
    protected void onRestart() {
        Log.i(Tag, "MainActivity->onRestart()");
        super.onRestart();
    }

    @Override
    protected void onResume() {
        Log.i(Tag, "MainActivity->onResume()");
        super.onResume();
    }

    @Override
    protected void onPause() {
        Log.i(Tag, "MainActivity->onPause()");
        super.onPause();
    }

    @Override
    protected void onStop() {
        Log.i(Tag, "MainActivity->onStop()");
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        Log.i(Tag, "MainActivity->onDestroy()");
        super.onDestroy();
    }
}

5)Fragment1.java
package com.example.fragment;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
 * Created by elimy on 2016-08-21.
 */
public class Fragment1 extends Fragment {

    private  final  String Tag ="fragment1";
    /*
    * 調用時間:繪制界面的時候回調,返回Fragment view
    * 參數:
    *   inflater布局加載器用於從xml加載fragment
    *   container:指示fragment存放的parent view
    *   savedInstanceState:有人解釋說是,如果是true,fragment xml布局會加入到parent view
    *       的ViewGroup中,則根元素就是container,如果為false,fragment xml會作為單獨的view
    *       返回,根元素為fragment xml的根元素,沒有深入了解就不裝逼了,大家自己去學習學習大神們的吧
    * */
    @Nullable
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d(Tag,"fragment1->onCreateView()");
        return inflater.inflate(R.layout.fragment,container,false);
    }

    /*
    * 調用時間:在Fragment綁定到Activity時調用,只調用一次
    * activity:及綁定的activity
    * */
    @Override
    public void onAttach(Activity activity) {
        Log.d(Tag,"fragment1->onAttach()");
        super.onAttach(activity);
    }

    /*
    * 調用時間:在Fragment創建時調用,只調用一次
    * */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(Tag, "fragment1->onCreate()");
    }
    /*
  * 調用時間:在Fragment所在的Activity創建完成後調用
  * */
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        Log.d(Tag,"fragment1->onActivityCreated()");
        super.onActivityCreated(savedInstanceState);
    }
    /*
    * 調用時間:Fragment啟動時回調
    * */
    @Override
    public void onStart() {
        Log.d(Tag,"fragment1->onStart()");
        super.onStart();
    }
    /*
    * 調用時間:Fragment獲取焦點是回調
    * */
    @Override
    public void onResume() {
        Log.d(Tag,"fragment1->onResume()");
        super.onResume();
    }
    /*
    *調用時間:Fragment暫停,並進入後台未獲取焦點時回調
    * */
    @Override
    public void onPause() {
        Log.d(Tag,"fragment1->onPause()");
        super.onPause();
    }
    /*
    * 調用時間:Fragment停止時回調
    * */
    @Override
    public void onStop() {
        Log.d(Tag,"fragment1->onStop()");
        super.onStop();
    }
    /*
    * 調用時間: 銷毀 Fragement 繪制的 View 組件時回調
    * */
    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d(Tag, "fragment1->onDestroyView()");
    }
    /*
    * 調用時間: 銷毀 Fragement 回調
    * */
    @Override
    public void onDestroy() {
        Log.d(Tag,"fragment1->onDestroy()");
        super.onDestroy();
    }
    /*
    * 調用時間:  Fragement與Activity解綁時回調
    * */
    @Override
    public void onDetach() {
        Log.d(Tag,"fragment1->onDetach()");
        super.onDetach();
    }
}


2.2)看一張Fragment的生命周期圖(來至官方文檔)
\
3.Fragment靜態添加使用
如2添加Fragment的方式即為靜態添加,一般步驟如下:
1)在主布局添加如下代碼,並且用 android:name=""屬性指定fragment的java類
    

2)建立fragment的java類,並通過inflater.inflate(R.layout.fragment,container,false);
加載fragment xml布局,並返回View.

3)建立對應的fragment xml文件實現對應的布局

4.Fragment的動態添加使用
4.1)定義fragment_girl1.xml






4.2)定義Fragment_girl1.java
package com.example.fragment;
//注意這裡是導入的android.app包下的Fragment
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 elimy on 2016-08-21.
 */
public class Fragment_girl1 extends Fragment {

    public Fragment_girl1() {
        super();
    }

    @Nullable
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_girl1,container,false);
    }

}   


4.3)定義fragment_girl2.xml





4.4)定義Fragment_girl2.java
package com.example.fragment;
//注意這裡導入的是android.support.v4.app包下的Fragment
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 elimy on 2016-08-21.
 */
public class Fragment_girl2 extends Fragment {

    public Fragment_girl2() {
        super();
    }

    @Nullable
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_girl2,container,false);
    }

}


4.5)定義主布局activity_three.xml


4.6)定義主布局java類ThreeActivity.java
package com.example.fragment;

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

/**
 * Created by elimy on 2016-08-21.
 */
public class ThreeActivity extends AppCompatActivity {
    private Button add,v4_add;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_three);
        add= (Button) findViewById(R.id.add);
        v4_add= (Button) findViewById(R.id.v4_add);
        add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //記得這裡面的Fragment也是非V4包下的哦
                Fragment_girl1 girl1 = new Fragment_girl1();
                //實例化非V4包下的FragmentManager
                android.app.FragmentManager fragmentManager = getFragmentManager();
                //實例化非V4包下的FragmentTransaction
                android.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
                //替換原來的布局
                transaction.replace(R.id.activity_three_layout,girl1);
                //提交事務
                transaction.commit();
            }
        });
        v4_add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //實例化V4包下的FragmentManager
                FragmentManager fragmentManager =getSupportFragmentManager();
                //實例化FragmentTransaction對象
                FragmentTransaction v4_transaction = fragmentManager.beginTransaction();
                //實例化自定義的碎片
                Fragment_girl2 girl2 = new Fragment_girl2();
                //替換掉activity的根布局
                v4_transaction.replace(R.id.activity_three_layout,girl2);
                //提交事務
                v4_transaction.commit();
            }
        });
    }

}

4.7)效果截圖
分別是替換前效果,點擊add button後效果和點擊v4_add button後效果

\\\

5.Fragment之間的通信
我用兩個妹紙來做一個兩個Fragment妹紙的對話

5.1)導入圖片
5.2)主布局activity_main.xml


    

    
    

    

5.3)主布局java類MainActivity.java
package com.example.fragmentdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

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


5.4)第一個妹紙Fragment的xml布局fragment_one.xml


    
        


5.5)第一個妹子Fragment的java類實現GirlOneFragment.java
package com.example.fragmentdemo;

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;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

/**
 * Created by elimy on 2016-08-22.
 */
public class GirlOneFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_one, container, false);
    }
    /*
* 調用時間:在Fragment所在的Activity創建完成後調用
* */
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        //通過Fragment的getActivity()方法獲取到宿主Activity在根據宿主Activity的findViewById()尋找相應的空間
        Button add = (Button) getActivity().findViewById(R.id.send_one);
        final EditText edit1= (EditText) getActivity().findViewById(R.id.edit);
        final TextView girl1_say= (TextView) getActivity().findViewById(R.id.girl1_say);
        //為girl1的發送按鈕添加監聽
        add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //獲取輸入框的文字
                String content = edit1.getText().toString().trim();
                //設置到girl2 fragment顯示
                girl1_say.setText(content);
            }
        });
        super.onActivityCreated(savedInstanceState);
    }
}   


5.6)第二個妹紙Fragment的xml布局fragment_two.xml


    
        


5.7)第二個妹子Fragment的java類實現GirlTwoFragment.java
package com.example.fragmentdemo;

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;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

/**
 * Created by elimy on 2016-08-22.
 */
public class GirlTwoFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_two, container, false);
    }
    /*
* 調用時間:在Fragment所在的Activity創建完成後調用
* */
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        //通過Fragment的getActivity()方法獲取到宿主Activity在根據宿主Activity的findViewById()尋找相應的空間
        Button add = (Button) getActivity().findViewById(R.id.send_two);
        final EditText edit2= (EditText) getActivity().findViewById(R.id.edit_two);
        final TextView girl2_say= (TextView) getActivity().findViewById(R.id.girl2_say);
        //為girl2的發送按鈕添加監聽
        add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //獲取輸入框的文字
                String content = edit2.getText().toString().trim();
                //設置到girl1 fragment顯示
                girl2_say.setText(content);
            }
        });
        super.onActivityCreated(savedInstanceState);
    }
}

5.8)效果截圖

 

\

 

6.Fragment與Activity的通信

6.1 簡單方法
(1)Fragment可通過getActivity()方法獲取宿主Activity從而實現調用Activity和FragmentActivity類的
一些public類型方法,例如:findViewById()

(2)Activity與Fragment可以通過如下代碼實例化Fragment並調用它的方法
            //通過findFragmentById()實例化GirlOneFragment,參數來著GirlOneFragment對應的主布局xml中的fragment id值
            GirlOneFragment girlOneFragment1= (GirlOneFragment) getSupportFragmentManager().findFragmentById(R.id.girlOneFg);
            //通過實例化調用GirlOneFragment的自定義GetString()方法
            girlOneFragment1.GetString();
            //通過findFragmentByTag()實例化GirlOneFragment
            GirlOneFragment girlOneFragment2 = getSupportFragmentManager().findFragmentByTag()
            //直接new
            GirlOneFragment girlOneFragment = new GirlOneFragment();
            //調用GirlOneFragment自定義方法GetString()
            girlOneFragment.GetString();


6.2 接口實現
(1)定義一個通訊的Fragement類InterfaceContactFragment.java
package com.example.fragmentdemo2;

import android.app.Activity;
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 elimy on 2016-08-23.
 */
public class InterfaceContactFragment extends Fragment {
    //定義接口成員變量
    public ShowMessage showMessageCallback;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_contact, container, false);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        //因為宿主Activity繼承了ShowMessage接口,所以可以強制類型轉換
        showMessageCallback = (ShowMessage) activity;
        showMessageCallback.showMessage(this,"Hello activity,I am InterfaceContactFragment!");
    }
    //定義通信接口
    public interface ShowMessage{
        public void showMessage(Fragment fragment, String info);
    }
}    

(2)宿主活動對信息的接收實現MainActivity.java
package com.example.fragmentdemo2;

import android.os.Bundle;
import android.os.PersistableBundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

/**
 * Created by elimy on 2016-08-23.
 */
public class MainActivity extends AppCompatActivity implements InterfaceContactFragment.ShowMessage{
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
/*        //實例化自定義Fragment
        InterfaceContactFragment interfaceContactFragment= new InterfaceContactFragment();
        //實例化FragmentManager
        FragmentManager fragmentManager=getSupportFragmentManager();
        //實例化FragmentTransaction
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        //通過事務replace()方法替換掉原來的布局
        transaction.replace(R.id.fragment_linear,interfaceContactFragment);
        //提交事務
        transaction.commit();*/

    }

    /* 繼承InterfaceContactFragment的內部ShowMessage接口並實現showMessage方法
      *這裡參數由fragment Attach到activity時由實例化的接口成員變量調用回調方法傳遞過來
      */
    @Override
    public void showMessage(Fragment fragment, String info) {
        Log.d("showMessage",info+fragment.getId());
    }
}  


6.3 Intent廣播實現

(1)InterfaceContactFragment.java中注冊Intent並發送廣播

 

package com.example.fragmentdemo;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * Created by elimy on 2016-08-23.
 */
public class InterfaceContactFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_contact, container, false);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        /*
        *   Intent intent1 = new Intent();
        *    intent.setAction("android.intent.action.BROADCAST")
        * */

        //通過帶參構造方法實例化Intent,與上面效果相同
        Intent intent = new Intent("android.intent.action.BROADCAST");
        //為意向添加數據(鍵值對形式)
        intent.putExtra("msg","Hello, I am InterfaceContactFragment");
        //實例化LocalBroadcastManager類
        LocalBroadcastManager broadcastManager =LocalBroadcastManager.getInstance(getActivity());
        //發送隱式broadcast
        broadcastManager.sendBroadcast(intent);
        Log.d("onActivityCreated","onActivityCreated()");

    }
}

 

(2)SecondActivity.java宿主或其他Activity注冊廣播接收者接收廣播
package com.example.fragmentdemo;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

/**
 * Created by elimy on 2016-08-23.
 */
public class SecondActivity extends AppCompatActivity{
    BroadcastReceiver broadcastReceiver;
    LocalBroadcastManager broadcastManager;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        //實例化broadcastManager
         broadcastManager =LocalBroadcastManager.getInstance(this);
        //實例化過濾器onReceive
        IntentFilter filter = new IntentFilter("android.intent.action.BROADCAST");
        //實例化BroadcastReceiver並實現繼承方法接收數據
         broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                //根據鍵值獲取消息
                Log.d("","onReceive()");
                String s =intent.getStringExtra("msg");
                Log.d("GetMessage",s);
            }
        };
        //動態注冊廣播接收者
        broadcastManager.registerReceiver(broadcastReceiver,filter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("onDestroy","onDestroy()");
        broadcastManager.unregisterReceiver(broadcastReceiver);
    }

}

注意:我們在onCreate()中registerReceiver的broadcastReceiver需要在onDestroy()中unregisterReceiver在onStart()中registerReceiver的broadcastReceiver需要在onStop()中unregisterReceiver不然會拋出異常,至於原因伙伴們可以想想Activity的生命周期,就明白了。

6.4 其他還包括通過EventBus和handler去實現fragment和Activity與fragment之間的通信,感興趣的伙伴可以搜索學習,這裡就不一一列舉了。

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