Fragment的使用

一、简介

1.定义:碎片。API11(3.0)之后才出现的,低版本想要使用的话,需要继承FragmentActivity类。
2.生命周期:有自己独立的生命周期,但是依赖于Activity的生命周期。一旦所依赖的Activtiy被杀死,所有相关的Fragment都会被杀死。添加Fragment时的生命周期:onAttach()–>onCreate()–>onCreateView()–>onActivityCreated()–>onStart()–>onResume()。Fragment被移除销毁时的生命周期:onPause()–>onStop–>onDestroyView()–>onDestroy()–>onDetach()。切换Fragment时的生命周期:onPause()–>onStop–>onDestroyView()。
多个Fragment之间切换的生命周期如下:

 第一个Fragment被加载
 -----Fragment1->>onAttach  -----Fragment1->>onCreate  -----Fragment1->>onCreateView  -----Fragment1->>onActivityCreated  -----Fragment1->>onStart  -----Fragment1->>onResume  第二个Fragment进来
 -----Fragment1->>onPause  -----Fragment1->>onStop  -----Fragment1->>onDestroyView 
 -----Fragment2->>onAttach  -----Fragment2->>onCreate  -----Fragment2->>onCreateView  -----Fragment2->>onActivityCreated  -----Fragment2->>onStart  -----Fragment2->>onResume  第三个Fragment进来
 -----Fragment2->>onPause  -----Fragment2->>onStop  -----Fragment2->>onDestroyView 
 -----Fragment3->>onAttach  -----Fragment3->>onCreate  -----Fragment3->>onCreateView  -----Fragment3->>onActivityCreated  -----Fragment3->>onStart  -----Fragment3->>onResume 
 回退到第二个Fragment
 -----Fragment3->>onPause  -----Fragment3->>onStop  -----Fragment3->>onDestroyView 
 -----Fragment2->>onCreateView  -----Fragment2->>onActivityCreated  -----Fragment2->>onStart  -----Fragment2->>onResume 




3.相关方法与相关类
FragmentManager
getFragmentManager(),getSupportFragmentManager()
findFragmentByTag() , findFragmentById() [在xml文件中定义了frament标签的id]
beginTransaction()【开启一个事务,可以在事务一次add多个fragment,或者replace一个fragment】
FragmentTransaction
replace(),add(),addToBackStack()
remove()
commit()
transaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)【设置各种切换动画】

二、Fragment的使用场景

1.结合Activity使用
- Fragment可以在xml文件中用fragment标签添加在一个activity中,也可以在代码中add。
- 涉及到Activity与Fragment之间数据交互,Fragment之间数据交互。
2.结合ActionBar使用
3.结合ViewPager使用
- PagerAdapter
- FragmentPagerAdapter
- FragmentStatePagerAdapter
我们还可以通过ViewPager来管理Fragment,通过Adapter添加多个Fragment,然后通过setcurrentitem进行切换。我们同样可以通过setArguments向Fragment传递数据。
4.结合
5.ListFragment
6.DialogFragment
7.PreferenceFragment

三、示例代码

1.结合activity使用
数据传递:
①Activity向Fragment传递数据:setArgument()/getArgument();
②Fragment之间数据传递:
示例一:Activity向Fragment传递数据
一个Activity可以结合一个或者多个Fragment使用,如果显示的数据之间有共性,可以共用Fragment。
布局文件activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" tools:context=".MainActivity" >

    <LinearLayout  android:id="@+id/left" android:layout_width="wrap_content" android:layout_height="match_parent" android:background="#CCCCCC" android:orientation="vertical" >

        <Button  android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="男鞋" />

        <Button  android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="女鞋" />

        <Button  android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="男装" />

        <Button  android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="女装" />
    </LinearLayout>

    <FrameLayout  android:id="@+id/center" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="3" >
    </FrameLayout>

</LinearLayout>
public class MainActivity extends Activity implements OnClickListener {
    private FragmentManager manager;
    private FragmentTransaction transaction;
    private Button button1, button2, button3, button4;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        manager = getFragmentManager();
        button1 = (Button) this.findViewById(R.id.button1);
        button1.setOnClickListener(this);
        button2 = (Button) this.findViewById(R.id.button2);
        button2.setOnClickListener(this);
        button3 = (Button) this.findViewById(R.id.button3);
        button3.setOnClickListener(this);
        button4 = (Button) this.findViewById(R.id.button4);
        button4.setOnClickListener(this);

        //默认自动触发一次
        button1.performClick();
    }


    /** * Fragment之间传递数据。 * @note 传递数据必须在add/replace之前。 * @note 如果展示的数据结构相同,使用同一个Fragment来接收不同的数据参数;否则可以新建多个Fragment */
    @Override
    public void onClick(View v) {
        transaction = manager.beginTransaction();
        Bundle bundle = new Bundle();
        Fragment1 fragment1 = new Fragment1();

        switch (v.getId()) {
        case R.id.button1:
            bundle.putString("category_id", "12");
            break;
        case R.id.button2:
            bundle.putString("category_id", "13");
            break;
        case R.id.button3:
            bundle.putString("category_id", "14");
            break;
        case R.id.button4:
            bundle.putString("category_id", "15");
            break;
        }
        transaction.replace(R.id.center, fragment1, "fragment1");
        //transaction.addToBackStack("fragment1");// 添加到Activity管理的回退栈中。
        fragment1.setArguments(bundle);
        transaction.commit();
    }
}

