1. Fragment是什么
1.什么是Fragment?
fragment它自己的中文意思:碎片;
一个可以将activity拆分成几个完全独立封装的可重用的组件,每个组件有自己的生命周期和ui布局。
2.用fragment能解决什么问题?
说明:总的来说,Fragment和Activity的生命周期类似。需要注意的是,它相比于Activity,多了onAttach(), onDetch(), onCreateView()和onDestroyView()这几个回调函数;但是,却少了onRestart()。
Fragment的生命周期非常复杂,分为以下几种情况:
- 如果是通过XML中的<fragment/>标签实例化的,那么第一个收到的回调将是onInflate
- 如果setRetainInstance(true),那么当Activity重建时,Fragment的onDestroy以及Activity重建后Fragment的onCreate回调不会被调用.(无论是否将其添加到了返回栈)
- 如果当前显示的是Fragment A,然后执行FragmentTransaction.replace(),那么Fragment A会执行onPause()->onStop()->onDestroyView()->onDestroy()->onDetach(),如果执行FragmentTransaction.replace().addToBackStack(),那么Fragment A会执行onPause()->onStop()->onDestroyView()
- FragmentTransaction.hide(),将不会导致onPause(),而是会触发onHiddenChanged()
- FragmentTransaction.detach(),会导致onPause()->onStop()->onDestroyView(),注意:onDestroy()和onDetach()不会调用
3.fragment静态加载方法
fragment静态加载所用的布局,android:name属性中是MyFragment.java的全名,android:id中是Fragment的唯一标识(这个必须得加,否则报错,也可用android:tag属性来作唯一标识)。
- <fragment
- android:name="com.example.myfragment.MyFragment"
- android:id="@+id/myfragment_1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
4.fragment动态加载方法
1.创建一个类继承Fragment,复写onCreateView方法。
例如:
public class AnotherRightFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){
//传进fragment布局文件创建一个view对象
View view =inflater.inflate(R.layout_another_right_fragment,container,flase);
return view;
}
}
2.在MainActivity中创建待添加的fragment实例。
AnotherRightFragment fragment = new AnotherRightFragment();
3.在Activity中通过调用个体FragmentManager()方法获取到FragmentManager。
FragmentManager fragmentManager = getFragmentManager();
4.开启一个事物,通过调用beginTransaction()方法开启。
FragmentTransaction transaction = fragmentManager.beginTransaction();
5.向容器内加入Fragment,一般使用replace()方法实现,需要传入容器的id和待添加的碎片实例。
transaction.replace(R.id.right_layout,fragment);
6.提交事务,调用commit()方法来完成。
transaction.commit();
5.viewpager+fragment实现页卡滑动切换
布局文件activity_main.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="@dimen/top_tab_height"
android:background="@color/main_top_color" >
<TextView
android:id="@+id/picture_text"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0"
android:gravity="center"
android:text="@string/picture"
android:textStyle="bold"
android:textColor="@color/main_top_tab_color"
android:textSize="@dimen/main_top_tab_text_size" />
<TextView
android:id="@+id/movie_text"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0"
android:gravity="center"
android:text="@string/movie"
android:textStyle="bold"
android:textColor="@color/main_top_tab_color"
android:textSize="@dimen/main_top_tab_text_size" />
<TextView
android:id="@+id/music_text"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0"
android:gravity="center"
android:text="@string/music"
android:textStyle="bold"
android:textColor="@color/main_top_tab_color"
android:textSize="@dimen/main_top_tab_text_size" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/main_line_height"
android:layout_gravity="bottom"
android:orientation="vertical"
android:background="@color/main_top_color"
>
<ImageView
android:id="@+id/cursor"
android:layout_width="@dimen/main_matrix_width"
android:layout_height="@dimen/main_line_height"
android:scaleType="matrix"
android:src="@color/matrix_color" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="0.5dp"
android:background="@color/main_top_color"/>
<android.support.v4.view.ViewPager
android:id="@+id/vPager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_weight="1.0"
android:background="@color/white"
android:flipInterval="30"
android:persistentDrawingCache="animation" />
</LinearLayout>
2.Fragment静态加载怎么用
- <fragment
- android:name="com.example.myfragment.MyFragment"
- android:id="@+id/myfragment_1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
以上就是静态加载所用的布局,android:name属性中是MyFragment.java的全名,android:id中是Fragment的唯一标识(这个必须得加,否则报错,也可用android:tag属性来作唯一标识)。
- public class MainActivity extends ActionBarActivity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //做一个简单的UI操作,证明静态加载时我们可以直接获取到
- //Fragment中的UI控件
- TextView tv = (TextView) findViewById(R.id.textView);
- tv.setText("床前明月光");
- }
- }
3.Fragment动态加载怎么用
- // 开启一个新事务
- transaction = manager.beginTransaction();
- // 使用add方法添加Fragment,第一个参数是要把Fragment添加到的布局Id
- // 第二个就是要添加的Fragment
- transaction.add(R.id.fragments, fragment);
- // 提交事务,否则添加就没成功
- transaction.commit();
4.ViewPager+Fragment实现页卡滑动
效果图:
既可以实现滑动使单选按钮改变颜色,也可以通过点击单选按钮实现页面跳转,类似于微信
xml代码(布局文件):
activity_main.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
- android:orientation="vertical"
- android:layout_height="match_parent" tools:context="com.example.test0615.MainActivity">
- <android.support.v4.view.ViewPager
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:id="@+id/vp_main_viewpager"
- ></android.support.v4.view.ViewPager>
- <RadioGroup
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:id="@+id/rg_main_radio"
- >
- <!--layout_weight属性:设置权重,每个单选按钮占屏幕宽度的四分之一;button属性:设置单选按钮不可见-->
- <RadioButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:button="@null"
- android:text="微信"
- android:id="@+id/rb_mian_one"
- android:layout_weight="1"
- android:background="@drawable/selector_radiobutton"
- />
- <!--background属性:设置单选按钮的选择器-->
- <RadioButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:button="@null"
- android:text="通讯录"
- android:id="@+id/rb_mian_two"
- android:layout_weight="1"
- android:background="@drawable/selector_radiobutton"
- />
- <RadioButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:button="@null"
- android:text="发现"
- android:id="@+id/rb_mian_three"
- android:layout_weight="1"
- android:background="@drawable/selector_radiobutton"
- />
- <RadioButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:button="@null"
- android:text="我"
- android:id="@+id/rb_mian_four"
- android:layout_weight="1"
- android:background="@drawable/selector_radiobutton"
- />
- </RadioGroup>
- </LinearLayout>
选择器代码:
selcctor_radiobutton:
- <?xml version="1.0" encoding="utf-8"?>
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_checked="true" android:drawable="@color/colorPrimary"></item>//单选按钮被选中,背景颜色为蓝色
- <item android:state_checked="false" android:drawable="@color/colorAccent"></item>//为被选中,背景颜色为粉色
- </selector>
页面代码:
fragment_weixin.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical" android:layout_width="match_parent"
- android:layout_height="match_parent">
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="这是微信页面"
- android:textSize="40sp"
- />
- </LinearLayout>
fragment_contacts.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical" android:layout_width="match_parent"
- android:layout_height="match_parent">
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="这是通讯录页面"
- android:textSize="40sp"
- />
- </LinearLayout>
同样的页面,我们在写两个,在这里我就不再写了
接下来我们就是将页面转为Fragment了
WeiXinFragment.java
- package com.example.test0615;
- import android.os.Bundle;
- import android.support.annotation.Nullable;
- import android.support.v4.app.Fragment;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- /**
- * Created by Administrator on 2017/6/15 0015.
- */
- public class WeiXinFragment extends Fragment {
- @Nullable
- @Override
- public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_weixin,null);//方法的第一个参数为我们需要转化的页面
- }
- }
ContactsFragment.java
- package com.example.test0615;
- import android.os.Bundle;
- import android.support.annotation.Nullable;
- import android.support.v4.app.Fragment;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- /**
- * Created by Administrator on 2017/6/15 0015.
- */
- public class ContactsFragment extends Fragment {
- @Nullable
- @Override
- public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_contacts,null);
- }
- }
再建两个Java页面,将剩下的两个个页面转为Fragment
接下来就是代码的重中之重:
- package com.example.test0615;
- import android.support.annotation.IdRes;
- import android.support.v4.app.Fragment;
- import android.support.v4.app.FragmentManager;
- import android.support.v4.app.FragmentPagerAdapter;
- import android.support.v4.view.PagerAdapter;
- import android.support.v4.view.ViewPager;
- import android.support.v7.app.AppCompatActivity;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.RadioButton;
- import android.widget.RadioGroup;
- import java.util.ArrayList;
- import java.util.List;
- public class MainActivity extends AppCompatActivity {
- private ViewPager vp_main_viewpager;
- private RadioGroup rg_main_radio;
- //定义一个用来放Fragment的集合
- private List<Fragment> fragments=new ArrayList<>();
- //用来放View的集合
- private List<View> buttons;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- vp_main_viewpager = (ViewPager) findViewById(R.id.vp_main_viewpager);
- rg_main_radio = (RadioGroup) findViewById(R.id.rg_main_radio);
- WeiXinFragment weiXinFragment=new WeiXinFragment();
- ContactsFragment contactsFragment=new ContactsFragment();
- FindFragment findFragment=new FindFragment();
- MyFragment myFragment=new MyFragment();
- //将Fragment放入集合
- fragments.add(weiXinFragment);
- fragments.add(contactsFragment);
- fragments.add(findFragment);
- fragments.add(myFragment);
- //设置适配器
- vp_main_viewpager.setAdapter(new MyAdapter(getSupportFragmentManager()));
- //得到单选组的所有单选按钮
- buttons=rg_main_radio.getTouchables();
- //给页面设置一个监听事件
- vp_main_viewpager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- }
- //页面滑动事件
- @Override
- public void onPageSelected(int position) {
- //根据页面的位置拿到每个页面对应的单选按钮
- RadioButton radioButton= (RadioButton) buttons.get(position);
- //将该单选按钮设置为选中状态
- radioButton.setChecked(true);
- }
- @Override
- public void onPageScrollStateChanged(int state) {
- }
- });
- //给单选组设置点击事件监听
- rg_main_radio.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(RadioGroup group, @IdRes int checkedId) {
- //如果当前单选按钮的ID为自己设置的ID
- if(checkedId==R.id.rb_mian_one){
- //设置当前展示的页面
- vp_main_viewpager.setCurrentItem(0);
- }else if(checkedId==R.id.rb_mian_two){
- vp_main_viewpager.setCurrentItem(1);
- }else if(checkedId==R.id.rb_mian_three){
- vp_main_viewpager.setCurrentItem(2);
- }else if(checkedId==R.id.rb_mian_four){
- vp_main_viewpager.setCurrentItem(3);
- }
- }
- });
- }
- class MyAdapter extends FragmentPagerAdapter{
- public MyAdapter(FragmentManager fm) {
- super(fm);
- }
- @Override
- public Fragment getItem(int position) {
- return fragments.get(position);
- }
- @Override
- public int getCount() {
- return fragments.size();
- }
- }
- }
5.Fragment生命周期
Fragment生命周期图
测试代码:
- package com.goso.testapp;
- import android.app.Activity;
- import android.app.ListFragment;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.ArrayAdapter;
- import android.widget.ListView;
- /**
- * Demonstration of using ListFragment to show a list of items
- * from a canned array.
- */
- public class FragmentListArray extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- Log.e("HJJ", "Activity &&&& onCreate...");
- // Create the list fragment and add it as our sole content.
- if (getFragmentManager().findFragmentById(android.R.id.content) == null) {
- ArrayListFragment list = new ArrayListFragment();
- getFragmentManager().beginTransaction().add(android.R.id.content, list).commit();
- }
- }
- @Override
- protected void onStart() {
- // TODO Auto-generated method stub
- super.onStart();
- Log.e("HJJ", "Activity &&&& onStart...");
- }
- @Override
- protected void onResume() {
- // TODO Auto-generated method stub
- super.onResume();
- Log.e("HJJ", "Activity &&&& onResume...");
- }
- @Override
- protected void onStop() {
- // TODO Auto-generated method stub
- super.onStop();
- Log.e("HJJ", "Activity &&&& onStop...");
- }
- @Override
- protected void onPause() {
- // TODO Auto-generated method stub
- super.onPause();
- Log.e("HJJ", "Activity &&&& onPause...");
- }
- @Override
- protected void onDestroy() {
- // TODO Auto-generated method stub
- super.onDestroy();
- Log.e("HJJ", "Activity &&&& onDestroy...");
- }
- public static class ArrayListFragment extends ListFragment {
- @Override
- public void onAttach(Activity activity) {
- // TODO Auto-generated method stub
- Log.e("HJJ", "ArrayListFragment **** onAttach...");
- super.onAttach(activity);
- }
- @Override
- public void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- Log.e("HJJ", "ArrayListFragment **** onCreate...");
- super.onCreate(savedInstanceState);
- }
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- Log.e("HJJ", "ArrayListFragment **** onCreateView...");
- return super.onCreateView(inflater, container, savedInstanceState);
- }
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- Log.e("HJJ", "ArrayListFragment **** onActivityCreated...");
- String[] array = new String[]{"C++", "JAVA", "PYTHON"};
- setListAdapter(new ArrayAdapter<String>(getActivity(),
- android.R.layout.simple_list_item_1, array));
- }
- @Override
- public void onStart() {
- // TODO Auto-generated method stub
- Log.e("HJJ", "ArrayListFragment **** onStart...");
- super.onStart();
- }
- @Override
- public void onResume() {
- Log.e("HJJ", "ArrayListFragment **** onResume...");
- // TODO Auto-generated method stub
- super.onResume();
- }
- @Override
- public void onPause() {
- Log.e("HJJ", "ArrayListFragment **** onPause...");
- // TODO Auto-generated method stub
- super.onPause();
- }
- @Override
- public void onStop() {
- Log.e("HJJ", "ArrayListFragment **** onStop...");
- // TODO Auto-generated method stub
- super.onStop();
- }
- @Override
- public void onDestroyView() {
- Log.e("HJJ", "ArrayListFragment **** onDestroyView...");
- // TODO Auto-generated method stub
- super.onDestroyView();
- }
- @Override
- public void onDestroy() {
- // TODO Auto-generated method stub
- Log.e("HJJ", "ArrayListFragment **** onDestroy...");
- super.onDestroy();
- }
- @Override
- public void onDetach() {
- Log.e("HJJ", "ArrayListFragment **** onDetach...");
- // TODO Auto-generated method stub
- super.onDetach();
- }
- @Override
- public void onListItemClick(ListView l, View v, int position, long id) {
- Log.i("FragmentList", "Item clicked: " + id);
- }
- }
- }
五、结果
- onCreate过程
- 01-22 15:30:28.091: E/HJJ(10315): Activity &&&& onCreate...
- 01-22 15:30:28.091: E/HJJ(10315): ArrayListFragment **** onAttach...
- 01-22 15:30:28.091: E/HJJ(10315): ArrayListFragment **** onCreate...
- 01-22 15:30:28.115: E/HJJ(10315): ArrayListFragment **** onCreateView...
- 01-22 15:30:28.123: E/HJJ(10315): ArrayListFragment **** onActivityCreated...
- onStart过程
- 01-22 15:30:28.123: E/HJJ(10315): Activity &&&& onStart...
- 01-22 15:30:28.123: E/HJJ(10315): ArrayListFragment **** onStart...
- onResume过程
- 01-22 15:30:28.123: E/HJJ(10315): Activity &&&& onResume...
- 01-22 15:30:28.123: E/HJJ(10315): ArrayListFragment **** onResume...
- onPause过程
- 01-22 15:31:26.748: E/HJJ(10315): ArrayListFragment **** onPause...
- 01-22 15:31:26.748: E/HJJ(10315): Activity &&&& onPause...
- onStop过程
- 01-22 15:31:27.638: E/HJJ(10315): ArrayListFragment **** onStop...
- 01-22 15:31:27.638: E/HJJ(10315): Activity &&&& onStop...
- onStart过程
- 01-22 15:31:57.537: E/HJJ(10315): Activity &&&& onStart...
- 01-22 15:31:57.537: E/HJJ(10315): ArrayListFragment **** onStart...
- onResume过程
- 01-22 15:31:57.537: E/HJJ(10315): Activity &&&& onResume...
- 01-22 15:31:57.537: E/HJJ(10315): ArrayListFragment **** onResume...
- onPause过程
- 01-22 15:32:47.412: E/HJJ(10315): ArrayListFragment **** onPause...
- 01-22 15:32:47.412: E/HJJ(10315): Activity &&&& onPause...
- onStop过程
- 01-22 15:32:47.865: E/HJJ(10315): ArrayListFragment **** onStop...
- 01-22 15:32:47.865: E/HJJ(10315): Activity &&&& onStop...
- onDestroy过程
- 01-22 15:32:47.865: E/HJJ(10315): ArrayListFragment **** onDestroyView...
- 01-22 15:32:47.865: E/HJJ(10315): ArrayListFragment **** onDestroy...
- 01-22 15:32:47.865: E/HJJ(10315): ArrayListFragment **** onDetach...
- 01-22 15:32:47.865: E/HJJ(10315): Activity &&&& onDestroy...