現(xiàn)在對于android app而言,fragment的使用已經非常廣泛。大概分為兩種情況:第一種是直接使用Activity裝載fragment,第二種是ViewPager+Fragment,所以fragment的切換就變成了很頻繁的操作。fragment的切換又分兩種情況:
- 每次創(chuàng)建新的實例進行替換
- 先創(chuàng)建好,每次通過 show()或者hide() 方法控制顯示隱藏
不管上述哪種情況,我們在大多數(shù)情況下,都需要知道具體哪個fragment顯示在用戶面前或者第一次顯示在用戶面前這樣一個時機,好讓用戶看到我們想展示給他的數(shù)據。下面給出兩種對應的解決方案,僅供參考:
一,通過Activity直接裝載多個Fragment(多用于最外層導航tab頁)
主要方式:通過重寫onHiddenChanged(boolean hidden)方法
這個方法是V4包中Fragment的方法,當Fragment對用戶可見性改變的時候,這個方法會被調用。參數(shù) hidden 的值 為false 表示 可見, true表示不可見。要注意的是,但Fragment第一次被add到Activity的時候,這個方法不會被調用。所以要處理一下fragment 第一次對用戶可見的情況。
先寫一個BaseFragment ,讓所有的fragment繼承自它。
public class BaseFragment extends Fragment {
protected boolean isFirstVisible = false;
public BaseFragment() {
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
isFirstVisible = true;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
isFirstVisible = false;
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onDestroyView() {
super.onDestroyView();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onDetach() {
super.onDetach();
}
}
主要是在BaseFragment里面定義了一個boolean類型的變量。用來表示是否是第一次可見。讓所有fragment也能繼承這個屬性。接下來去看具體的Fragment代碼:
public class FindFragment extends BaseFragment {
private static final String TAG = "FindFragment";
@Override
public void onResume() {
super.onResume();
Log.d("xls", "FindFragment onResume");
if(isFirstVisible){
LogUtil.d("xiong","FindFragment 第一次可見");
}
}
@Override
public void onHiddenChanged(boolean hidden) {
Log.d("xls", "FindFragment onHiddenChanged : " + hidden);
if (hidden) {
//隱藏
isFirstVisible = false;
} else {
//顯示
LogUtil.d("xiong","FindFragment 顯示");
}
}
}
第一次可見在 onResume中,if語句里,后面就都是在onHiddenChanged方法里。
二,ViewPager+Fragment配合使用
主要方式:通過重寫setUserVisibleHint方法。
同樣的先寫一個BaseFragment:
public class BaseFragment extends Fragment {
protected boolean isVisible;
public BaseFragment() {
// Required empty public constructor
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser){
isVisible = true;
onVisible();
}else{
isVisible = false;
onInVisible();
}
}
public void onVisible(){
}
public void onInVisible(){
}
}
BaseFrament里面增加了兩個方法onVisible 和 onInVisible用于給子Fragment回調。當然這個位置可以根據自己的習慣去定義回調方式。
具體的子Fragment如下:
public class ProducingFragment extends BaseFragment {
public ProducingFragment() {
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onVisible() {
super.onVisible();
Log.d("xls", "producingFragment is Visible");
if (!isResumed()) {
return;
}
//do your work here
}
@Override
public void onInVisible() {
super.onInVisible();
Log.d("xls", "producingFragment is InVisible");
}
}
需要注意的是,setUserVisibleHint這個方法是被系統(tǒng)調用的,一般最早的一次是在fragment的onResume方法被調用之前,如果這個時候你的控件都沒有初始化完成,就會出問題。所以在 onVisible方法里 加了一個判斷,看這個Fragment是否已經Resume了,再去處理業(yè)務邏輯。
如果要做第一次顯示判斷,則跟第一種方式邏輯類似。
以上為個人的總結,歡迎各位同道點評。。。。