上面讲解了如何在Activity中向Fragment传递数据。下面示例讲解如何在Fragment之间进行数据传递。
示例二:Fragment之间数据传递

public class MainActivity extends Activity {
    private FragmentManager manager;
    private FragmentTransaction transaction;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        manager = getFragmentManager();
        transaction = manager.beginTransaction();

        LeftFragment leftFragment = new LeftFragment();
        RightFragment rightFragment = new RightFragment();

        // replace 是先remove掉相同id的所有fragment,然后在add当前的这个fragment。大部分情况:两者相同
        transaction.add(R.id.left, leftFragment, "left");
        transaction.add(R.id.right, rightFragment, "right");
        transaction.commit();
    }
}

在LeftFragment 中获得RightFragment中某个控件的值。通过getActivity获得Activity中某个控件的值。

public class LeftFragment extends Fragment {

    private Button button;
    private FragmentManager manager;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        manager = getFragmentManager();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.left, null);
        button = (Button) view.findViewById(R.id.button1);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                RightFragment rightFragment = (RightFragment) manager
                    .findFragmentByTag("right");
                String msg = ((EditText) rightFragment.getView()
                    .findViewById(R.id.editText1)).getText().toString();
                Toast.makeText(getActivity(), "-right->>" + msg, 0).show();

                Log.i("-->", getActivity().toString());
                if(getActivity() instanceof MainActivity){
                    MainActivity main = (MainActivity) getActivity();
                    TextView tv = (TextView) main.findViewById(R.id.tv);
                    Log.i("-->", tv.getText().toString());
                }
            }
        });
        return view;
    }
    @Override
    public void onPause() {
        super.onPause();
    }
}

示例三:在activity中获得fragment中某个控件的值
MainActivity .java

public class MainActivity extends Activity {
    private FragmentManager manager;
    private FragmentTransaction transaction;
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (Button) this.findViewById(R.id.button);

        // 添加
        manager = getFragmentManager();
        transaction = manager.beginTransaction();
        transaction.add(R.id.left, new LeftFragment(), "left");
        transaction.commit();

        // 在activity中获得fragment控件的值,使用回调
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //通过tag找到要操作的fragment
                LeftFragment leftFragment = (LeftFragment) manager.findFragmentByTag("left");
                leftFragment.getEditText(new CallBack() {
                    @Override
                    public void getResult(String result) {
                        Toast.makeText(MainActivity.this, "-->>" + result, 1).show();
                    }
                });
            }
        });
    }
}

LeftFragment.java

public class LeftFragment extends Fragment {

    private Button button;
    private EditText editText;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.left, null);
        editText = (EditText) view.findViewById(R.id.editText1);
        button = (Button) view.findViewById(R.id.button1);

        //在fragment中获得activity控件的值
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EditText editText = (EditText) getActivity().findViewById(R.id.editText2);
                Toast.makeText(getActivity(), "-->>" + editText.getText().toString(), 1).show();
            }
        });
        return view;
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    /** * 对外提供的方法,用于在Activity中获得fragment中的值 * @param callBack */
    public void getEditText(CallBack callBack) {
        String msg = editText.getText().toString();
        callBack.getResult(msg);
    }
    public interface CallBack {
        public void getResult(String result);
    }
}

2.结合ActionBar使用

public class MainActivity extends Activity {
    private ActionBar actionBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        actionBar = getActionBar();
        // 设置ActionBar的导航模式
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        //隐藏标题栏
        actionBar.setDisplayShowTitleEnabled(false);
        actionBar.setDisplayShowHomeEnabled(false);
        //添加tabs
        actionBar.addTab(actionBar.newTab().setText("系统管理")
                .setIcon(getResources().getDrawable(R.drawable.alarm))
                .setTabListener(new MyTabListener()).setTag(1));
        actionBar.addTab(actionBar.newTab().setText("用户管理")
                .setIcon(getResources().getDrawable(R.drawable.sys))
                .setTabListener(new MyTabListener()).setTag(2));
        actionBar.addTab(actionBar.newTab().setText("产品管理")
                .setIcon(getResources().getDrawable(R.drawable.user))
                .setTabListener(new MyTabListener()).setTag(3));
    }
    public class MyTabListener implements ActionBar.TabListener {

        @Override
        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            int tag = Integer.parseInt(tab.getTag().toString());
            switch (tag) {
            case 1:
                ft.replace(R.id.main, new FragmentA(), "fragment1");
                break;

            case 2:
                ft.replace(R.id.main, new FragmentB(), "fragment2");
                break;

            case 3:
                ft.replace(R.id.main, new FragmentC(), "fragment3");
                break;
            }
        }

        @Override
        public void onTabUnselected(Tab tab, FragmentTransaction ft) {

        }

        @Override
        public void onTabReselected(Tab tab, FragmentTransaction ft) {

        }
    }
}

