Fragment 生命周期

作者: Lost_Robot | 来源:发表于2017-07-25 17:29 被阅读214次

    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时(跟用户交互)要调用的核心的生命周期方法如下:

    1. 把Fragment对象跟Activity关联时,调用onAttach(Activity)方法;
    2. Fragment对象的初始创建时,调用onCreate(Bundle)方法;
    3. onCreateView(LayoutInflater, ViewGroup, Bundle)方法用于创建和返回跟Fragment关联的View对象;
    4. onActivityCreate(Bundle)方法会告诉Fragment对象,它所依附的Activity对象已经完成了Activity.onCreate()方法的执行;
    5. onStart()方法会让Fragment对象显示给用户(在包含该Fragment对象的Activity被启动后);
    6. onResume()会让Fragment对象跟用户交互(在包含该Fragment对象的Activity被启恢复后)。
    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生命周期详细对比

    这张图是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分享这个信息。
    
    
    
    
    

    相关文章

      网友评论

        本文标题:Fragment 生命周期

        本文链接:https://www.haomeiwen.com/subject/eqawkxtx.html