第一行代码学习笔记第四章——探究碎片
知識點目錄
- 4.1 碎片是什么
- 4.2 碎片的使用方式
* 4.2.1 碎片的簡單用法
* 4.2.2 動態添加碎片
* 4.2.3 在碎片中模擬返回棧
* 4.2.4 碎片和活動之間進行通信
- 4.3 碎片的生命周期
* 4.3.1 碎片的狀態和回調
* 4.3.2 體驗碎片的生命周期
- 4.4 動態加載布局的技巧
* 4.4.1 使用限定符
* 4.4.2 使用最小寬度限定符
- 4.5 碎片的最佳實踐——一個簡易版的新聞應用
知識點回顧
一般手機的屏幕大小在3-6英寸之間;一般平板電腦的屏幕在7-10英寸之間。隨著屏幕大小的不同,同樣的界面在視覺效果上有較大的差異。為了同時兼顧手機和平板視覺效果,從Android3.0開始引入了碎片的概念,它可以讓界面在平板上更好地展示。
4.1 碎片是什么
碎片(Fragment)是一種可以嵌入在活動當中的UI片段。可以將其理解為一種迷你型的活動。有時候我們為了充分利用屏幕的大小,可以將多個Fragment嵌入到一個活動當中。
4.2 碎片的使用方式
4.2.1 碎片的簡單用法
1. 新建碎片布局文件
新建左側碎片布局left_fragment.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="Button"android:textAllCaps="false"/></LinearLayout>新建右側碎片布局right_fragment.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:background="#00ff00"android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:textSize="20sp"android:text="This is right fragment"/></LinearLayout>2. 創建Fragment類
新建的LeftFragment類需要繼承Fragment,Fragment有系統內置的android.app.Fragment和support-v4庫中的android.support.v4.app.Fragment兩種,考慮更好的兼容性,建議使用android.support.v4.app.Fragment,而build.gradle文件中的appcompat-v7會將support-v4一起引入進來,所以直接引用即可。
創建LeftFragment類:
public class LeftFragment extends Fragment {@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {View view = inflater.inflate(R.layout.left_fragment, container, false);return view;} }創建RightFragment類:
public class RightFragment extends Fragment {@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {View view = inflater.inflate(R.layout.right_fragment, container, false);return view;}重寫Fragment的onCreateView方法,通過inflater()方法將上面定義的布局加載進來。
3. 使用創建的Fragment類
修改activity_main.xml文件:
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><fragmentandroid:id="@+id/left_fragment"android:name="com.example.fragmenttest.LeftFragment"android:layout_width="0dp"android:layout_weight="1"android:layout_height="match_parent"/><fragmentandroid:id="@+id/right_fragment"android:name="com.example.fragmenttest.RightFragment"android:layout_width="0dp"android:layout_weight="1"android:layout_height="match_parent"/></LinearLayout>使用標簽在布局中添加碎片,通過android:name屬于來顯式指明要添加的碎片類名。
4. Fragment的簡單運行效果
4.2.2 動態添加碎片
碎片不僅可以在xml中靜態加載,還可以在程序運行時動態地添加到活動中。
新建another_right_fragment.xml文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#ffff00"android:orientation="vertical"><TextViewandroid:id="@+id/textview"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:textSize="20sp"android:text="This is another right fragment"/></LinearLayout>創建AnotherRightFragment類:
public class AnotherRightFragment extends Fragment {@Nullable@Overridepublic View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {View view = inflater.inflate(R.layout.another_right_fragment, container, false);return view;} }修改activity_main.xml文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"><fragmentandroid:id="@+id/left_fragment"android:name="com.example.fragmenttest.LeftFragment"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"/><FrameLayoutandroid:id="@+id/right_layout"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"/></LinearLayout>在代碼中向FrameLayout里添加內容,從而實現動態添加碎片的功能。
修改MainActivity中的代碼:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button button = (Button) findViewById(R.id.button);button.setOnClickListener(this);replaceFragment(new RightFragment());}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.button:replaceFragment(new AnotherRightFragment());break;default:break;}}private void replaceFragment(Fragment fragment) {FragmentManager fragmentManager = getSupportFragmentManager();FragmentTransaction transaction = fragmentManager.beginTransaction();transaction.replace(R.id.right_layout, fragment);transaction.commit();} }上面代碼是當點擊左側的按鈕時,通過replaceFragment()方法將右邊的碎片替換成AnotherRightFragment。
總結動態添加碎片的步驟:
-
創建待添加的碎片實例
-
調用getSupportFragmentManager()方法來獲取FragmentManager
-
通過調用beginTransaction()方法來開啟一個事務
-
向容器內添加或替換碎片,一般使用replace()方法實現,需要傳入容器的id和待添加的碎片實例
-
提交事務,調用commit()方法來完成
效果圖:
運行程序,效果圖如下:
4.2.3 在碎片中模擬返回棧
上面通過點擊按鈕添加一個碎片后,如果此時按下Back鍵程序就會直接退出。如果想要模范返回棧的效果,返回到上一個碎片,則需要在提交事務之前調用addToBackStack()方法。
private void replaceFragment(Fragment fragment) {FragmentManager fragmentManager = getSupportFragmentManager();FragmentTransaction transaction = fragmentManager.beginTransaction();transaction.replace(R.id.right_layout, fragment);transaction.addToBackStack(null);transaction.commit(); }效果圖:
重新運行程序,效果圖如下:
4.2.4 碎片和活動之間進行通信
1. Activity調用Fragment方法
LeftFragment leftFragment = (LeftFragment) getSupportFragmentManager().findFragmentById(R.id.left_fragment);2. Fragment調用Activity方法
MainActivity mainActivity = (MainActivity) getActivity();獲取到相應的實例對象后,然后就可以直接調用相應的公用方法。
4.3 碎片的生命周期
碎片也有生命周期,并且它和Activity的生命周期很相似。
4.3.1 碎片的狀態和回調
1. 運行狀態
碎片可見,并且與它所關聯的活動正處于運行狀態時,該碎片也在運行狀態。
2. 暫停狀態
當一個活動進入暫停狀態時(由于另一個未占滿屏幕的活動被添加到了棧頂),與它相關聯的可見碎片就會進入到暫停狀態。
3. 停止狀態
-
Activity進入停止狀態時,與它所關聯的碎片就會進入停止狀態。
-
調用了FragmentTransaction的remove()、replace()方法,但在提交事務之前調用了addToBackStack()方法,此時碎片也會進入到停止狀態。
4. 銷毀狀態
-
Activity進入銷毀狀態時,與它所關聯的碎片就會進入銷毀狀態。
-
調用了FragmentTransaction的remove()、replace()方法,但在提交事務之間沒有調用了addToBackStack()方法,此時碎片也會進入到銷毀狀態。
Android官方給出了Fragment完整的生命周期示意圖:
-
onAttach():碎片實例被關聯到活動實例
-
onCreate():創建碎片時,系統調用該方法
-
onCreateView():當碎片將要第一次繪制它的用戶界面時系統調用該方法
-
onActivityCreated:當宿主活動被創建,在onCreateView()方法之后調用該方法
-
onStart(): 碎片可見時調用該方法
-
onResume(): 碎片可交互時調用該方法
-
onPause(): 當首次表明用戶將要離開碎片時系統調用該方法
-
onStop(): 碎片將要被停止時調用
-
onDestroyView(): 調用該方法后,碎片將要被銷毀
-
onDestroy(): 該方法被用來清理碎片的狀態
4.3.2 體驗碎片的生命周期
省略…需要自己寫Demo去體驗!!!
4.4 動態加載布局的技巧
Android可以根據設備的分辨率或者屏幕大小來動態加載布局。
4.4.1 使用限定符
平板與手機最大的區別就是平板采用的雙頁模式,手機采用的是單頁模式。
在實際開發中,我們可以通過限定符讓程序的運行時動態的判斷是使用雙頁模式還是單頁模式。
修改activity_main文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"><fragmentandroid:id="@+id/left_fragment"android:name="com.example.fragmenttest.LeftFragment"android:layout_width="match_parent"android:layout_height="match_parent"/></LinearLayout>在res目錄下新建layout-large文件夾,并新建一個布局,也叫activity_main.xml,代碼如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"><fragmentandroid:id="@+id/left_fragment"android:name="com.example.fragmenttest.LeftFragment"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"/><fragmentandroid:id="@+id/right_fragment"android:name="com.example.fragmenttest.RightFragment"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="3"/></LinearLayout>layout/activity_main布局只包含了一個碎片,即單頁模式,而layout-large/activity_main布局包含了兩個碎片,即雙頁模式。
large就是一個限定符,那些屏幕被認為是large的設備就會自動加載layout-large文件夾下的布局,而屏幕小的設備則會加載layout文件夾下的布局。
效果圖:
單頁模式運行:
雙頁模式運行:
Android中有一些常見的限定符,參考下表:
4.4.2 使用最小寬度限定符
上面使用了large限定符,large屬于一個模糊的概念,如果我們想具體一點,到底多大是叫large,此時我們就可以使用最小寬度限定符(Smallest-width Qualifier)。
最小寬度限定符允許我們對屏幕的寬度指定一個最小值(以dp為單位),然后以這個值為臨界點,屏幕寬度大于這個值的設備就加載一個布局,屏幕寬度小于這個值的設備就加載另一個布局。
在res目錄下新建一個layout-sw600dp文件夾,然后新建activity_main.xml文件。
當程序運行在屏幕寬度大于600dp的設備上時,就會加載layout-sw600dp/activity_main布局;當程序運行在屏幕寬度小于600dp的設備上時,則加載默認的layout/activity_main布局。
4.5 碎片的最佳實踐——一個簡易版的新聞應用
代碼已上傳到我的github上,需要的朋友可以點擊如下鏈接查看:
碎片的最佳實踐——一個簡易版的新聞應用
運行效果圖:
單頁模式:
雙頁模式:
非常感謝您的耐心閱讀,希望我的文章對您有幫助。歡迎點評、轉發或分享給您的朋友或技術群。
總結
以上是生活随笔為你收集整理的第一行代码学习笔记第四章——探究碎片的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络请求工具
- 下一篇: 第一行代码学习笔记第五章——详解广播机制