3.结合ViewPager的使用
使用ViewPager,首先需要一个集合,可以是List,List,List,然后使用一个数据适配器将数据适配给ViewPager。ViewPager自带提供了三个适配器,根据情况决定使用哪一个。PagerAdapter适用于View的集合;FragmentPagerAdapter 适用于Fragment的集合,且页面无需缓存;FragmentStatePagerAdapter 适用于Fragment的集合,且需要缓存页面。
①PagerAdapter
MainActivity.java

public class MainActivity extends Activity {

    private ViewPager viewPager;
    // 表示ViewPager显示的内容
    private List<View> content;
    // 表示ViewPager显示的标题
    private List<String> title;
    private LayoutInflater inflater;
    private myPageAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        init();

        adapter = new myPageAdapter();
        viewPager.setAdapter(adapter);
        adapter.notifyDataSetChanged();

    }

    private void init() {
        viewPager = (ViewPager) this.findViewById(R.id.viewpager);
        //初始化数据
        inflater = LayoutInflater.from(this);
        content = new ArrayList<View>();
        title = new ArrayList<String>();
        View firstView = inflater.inflate(R.layout.first, null);
        View secondView = inflater.inflate(R.layout.second, null);
        View threeView = inflater.inflate(R.layout.three, null);
        content.add(firstView);
        content.add(secondView);
        content.add(threeView);
        title.add("体育");
        title.add("娱乐");
        title.add("新闻");
    }

    public class myPageAdapter extends PagerAdapter {
        //初始化每个item
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            ((ViewPager) container).addView(content.get(position));
            return content.get(position);
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return title.get(position);
        }

        @Override
        public int getCount() {
            return content.size();
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == arg1;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            ((ViewPager) container).removeView(content.get(position));

        }
    }

}

activity_main.xml
根据情况决定是否增加Title,一般app的导航界面,不需要Title,使用几张图片就可以实现了。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" >

    <!-- 看做一个普通的控件 -->

    <android.support.v4.view.ViewPager  android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" >

        <android.support.v4.view.PagerTitleStrip  android:id="@+id/pagertitle" android:layout_width="wrap_content" android:layout_height="30dp" android:background="@android:color/darker_gray" android:layout_gravity="top" >
        </android.support.v4.view.PagerTitleStrip>
    </android.support.v4.view.ViewPager>

</RelativeLayout>

②FragmentPagerAdapter
ViewPager的使用都是一样的,区别只是适配器的实现方式不同。

public class MyAdapter extends FragmentPagerAdapter {

        public MyAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            return list.get(position);
        }

        @Override
        public int getCount() {
            return list.size();
        }

    }

③FragmentStatePagerAdapter
该适配器使用和之前的类似。如果Fragment的数量比较多,一般超过5个以上,还是推进使用缓存的机制,对当前访问的fragment的左右fragment进行缓存。示例结果:


public class MainActivity extends FragmentActivity implements OnClickListener {
    private ViewPager viewPager;
    static final int NUM_ITEMS = 10;// 定义一共有10页
    private MyAdapter adapter;
    private Button go_first;
    private Button go_last;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        init();
        viewPager.setAdapter(adapter);
    }

    private void init() {
        viewPager = (ViewPager) this.findViewById(R.id.pager);
        adapter = new MyAdapter(getSupportFragmentManager());
        go_first = (Button) this.findViewById(R.id.goto_first);
        go_last = (Button) this.findViewById(R.id.goto_last);
        go_first.setOnClickListener(this);
        go_last.setOnClickListener(this);
    }
    //跳转到首页和尾页
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.goto_first:
            viewPager.setCurrentItem(0);
            break;
        case R.id.goto_last:
            viewPager.setCurrentItem(NUM_ITEMS -1);
            break;
        }
    }
    public static class MyAdapter extends FragmentStatePagerAdapter {

        public MyAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int arg0) {
            return ArrayListFragment.getIntances(arg0);
        }

        @Override
        public int getCount() {
            return NUM_ITEMS;
        }

    }

    public static class ArrayListFragment extends ListFragment {
        int num;
        static ArrayListFragment getIntances(int num) {
            ArrayListFragment listFragment = new ArrayListFragment();
            Bundle bundle = new Bundle();
            bundle.putInt("num", num);
            listFragment.setArguments(bundle);
            return listFragment;
        }

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, getData()));
        }

        public List<String> getData() {
            List<String> list = new ArrayList<String>();
            for (int i = 0; i < 20; i++) {
                list.add("jack" + i);
            }
            return list;
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            System.out.println("------>>" + num);
            num = (getArguments() != null ? getArguments().getInt("num") : 1);
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

            View view = inflater.inflate(R.layout.fragment_pager_list, null);
            TextView textView = (TextView) view.findViewById(R.id.text);
            textView.setText("Fragment #" + num);
            return view;
        }
        @Override
        public void onListItemClick(ListView l, View v, int position, long id) {
            Log.i("FragmentList", "Item clicked: " + id);
        }
    }
}

你可能感兴趣的:(Fragment)