Fragment (一)

 

1,简介

Fragement(碎片)允许将Activity拆分成多个完全独立封装的可重用组件,每个组件有它自己的生命周期和UI布局,由此可见,Fragement依赖于Activity,它的生命周期直接被其所属的宿主activity的生命周期影响。

形象的理解Fragement,手机屏幕如下图所示:

Fragment (一)

Fragement 具有以下优点:

  • 组件重用,多个Activity可重用同一个Fragement;
  • 为不同屏幕大小的设备创建动态的灵活的UI,在Activity运行过程中,可以添加、移除或者替换Fragment(add()、remove()、replace())

 

2,生命周期

Fragement的生命周期镜像它的宿主Activity的生命周期事件。若Activity进入active-resumed状态的时候,添加或者移除一个Fragement就会影响它自己的生命周期。

Fragement生命周期方面如下:

/**
* Listing 4-4: Fragment skeleton code
* Listing 4-5: Fragment lifecycle event handlers
*/
package com.paad.fragments; import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; public class MySkeletonFragment extends Fragment { // Called when the Fragment is attached to its parent Activity.
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Get a reference to the parent Activity.
} // Called to do the initial creation of the Fragment.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initialize the Fragment.
} // Called once the Fragment has been created in order for it to
// create its user interface.
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
// Create, or inflate the Fragment's UI, and return it.
// If this Fragment has no UI then return null.
return inflater.inflate(R.layout.my_fragment, container, false);
} // Called once the parent Activity and the Fragment's UI have
// been created.
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Complete the Fragment initialization �particularly anything
// that requires the parent Activity to be initialized or the
// Fragment's view to be fully inflated.
} // Called at the start of the visible lifetime.
@Override
public void onStart(){
super.onStart();
// Apply any required UI change now that the Fragment is visible.
} // Called at the start of the active lifetime.
@Override
public void onResume(){
super.onResume();
// Resume any paused UI updates, threads, or processes required
// by the Fragment but suspended when it became inactive.
} // Called at the end of the active lifetime.
@Override
public void onPause(){
// Suspend UI updates, threads, or CPU intensive processes
// that don't need to be updated when the Activity isn't
// the active foreground activity.
// Persist all edits or state changes
// as after this call the process is likely to be killed.
super.onPause();
} // Called to save UI state changes at the
// end of the active lifecycle.
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save UI state changes to the savedInstanceState.
// This bundle will be passed to onCreate, onCreateView, and
// onCreateView if the parent Activity is killed and restarted.
super.onSaveInstanceState(savedInstanceState);
} // Called at the end of the visible lifetime.
@Override
public void onStop(){
// Suspend remaining UI updates, threads, or processing
// that aren't required when the Fragment isn't visible.
super.onStop();
} // Called when the Fragment's View has been detached.
@Override
public void onDestroyView() {
// Clean up resources related to the View.
super.onDestroyView();
} // Called at the end of the full lifetime.
@Override
public void onDestroy(){
// Clean up any resources including ending threads,
// closing database connections etc.
super.onDestroy();
} // Called when the Fragment has been detached from its parent Activity.
@Override
public void onDetach() {
super.onDetach();
}
}

生命周期要点:

  • 开始于绑定到它的你Activity,结束于从父Activity分离,对应于onAttach 和onDetach事件,通常情况下,onAttach用来获取一下Fragement的父Activity的引用,为进一步初始化做准备;
  • 不能依赖调用onDestroy方法来销毁它,因为此方面不定会被执行;
  • 与Activity一样,应该使用onCreate方法来初始化Fragement,在其生命周期内创建的作用域对象,且确保只创建一次;
  • 在onCreateView和onDestroyView上初始化和销毁UI;
  • 当Fragement暂停或停止时,保存所有的UI状态和持久化所有的数据。

3,使用Fragement

最佳实践是使用容器View来创建布局,将Fragement在运行时放入容器内

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"> <FrameLayout
android:id="@+id/ui_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
</FrameLayout> <FrameLayout
android:id="@+id/details_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="3"
    android:visibility =”gone”    --隐藏
/>
</LinearLayout>
 

在运行时使用Fragement transaction来动态填充布局,从而当配置改变时,能确保一致性,框架代码如下:

package com.paad.fragments;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle; public class MyFragmentActivity extends Activity { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Inflate the layout containing the Fragment containers
setContentView(R.layout.fragment_container_layout); FragmentManager fm = getFragmentManager(); // Check to see if the Fragment back stack has been populated
// If not, create and populate the layout.
DetailsFragment detailsFragment =
(DetailsFragment)fm.findFragmentById(R.id.details_container); if (detailsFragment == null) {
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.details_container, new DetailsFragment());
ft.add(R.id.ui_container, new MyListFragment());
ft.commit();
}
}
}
package com.paad.weatherstation;

import com.paad.fragments.R;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; public class DetailsFragment extends Fragment { public DetailsFragment() {
} // Called once the Fragment has been created in order for it to
// create its user interface.
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
// Create, or inflate the Fragment's UI, and return it.
// If this Fragment has no UI then return null.
return inflater.inflate(R.layout.details_fragment, container, false);
}
}
package com.paad.weatherstation;

import com.paad.fragments.R;

import android.annotation.SuppressLint;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; public class MyListFragment extends Fragment { public MyListFragment() {
} // Called once the Fragment has been created in order for it to
// create its user interface.
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
// Create, or inflate the Fragment's UI, and return it.
// If this Fragment has no UI then return null.
return inflater.inflate(R.layout.list_fragment, container, false);
}
}

Fragement 和Activity之间的接口:

  • 任何Fragement中可使用getActivity方法返回对父Activity的引用;
  • 在fragement需要和它的主Activity共享事件的地方,最好在Fragement中创建回调接口,而主Activity必须实现它来监听Fragement中的改变;
package com.paad.fragments;

import android.app.Activity;
import android.app.Fragment; /**
* MOVED TO PA4AD_Ch04_Seasons
*/
public class SeasonFragment extends Fragment { public interface OnSeasonSelectedListener {
public void onSeasonSelected(Season season);
} private OnSeasonSelectedListener onSeasonSelectedListener;
private Season currentSeason; @Override
public void onAttach(Activity activity) {
super.onAttach(activity); try {
onSeasonSelectedListener = (OnSeasonSelectedListener)activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() +
" must implement OnSeasonSelectedListener");
}
} private void setSeason(Season season) {
currentSeason = season;
onSeasonSelectedListener.onSeasonSelected(season);
} }

若理解有难道,可以了解一下JAVA编程思想中的上塑造型,内部类,接口方面的知识

上一篇:微服务(入门三):netcore ocelot api网关结合consul服务发现


下一篇:mysql各种操作记录