Fragment 描述:
??翻譯可以譯為:碎片、片段,Android 3.0開始引入fragments 的概念;
1. 作用
??目的:解決屏幕適配的問題,增加UI設計的靈活性;
??Fragment必須被寫成可重用的模塊。因為fragment有自己的layout,自己進行事件響應,擁有自己的生命周期和行為,所以你可以在多個activity中包含同一個Fragment的不同實例。
注意:
Fragment不能獨立存在,它必須嵌入到activity中,而且Fragment的生命周期直接受所在的activity的影響。
Fragment優點
- Fragment可以使你能夠將activity分離成多個可重用的組件,每個都有它自己的生命周期和UI。
- Fragment可以輕松得創建動態靈活的UI設計,可以適應于不同的屏幕尺寸。從手機到平板電腦。
- Fragment是一個獨立的模塊,緊緊地與activity綁定在一起。可以運行中動態地移除、加入、交換等。
- Fragment提供一個新的方式讓你在不同的安卓設備上統一你的UI。
- Fragment 解決Activity間的切換不流暢,輕量切換。
- Fragment 替代TabActivity做導航,性能更好。
- Fragment 在4.2.版本中新增嵌套fragment使用方法,能夠生成更好的界面效果。
- Fragment做局部內容更新更方便,原來為了到達這一點要把多個布局放到一個activity里面,現在可以用多Fragment來代替,只有在需要的時候才加載Fragment,提高性能。
- 可以從startActivityForResult中接收到返回結果,但是View不能。
Fragment
顯示Fragment時(跟用戶交互)要調用的核心的生命周期方法如下:
- 把Fragment對象跟Activity關聯時,調用onAttach(Activity)方法;
- Fragment對象的初始創建時,調用onCreate(Bundle)方法;
- onCreateView(LayoutInflater, ViewGroup, Bundle)方法用于創建和返回跟Fragment關聯的View對象;
- onActivityCreate(Bundle)方法會告訴Fragment對象,它所依附的Activity對象已經完成了Activity.onCreate()方法的執行;
- onStart()方法會讓Fragment對象顯示給用戶(在包含該Fragment對象的Activity被啟動后);
- onResume()會讓Fragment對象跟用戶交互(在包含該Fragment對象的Activity被啟恢復后)。
場景演示 : 切換到該Fragment
11-29 14:26:35.095: D/AppListFragment(7649): onAttach
11-29 14:26:35.095: D/AppListFragment(7649): onCreate
11-29 14:26:35.095: D/AppListFragment(7649): onCreateView
11-29 14:26:35.100: D/AppListFragment(7649): onActivityCreated
11-29 14:26:35.120: D/AppListFragment(7649): onStart
11-29 14:26:35.120: D/AppListFragment(7649): onResume
屏幕滅掉:
11-29 14:27:35.185: D/AppListFragment(7649): onPause
11-29 14:27:35.205: D/AppListFragment(7649): onSaveInstanceState
11-29 14:27:35.205: D/AppListFragment(7649): onStop
屏幕解鎖
11-29 14:33:13.240: D/AppListFragment(7649): onStart
11-29 14:33:13.275: D/AppListFragment(7649): onResume
切換到其他Fragment:
11-29 14:33:33.655: D/AppListFragment(7649): onPause
11-29 14:33:33.655: D/AppListFragment(7649): onStop
11-29 14:33:33.660: D/AppListFragment(7649): onDestroyView
切換回本身的Fragment:
11-29 14:33:55.820: D/AppListFragment(7649): onCreateView
11-29 14:33:55.825: D/AppListFragment(7649): onActivityCreated
11-29 14:33:55.825: D/AppListFragment(7649): onStart
11-29 14:33:55.825: D/AppListFragment(7649): onResume
回到桌面
11-29 14:34:26.590: D/AppListFragment(7649): onPause
11-29 14:34:26.880: D/AppListFragment(7649): onSaveInstanceState
11-29 14:34:26.880: D/AppListFragment(7649): onStop
回到應用
11-29 14:36:51.940: D/AppListFragment(7649): onStart
11-29 14:36:51.940: D/AppListFragment(7649): onResume
退出應用
11-29 14:37:03.020: D/AppListFragment(7649): onPause
11-29 14:37:03.155: D/AppListFragment(7649): onStop
11-29 14:37:03.155: D/AppListFragment(7649): onDestroyView
11-29 14:37:03.165: D/AppListFragment(7649): onDestroy
11-29 14:37:03.165: D/AppListFragment(7649): onDetach
這張圖是Fragment生命周期和Activity生命周期對比圖,可以看到兩者還是有很多相似的地方,比如都有onCreate(),onStart(),onPause(),onDestroy()等等,因為Fragment是被托管到Activity中的,所以多了兩個onAttach()和onDetach()。這里講講與Activity生命周期不一樣的方法。
- onAttach()
Fragment和Activity建立關聯的時候調用,被附加到Activity中去。
- onCreate()
系統會在創建Fragment時調用此方法。可以初始化一段資源文件等等。
- onCreateView()
系統會在Fragment首次繪制其用戶界面時調用此方法。 要想為Fragment繪制 UI,從該方法中返回的 View 必須是Fragment布局的根視圖。如果Fragment未提供 UI,您可以返回 null。
- onViewCreated()
在Fragment被繪制后,調用此方法,可以初始化控件資源。
- onActivityCreated()
當onCreate(),onCreateView(),onViewCreated()方法執行完后調用,也就是Activity被渲染繪制出來后。
- onPause()
系統將此方法作為用戶離開Fragment的第一個信號(但并不總是意味著此Fragment會被銷毀)進行調用。 通常可以在此方法內確認在當前用戶會話結束后仍然有效的任何更改(因為用戶可能不會返回)。
- onDestroyView()
Fragment中的布局被移除時調用。
- onDetach()
Fragment和Activity解除關聯的時候調用。
但需要注一點是:除了onCreateView,其他的所有方法如果你重寫了,必須調用父類對于該方法的實現。
Fragment怎么用
兩種方式:靜態用法和動態用法。
靜態用法
1、繼承Fragment,重寫onCreateView決定Fragemnt的布局
2、在Activity中聲明此Fragment,就當和普通的View一樣
首先是布局文件:fragment1.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00ff00" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is fragment 1"
android:textColor="#000000"
android:textSize="25sp" />
</LinearLayout>
可以看到,這個布局文件非常簡單,只有一個LinearLayout,里面加入了一個TextView。我們再新建一個fragment2.xml :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffff00" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is fragment 2"
android:textColor="#000000"
android:textSize="25sp" />
</LinearLayout>
然后新建一個類Fragment1,這個類是繼承自Fragment的:
public class Fragment1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment1, container, false);
}
}
可以看到,在onCreateView()方法中加載了fragment1.xml的布局。同樣fragment2.xml也是一樣的做法,新建一個Fragment2類:
public class Fragment2 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment2, container, false);
}
}
然后打開或新建activity_main.xml作為主Activity的布局文件,在里面加入兩個Fragment的引用,使用android:name前綴來引用具體的Fragment:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false" >
<fragment
android:id="@+id/fragment1"
android:name="com.example.fragmentdemo.Fragment1"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1" />
<fragment
android:id="@+id/fragment2"
android:name="com.example.fragmentdemo.Fragment2"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
最后新建MainActivity作為程序的主Activity,里面的代碼非常簡單,都是自動生成的:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
現在我們來運行一次程序,就會看到,一個Activity很融洽地包含了兩個Fragment,這兩個Fragment平分了整個屏幕
動態用法
上面僅僅是Fragment簡單用法,它真正強大部分是在動態地添加到Activity中,那么動態用法又是如何呢?
還是在靜態用法代碼的基礎上修改,打開activity_main.xml,將其中對Fragment的引用都刪除,只保留最外層的LinearLayout,并給它添加一個id,因為我們要動態添加Fragment,不用在XML里添加了,刪除后代碼如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false" >
</LinearLayout>
然后打開MainActivity,修改其中的代碼如下所示:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Display display = getWindowManager().getDefaultDisplay();
if (display.getWidth() > display.getHeight()) {
Fragment1 fragment1 = new Fragment1();
getFragmentManager().beginTransaction().replace(R.id.main_layout, fragment1).commit();
} else {
Fragment2 fragment2 = new Fragment2();
getFragmentManager().beginTransaction().replace(R.id.main_layout, fragment2).commit();
}
}
}
看到了沒,首先,我們要獲取屏幕的寬度和高度,然后進行判斷,如果屏幕寬度大于高度就添加fragment1,如果高度大于寬度就添加fragment2。動態添加Fragment主要分為4步:
1.獲取到FragmentManager,在Activity中可以直接通過getFragmentManager得到。
2.開啟一個事務,通過調用beginTransaction方法開啟。
3.向容器內加入Fragment,一般使用replace方法實現,需要傳入容器的id和Fragment的實例。
4.提交事務,調用commit方法提交。
要想管理 Activity 中的片段,需要使用 FragmentManager。要想獲取它,需要 Activity 調用 getFragmentManager()。
使用 FragmentManager 執行的操作包括:
- 通過 findFragmentById()(對于在 Activity 布局中提供 UI 的片段)或 findFragmentByTag()(對于提供或不提供 UI 的片段)獲取 Activity 中存在的片段
- 通過 popBackStack()將片段從返回棧中彈出
- 通過 addOnBackStackChangedListener() 注冊一個偵聽返回棧變化的偵聽器
- 也可以使用 FragmentManager 打開一個 FragmentTransaction,通過它來執行某些事務,如添加和刪除片段。
Fragment通信
盡管 Fragment 是作為獨立于 Activity的對象實現,并且可在多個 Activity 內使用,但Fragment 的給定實例會直接綁定到包含它的 Activity。具體地說,Fragment 可以通過 getActivity() 訪問 Activity實例,并輕松地執行在 Activity 布局中查找視圖等任務。如:
View listView = getActivity().findViewById(R.id.list);
同樣地,Activity 也可以使用 findFragmentById() 或 findFragmentByTag(),通過從 FragmentManager 獲取對 Fragment 的引用來調用Fragment中的方法。例如:
ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);
創建對 Activity 的事件回調
在某些情況下,可能需要通過與 Activity 共享事件。執行此操作的一個好方法是,在Fragment 內定義一個回調接口,并要求宿主 Activity 實現它。 當 Activity 通過該接口收到回調時,可以根據需要與布局中的其他Fragment共享這些信息。
例如,如果一個新聞應用的 Activity 有兩個Fragment ,一個用于顯示文章列表(Fragment A),另一個用于顯示文章(Fragment B)—,那么Fragment A必須在列表項被選定后告知 Activity,以便它告知Fragment B 顯示該文章。 在本例中,OnArticleSelectedListener 接口在片段 A 內聲明:
public static class FragmentA extends ListFragment {
public interface OnArticleSelectedListener {
public void onArticleSelected(Uri articleUri);
}
}
然后,該Fragment的宿主 Activity 會實現 OnArticleSelectedListener 接口并替代 onArticleSelected(),將來自Fragment A 的事件通知Fragment B。為確保宿主 Activity 實現此界面,Fragment A 的 onAttach() 回調方法(系統在向 Activity 添加Fragment時調用的方法)會通過轉換傳遞到 onAttach() 中的 Activity 來實例化 OnArticleSelectedListener 的實例:
public static class FragmentA extends ListFragment {
OnArticleSelectedListener mListener;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnArticleSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
}
}
}
```
如果 Activity 未實現界面,則片段會引發 ClassCastException。實現時,mListener 成員會保留對 Activity 的 OnArticleSelectedListener 實現的引用,以便Fragment A 可以通過調用 OnArticleSelectedListener 界面定義的方法與 Activity 共享事件。例如,如果Fragment A 是 ListFragment 的一個擴展,則用戶每次點擊列表項時,系統都會調用Fragment中的 onListItemClick(),然后該方法會調用 onArticleSelected() 以與 Activity 共享事件:
```
public static class FragmentA extends ListFragment {
OnArticleSelectedListener mListener;
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
Uri noteUri = ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id);
mListener.onArticleSelected(noteUri);
}
}
```
###Fragment是否很完美
因為Fragment是由FragmentManager來管理,每一個Activity有一個FragmentManager,管理著一個Fragment的棧,Activity是系統級別的,由系統來管理ActivityManager,棧也是系統范圍的。而Fragment則是每個Activity范圍內的,所以在使用Fragment的時候也有幾點要注意。
- 同一個Activity中,只能有一個ID或TAG標識的Fragment實例。
>這很容易理解,同一個范圍內,有標識的實例肯定是要唯一才行(否則還要標識干嘛)這個在布局中經常犯錯,在布局中寫Fragment最好不要加ID或者TAG,否則很容易出現不允許創建的錯誤。我的原則是如果放在布局中,就不要加ID和TAG,如果需要ID和TAG就全用代碼控制。創建新實例前先到FragmentManager中查找一番,這也正是有標識的意義所在。
- 一個Activity中有一個Fragment池,實例不一定會被銷毀,可能會保存在池中。
- 這個跟第一點差不多。就好比系統會緩存Activity的實例一樣,FragmentManager也會緩存Fragment實例,以方便和加速再次顯示。
>FragmentManager的作用范圍是整個Activity,所以,某一個布局ID,不能重復被Fragment替換。
通常顯示Fragment有二種方式,一種是層疊到某個布局上,或者把某個布局上面的Fragment替換掉,但是這個布局不能出現二次,比如布局A中有ID為id的區域,要顯示為Fragment,此布局A,只能在一個Activity中顯示一個,否則第二個id區域不能被Fragment成功替換。因為雖有二個ID布局的實例,但ID是相同的,對FragmentManager來說是一樣的,它會認為只有一個,因為它看的是布局的ID,而不是布局的實例。
- Fragment的生命周期反應Activity的生命周期。
>Fragment在顯示和退出時會走一遍完整的生命周期。此外,正在顯示時,就跟Activity的一樣,Activity被onPause,里面的Fragment就onPause,以此類推,由此帶來的問題就是,比如你在onStart()里面做了一些事情,那么,當宿主Activity被擋住,又出現時(比如接了個電話),Fragment的onStart也會被高到,所以你要想到,這些生命周期不單單在顯示和退出時會走到。
- Fragment的可見性。
>這個問題出現在有Fragment棧的時候,也就是說每個Fragment不知道自己是否真的對用戶可見。比如現在是Fragment A,又在其上面顯示了Fragment B,當B顯示后,A并不知道自己上面還有一個,也不知道自己對用戶不可見了,同樣再有一個C,B也不知。C退出后,B依然不知自己已在棧頂,對用戶可見,B退后,A也不知。也就是說Fragment顯示或者退出,棧里的其他Fragment無法感知。這點就不如Activity,a被b蓋住后,a會走到onStop(),同樣c顯示后,b也能通過onStop()感知。Fragment可以從FragmentManager監聽BackStackState的變化,但它只告訴你Stack變了,不告訴你是多了,還是少,還有你處的位置。有一個解決方案就是,記錄頁面的Path深度,再跟Fragment所在的Stack深度來比較,如果一致,那么這個Fragment就在棧頂。因為每個頁面的Path深度是固定的,而Stack深度是不變化的,所以這個能準確的判斷Fragment是否對用戶可見,當然,這個僅針對整個頁面有效,對于布局中的一個區域是無效的。
- Fragment的事件傳遞。
>對于層疊的Fragment,其實就相當于在一個FrameLayout里面加上一堆的View,所以,如果處于頂層的Fragment沒處理點擊事件,那么事件就會向下層傳遞,直到事件被處理。比如有二個Fragment A和B,B在A上面,B只有TextView且沒處理事件,那么點擊B時,會發現A里的View處理了事件。這個對于Activity也不會發生,因為事件不能跨窗體傳播,上面的Activity沒處理事件,也不會傳給下面的Activity,即使它可見。解決之法,就是讓上面的Fragment的根布局吃掉事件,為每個根ViewGroup添加onClick=“true”。
- 與第三方Activity交互。
>與第三方交互,仍要采用Android的標準startActivityForResult()和onActivityResult()這二個方法來進行。但對于Fragment有些事情需要注意,Fragment也有這二個方法,但是為了能正確的讓Fragment收到onActivityResult(),需要:
>1. 宿主Activity要實現一個空的onActivityResult(),里面調用super.onActivityResult()
>2. 調用Fragment#startActivityForResult()而不是用Activity的 當然,也可以直接使用Activity的startActivityForResult(),那樣的話,就只能在宿主Activity里處理返回的結果了。
小結
在用法的代碼部分參考[郭神的博客](http://blog.csdn.net/guolin_blog),感覺郭神在代碼講解部分通俗易懂,看起來也方便。總之,在使用Fragment也有一些注意事項,不是那么完美的,雖然谷歌推薦我們用Fragment來代替Activity來使用,我們也確實這做了,現在基本主流的APP也都是少量Activity+很多Fragment,但也需要避免有些坑慎入。
參考地址
1,[https://developer.android.com/guide/components/fragments.html](https://developer.android.com/guide/components/fragments.html)
2,[http://blog.csdn.net/guolin_blog/article/details/8881711](http://blog.csdn.net/guolin_blog/article/details/8881711)
3,[http://toughcoder.net/blog/2014/10/22/effective-android-ui-architecture](http://toughcoder.net/blog/2014/10/22/effective-android-ui-architecture)
###我的實踐流程
使用流程:
1.在xml布局文件中使用FrameLayout占位;
```
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:theme="@style/AppBaseTheme">
<FrameLayout
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/main_slip" />
<RelativeLayout />
```
2.在Activity中獲取 FragmentTransaction,修改當前顯示的Fragment
```
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment fragment = HomePagerFragments.newInstance("sd", "sd");
switch (checkedId) {
case R.id.main_rb_home:
fragment = HomePagerFragments.newInstance("sd", "sd");
break;
case R.id.main_rb_find://求租
fragment = FindPagerFragment.Companion.newInstance("sd", "dssd");
// fragment = FriendsPagerFragment.newInstance();
break;
case R.id.main_rb_message://消息
fragment = ConversationPagerFragment.newInstance(this);
break;
case R.id.main_rb_order://訂單
fragment = FriendsPagerFragment.Companion.newInstance();
break;
case R.id.main_rb_mine:
fragment = MinePagerFragment.Companion.newInstance();
break;
}
transaction.replace(R.id.main_content, fragment);
transaction.commit();
}
```
3.實現每一個Fragment
```
package com.lisxhs.kuaiyue.UI.Pager.Home;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.lisxhs.kuaiyue.Mode.PersonBaseInfo;
import com.lisxhs.kuaiyue.Mode.TabHostValue;
import com.lisxhs.kuaiyue.R;
import com.lisxhs.kuaiyue.UI.OnItemClickListener;
import com.lisxhs.kuaiyue.UI.Pager.ContentFragment;
import com.lisxhs.kuaiyue.UI.Pager.DemandLobbyActivity;
import com.lisxhs.kuaiyue.UI.Pager.MiniFeaturesFragment;
import com.lisxhs.kuaiyue.UI.Pager.SearchActivity;
import com.lisxhs.kuaiyue.UI.Pager.UserInformationActivity;
import com.lisxhs.kuaiyue.UI.TabHostComponent;
import com.lisxhs.kuaiyue.Util.Adapter.GuessYouLikeRecyclerAdapter;
import com.lisxhs.kuaiyue.Util.Adapter.NewPersonRecyclerAdapter;
import com.lisxhs.kuaiyue.Util.MyScrollView;
import org.jetbrains.annotations.NotNull;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
public class HomePagerFragments extends Fragment implements View.OnClickListener {
private final String TAG = "HomePagerFragments";
private OnFragmentInteractionListener mListener;
private MyScrollView mScrollView;
private TabHostComponent mTabHostComponent;
private SwipeRefreshLayout mRefresh;
private View mFloatSearch;
private View mView;
private Context mContext;
private ContentFragment mGuessYouLike;
private ContentFragment mNewPerson;
private boolean mIsInitData = true;
public HomePagerFragments() {
// Required empty public constructor
}
public static HomePagerFragments newInstance(String param1, String param2) {
HomePagerFragments fragment = new HomePagerFragments();
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
mView = inflater.inflate(R.layout.homepager_fragment, container, false);
initView();
Log.d(TAG, "----onCreateView----");
return mView;
}
@Override
public void onStart() {
super.onStart();
Log.d(TAG, "----onStart----");
if (mIsInitData) {
initData();
}
}
private final int REFRESH_FINSH = 0;
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case REFRESH_FINSH:
mRefresh.setRefreshing(false);
//通知數據更新
break;
}
super.handleMessage(msg);
}
};
private void initView() {
mFloatSearch = (View) mView.findViewById(R.id.homepager_search);
mFloatSearch.setOnClickListener(this);
mRefresh = (SwipeRefreshLayout) mView.findViewById(R.id.homepager_refresh);
mRefresh.setColorSchemeResources(R.color.aqua, R.color.blue);
mRefresh.setSize(SwipeRefreshLayout.DEFAULT);
mRefresh.setProgressBackgroundColorSchemeColor(getResources().getColor(R.color.yellow));
mRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
//訪問網絡,完成數據的刷新
new Thread(new Runnable() {
@Override
public void run() {
// data.clear();
// for(int i=0;i<20;i++){
// data.add("SwipeRefreshLayout下拉刷新"+i);
// }
// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mHandler.sendEmptyMessage(REFRESH_FINSH);
}
}).start();
}
});
mFloatSearch = (View) mView.findViewById(R.id.homepager_search);
//猜你喜歡/推薦新人
mTabHostComponent = (TabHostComponent) mView.findViewById(R.id.homepager_tabhostcomponent);
}
private void initData() {
mIsInitData = false;
// mLoopSmallAds.setData(getData());
//設置猜你喜歡頁面信息
mTabHostComponent.setHW();
mGuessYouLike = new ContentFragment(mContext);
mGuessYouLike.setLayoutManager(new GridLayoutManager(getActivity(), 2));//兩列的網格布局
GuessYouLikeRecyclerAdapter adapter = new GuessYouLikeRecyclerAdapter(getContext(), getGuessYouLikeData());
adapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Intent intent = new Intent();
intent.setClass(mContext, UserInformationActivity.class);
intent.putExtra("UserId", getGuessYouLikeData().get(position).getId());
intent.putExtra("HXId", getGuessYouLikeData().get(position).getHXid());
intent.putExtra("UserName", getGuessYouLikeData().get(position).getRealname());
intent.putExtra("UserUrl", getGuessYouLikeData().get(position).getUrl());
startActivity(intent);
}
});
mGuessYouLike.setAdapter(adapter);
//設置推薦新人頁面信息
mNewPerson = new ContentFragment(mContext);
// GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 2, LinearLayoutManager.HORIZONTAL, false);
// layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
//
// @Override
// public int getSpanSize(int position) {
// // 每隔 3 個位置占據 2 列,其他位置則占 1 列
//// int pos = position % 3 == 0 ? 2 : 1;
// int pos = position % (new Random(System.currentTimeMillis()).nextInt());
// Log.e(TAG, "post>>>>>" + pos);
//
// return pos;
// }
// });
mNewPerson.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
NewPersonRecyclerAdapter mNewPersonAdapter = new NewPersonRecyclerAdapter(getContext(), GetNewPersonData());
mNewPersonAdapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Log.e(TAG, "position>>>>>" + position);
Intent intent = new Intent();
intent.setClass(mContext, UserInformationActivity.class);
intent.putExtra("UserId", GetNewPersonData().get(position).getId());
intent.putExtra("HXId", GetNewPersonData().get(position).getHXid());
intent.putExtra("UserName", GetNewPersonData().get(position).getRealname());
intent.putExtra("UserUrl", GetNewPersonData().get(position).getUrl());
startActivity(intent);
}
});
mNewPerson.setAdapter(mNewPersonAdapter);
// mNewPerson = ImageShowItem.newInstence(mContext, null);
List<String> DemandTitle = new ArrayList<String>(Arrays.asList("猜你喜歡", "推薦新人"));
List<View> DemandView = new ArrayList<View>(Arrays.asList(mGuessYouLike, mNewPerson));
TabHostValue tabHostValue = new TabHostValue(DemandTitle, DemandView);
mTabHostComponent.setValue(tabHostValue);
//初始化小功能
initMiniFeature();
}
private ArrayList<PersonBaseInfo> getGuessYouLikeData() {
ArrayList<PersonBaseInfo> data = new ArrayList<PersonBaseInfo>();
String[] picUrls = new String[]{
"http://img4.imgtn.bdimg.com/it/u=2588584214,1957369974&fm=11&gp=0.jpg",
"http://img3.imgtn.bdimg.com/it/u=271046179,1453629278&fm=11&gp=0.jpg",
"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3795770905,4042765228&fm=26&gp=0.jpg",
"https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2523214402,1651294430&fm=26&gp=0.jpg",
"https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3528666336,2810085622&fm=26&gp=0.jpg",
"https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3216390431,2469449241&fm=26&gp=0.jpg",
"https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3366932712,1378773184&fm=26&gp=0.jpg",
"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3178413963,2928643400&fm=26&gp=0.jpg",
"https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3290413363,1540049309&fm=26&gp=0.jpg",
"https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=602396125,1905492147&fm=26&gp=0.jpg"
};
String[] name = new String[]{"Anima micosoft", "張子諾", "瓊脂", "李玉生", "吳淑華", "張金鳳", "花魁", "紫雨軒"};
String[] address = new String[]{"北京·昌平", "北京·朝陽", "上海·浦東", "深圳·數碼", "北京·密云", "北京·朝陽", "成都·樂山", "河南·洛陽"};
int[] price = new int[]{100, 230, 99, 25, 2800, 15000, 899};
String[] priceunit = new String[]{"天", "周", "天", "小時", "月", "年", "月"};
for (int i = 0; i < 100; i++) {
PersonBaseInfo p = new PersonBaseInfo(i + "123", "13524526543", name[i % 8], "", "13524526543", 167, 48, false, 28, address[i % 8], null, picUrls[i % 10], null);
data.add(p);
//price[i % 7], priceunit[i % 7],
}
return data;
}
private ArrayList<PersonBaseInfo> GetNewPersonData() {
ArrayList<PersonBaseInfo> personBaseInfos = new ArrayList<PersonBaseInfo>();
String[] picUrls = new String[]{
"https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2610939267,2111867656&fm=26&gp=0.jpg",
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1498207459022&di=d5cecee8c605fd0064e55d6dee79e7bb&imgtype=0&src=http%3A%2F%2Fimg.taopic.com%2Fuploads%2Fallimg%2F140119%2F234931-14011ZU44090.jpg",
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1498207459021&di=ae19814f72ed78b3de95155990c425d0&imgtype=0&src=http%3A%2F%2Fimage.tianjimedia.com%2FuploadImages%2F2014%2F064%2FJ3WM56H20028.jpg",
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1498207459021&di=1d85fc33fa6e1397baf71e4416a73f1b&imgtype=0&src=http%3A%2F%2Fn.sinaimg.cn%2Ftranslate%2F20170510%2FUwol-fyeyqem3148702.jpg",
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1498207511859&di=bb795cc4d249850f8dc6bf5afcf17760&imgtype=jpg&src=http%3A%2F%2Fimg4.imgtn.bdimg.com%2Fit%2Fu%3D2188449118%2C29486929%26fm%3D214%26gp%3D0.jpg",
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1498207459020&di=ff07d11515af75bb7f91193df3aa36c8&imgtype=0&src=http%3A%2F%2Fimg.ithome.com%2Fnewsuploadfiles%2F2016%2F4%2F20160406_110824_799.jpg",
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1498207459018&di=dd42fc9fc665242eafa59284410542aa&imgtype=0&src=http%3A%2F%2Fimg.tupianzj.com%2Fuploads%2Fallimg%2F160630%2F9-160630092544.jpg",
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1498207459018&di=7f26d688dc12ba46dbd9a9f710468d81&imgtype=0&src=http%3A%2F%2Fn.sinaimg.cn%2Ftranslate%2F20170510%2F9iLV-fyeyqem3148601.jpg",
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1498207459016&di=ae5f99a032b53ad66a1ea1264bf39bcf&imgtype=0&src=http%3A%2F%2Fn.sinaimg.cn%2Ftranslate%2F20170510%2FQ5A5-fyeyqem3148719.jpg",
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1498207459016&di=4d5e05f399579e21bb7b2ea568748070&imgtype=0&src=http%3A%2F%2Fimg3.duitang.com%2Fuploads%2Fitem%2F201607%2F26%2F20160726223935_r8AeQ.jpeg",
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1498207459015&di=75c888958f7dec646f080dbffe157159&imgtype=0&src=http%3A%2F%2Fimg05.tooopen.com%2Fimages%2F20150521%2Ftooopen_sy_125612977867.jpg"
};
String[] name = new String[]{"Anli Bobo", "小才情", "瓊 脂", "阿里狐貍", "Miner fo", "Cholcoler", "小清新·雅", "雨 兒"};
String[] address = new String[]{"北京·昌平", "北京·朝陽", "上海·浦東", "深圳·數碼", "北京·密云", "北京·朝陽", "成都·樂山", "河南·洛陽"};
int[] price = new int[]{100, 230, 99, 25, 2800, 15000, 899};
String[] priceunit = new String[]{"天", "周", "天", "小時", "月", "年", "月"};
for (int i = 0; i < 1000; i++) {
PersonBaseInfo p = new PersonBaseInfo(i + "newperson", i + "NPS", name[i % 8], name[i % 8], "1237348123", 177, 56, true, 23, address[i % 8], null, picUrls[i % 11], null);
//price[i % 7], priceunit[i % 7],
personBaseInfos.add(p);
}
return personBaseInfos;
}
//小功能
private void initMiniFeature() {
ArrayList<Integer> mDatas = new ArrayList<Integer>(Arrays.asList(R.drawable.ic_home_sk1_1,
R.drawable.ic_home_sk1_2, R.drawable.ic_home_sk1_3, R.drawable.ic_home_sk1_4, R.drawable.ic_home_sk1_5,
R.drawable.ic_home_sk1_5, R.drawable.ic_home_sk1_4, R.drawable.ic_home_sk1_3, R.drawable.ic_home_sk1_2, R.drawable.ic_home_sk1_1));
ArrayList<String> ttt = new ArrayList<String>(Arrays.asList("私人訂制", "情感", "球類", "運動", "寵物", "線上", "占卜", "戀愛", "導游", "陪玩"));
MiniFeaturesFragment miniFeaturesFragment1 = MiniFeaturesFragment.newInstance("休閑娛樂", mDatas, ttt);
MiniFeaturesFragment miniFeaturesFragment2 = MiniFeaturesFragment.newInstance("商戶服務", mDatas, ttt);
// List<MiniFeaturesFragment> ll = new ArrayList<MiniFeaturesFragment>();
// ll.add(miniFeaturesFragment1);
// MiniFeatureAdapter adapter = new MiniFeatureAdapter(((FragmentActivity) mContext).getSupportFragmentManager(), ll);
// mEntertainment.setAdapter(adapter);
// mEntertainment.setCurrentItem(0);
// 不使用ViewPager 直接替換Fragment
// FragmentTransaction transaction = ((FragmentActivity) mContext).getSupportFragmentManager().beginTransaction();
// transaction.replace(R.id.homepager_merchant_services, miniFeaturesFragment2);
// transaction.replace(R.id.homepager_entertainment, miniFeaturesFragment1);
// transaction.commit();
}
public List<Map<String, Object>> getData() {
List<Map<String, Object>> mdata = new ArrayList<Map<String, Object>>();
Map<String, Object> map = new HashMap<String, Object>();
// map.put("url", "http://img2.duitang.com/uploads/item/201207/19/20120719132725_UkzCN.jpeg");
map.put("url", "http://pic.qiantucdn.com/58pic/26/53/03/59a58PICZp5_1024.jpg!/watermark/url/L3dhdGVybWFyay12MS5wbmc=/align/north/repeat/true");
map.put("view", new ImageView(mContext));
mdata.add(map);
Map<String, Object> map1 = new HashMap<String, Object>();
// map1.put("url", "http://img4.duitang.com/uploads/item/201404/24/20140424195028_vtvZu.jpeg");
map1.put("url", "http://pic.qiantucdn.com/58pic/26/36/00/058PICV58PICUy2_1024.jpg!/watermark/url/L3dhdGVybWFyay12MS5wbmc=/align/north/repeat/true");
map1.put("view", new ImageView(mContext));
mdata.add(map1);
Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("url", "http://pic.qiantucdn.com/58pic/26/36/16/50858PICHkU_1024.jpg!/watermark/url/L3dhdGVybWFyay12MS5wbmc=/align/north/repeat/true");
map2.put("view", new ImageView(mContext));
mdata.add(map2);
Map<String, Object> map3 = new HashMap<String, Object>();
// map3.put("url", "http://www.mangowed.com/uploads/allimg/130425/572-130425105311304.jpg");
map3.put("url", "http://pic.qiantucdn.com/58pic/26/36/00/12M58PICKDi_1024.jpg!/watermark/url/L3dhdGVybWFyay12MS5wbmc=/align/north/repeat/true");
map3.put("view", new ImageView(mContext));
mdata.add(map3);
return mdata;
}
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
Log.d(TAG, "----onAttach----");
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
@Override
public void onClick(View v) {
Intent intent = new Intent();
switch (v.getId()) {
case R.id.home_show_profit:
intent = new Intent(getContext(), DemandLobbyActivity.class);
break;
case R.id.homepager_search:
intent = new Intent(getContext(), SearchActivity.class);
break;
case R.id.home_show_skill:
intent = new Intent(getContext(), SearchActivity.class);
break;
}
startActivity(intent);
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
```
####Fragment與Activity信息交互:創建事件回調
>一個Fragment的實例總是和包含它的Activity直接相關。fragment可以通過getActivity() 方法來獲得Activity的實例,然后就可以調用一些例如findViewById() 之類的方法。
如:
>
```
View listView = getActivity.findViewById(R.id.list);
```
>但是注意調用getActivity()時,fragment必須和activity關聯(attached to an activity),否則將會返回一個null。
相似的,activity也可以獲得一個fragment的引用,從而調用fragment中的方法。
獲得fragment的引用要用FragmentManager,之后可以調用findFragmentById() 或者 findFragmentByTag().
比如:
```
ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);
```
> 一些情況下,可能需要fragment和activity共享事件,一個比較好的做法是在fragment里面定義一個回調接口,然后要求宿主activity實現它。
當activity通過這個接口接收到一個回調,它可以同布局中的其他fragment分享這個信息。