Fragment的使用

来源:互联网 发布:唇模招聘淘宝 编辑:程序博客网 时间:2024/05/29 12:09

一、简介

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);        }    }}
0 0
原创粉丝点击