Fragment
简介
Fragment即碎片,是一种可以嵌入活动当中的UI片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用的非常广泛。它和活动很像,同样能包含布局,同样拥有自己的生命周期。碎片的出现就是让一个应用可以同时适应手机和平板。
Fragment的生命周期
它与Activity生命周期的关系:
活动有的回调方法,碎片中几乎都有,不过碎片还提供了一些附加的回调方法。
1. onAttach(Activity)
当Fragment与Activity发生关联时调用。
2. onCreateView(LayoutInflater, ViewGroup,Bundle)
创建该Fragment的视图(加载布局)
3. onActivityCreated(Bundle)
当Activity的onCreate方法返回时调用
4. onDestoryView()
与onCreateView想对应,当该Fragment的视图被移除时调用
5. onDetach()
与onAttach相对应,当Fragment与Activity关联被取消时调用
静态使用Fragment
比如我们想要在一个活动中添加3个碎片,
1. 为每个碎片写一个布局,然后新建一个类继承Fragment,重写onCreateView()方法,加载各自的布局。
2. 在activity_main.xml中声明3个碎片,与声明一般的view一样。
<fragment
android:id="@+id/fragment1" android:name="com.example.administrator.myfragment.Fragment1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
注意:我们使用<fragment>
标签在布局中添加碎片,要通过android:name属性或者class属性显式指明要添加碎片的类名,而且一定要将类的包名也加上。
动态使用Fragment
- 创建待添加的碎片实例。
- 获取到FragmentManager,在活动中可以直接调用getFragmentManager()方法得到。
- 开启一个事务,通过调用beginTransaction()方法开启。
- 向容器内加入碎片,一般使用replace()方法实现,需要传入容器布局的id和待添加碎片的实例。
- 提交事务,调用commit()方法来完成。
首先我们要修改activity_main.xml中的内容,我们使用一个FramLayout布局,下边再加上一组RadioButton
<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">
<FrameLayout
android:id="@+id/framelayout"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>
<RadioGroup
android:id="@+id/radiogroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:background="#55000000">
<RadioButton
android:id="@+id/radiobutton1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:button="@null"
android:drawableTop="@drawable/conversation"
android:background="@null"/>
<RadioButton
android:id="@+id/radiobutton2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:button="@null"
android:drawableTop="@drawable/contact"
android:background="@null"/>
<RadioButton
android:id="@+id/radiobutton3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:button="@null"
android:drawableTop="@drawable/plugin"
android:background="@null"/>
</RadioGroup>
</RelativeLayout>
在上边RadioButton中,我们模仿QQ下边界面做了一个点击切换的效果。具体方法和前边将RaidoButton的内容一样。这里就一个写下代码,我们在drawable文件下新建xml文件
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/skin_tab_icon_contact_selected" android:state_checked="true"/>
<item android:drawable="@mipmap/skin_tab_icon_contact_normal"/>
</selector>
3个碎片的布局和继承于Fragment的类这里不再贴出代码,内容是第一个碎片放一个Button,第二个碎片放了一个TextView,第三个碎片中放了一个EditText。
下面是MainActivity.java
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.widget.RadioGroup;
public class MainActivity extends FragmentActivity{
private RadioGroup radioGroup;
private FragmentManager fragmentManager;
private FragmentTransaction fragmentTransaction;
private MyFragment1 myFragment1;
private MyFragment2 myFragment2;
private MyFragment3 myFragment3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
radioGroup= (RadioGroup) findViewById(R.id.radiogroup);
//初始化碎片
myFragment1=new MyFragment1();
myFragment2=new MyFragment2();
myFragment3=new MyFragment3();
fragmentManager=getSupportFragmentManager();
// 开启Fragment事务
//这里下面需要两个碎片进行数据交互,不能用replace()方法添加
fragmentTransaction=fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.framelayout,myFragment1);
fragmentTransaction.add(R.id.framelayout,myFragment2);
fragmentTransaction.add(R.id.framelayout,myFragment3);
fragmentTransaction.hide(myFragment1);
fragmentTransaction.hide(myFragment2);
fragmentTransaction.hide(myFragment3);
//提交事务
fragmentTransaction.commit();
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
fragmentTransaction=fragmentManager.beginTransaction();
switch (checkedId){
case R.id.radiobutton1:
fragmentTransaction.show(myFragment1);
fragmentTransaction.hide(myFragment2);
fragmentTransaction.hide(myFragment3);
break;
case R.id.radiobutton2:
fragmentTransaction.hide(myFragment1);
fragmentTransaction.show(myFragment2);
fragmentTransaction.hide(myFragment3);
String text=myFragment3.getText();
myFragment2.setTextView(text);
break;
case R.id.radiobutton3:
fragmentTransaction.hide(myFragment1);
fragmentTransaction.hide(myFragment2);
fragmentTransaction.show(myFragment3);
break;
default:
break;
}
fragmentTransaction.commit();
}
});
radioGroup.check(R.id.radiobutton1);
}
}
注意:这里MainActicity继承了FragmentActivity,是为了兼容2.3及以下版本,在获得FragmentManager实例时调用了getSupportFragmentManager()方法。如果继承Activity,那么只适用于4.0机以上版本,在获得FragmentManager实例时要调用getFragmentManager()方法。
在碎片中模拟返回栈
这里我们在事务提交之前调用FragmentTransaction的addToBackStack()方法,它可以在接收一个名字用于描述返回栈的状态,一般传入null即可。运行程序后,按下Back键后不会退出程序,而是返回上一个碎片界面。
在Viewpager中放入碎片
因为我们要在ViewPager中放入Fragment,首先要自定义Viewpager的适配器时要继承于FragmentPagerAdapter
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import java.util.ArrayList;
/**
* Created by Administrator on 2015/9/7.
*/
public class MyFragmentAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> fragments;
public MyFragmentAdapter(FragmentManager fm,ArrayList<Fragment> fragments) {
super(fm);
this.fragments=fragments;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
}
然后修改activity_main.xml中的内容,将上边加入的Framlayout换成Viewpager。
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
></android.support.v4.view.ViewPager>
最后修改MainActivity中的内容
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.widget.RadioGroup;
import com.example.administrator.myfragment.Adapter.MyFragmentAdapter;
import java.util.ArrayList;
/**
* Created by Administrator on 2015/9/7.
*/
public class MainActivity extends FragmentActivity {
private RadioGroup radioGroup;
private FragmentManager fragmentManager;
private MyFragment1 myFragment1;
private MyFragment2 myFragment2;
private MyFragment3 myFragment3;
private ViewPager viewPager;
private MyFragmentAdapter myFragmentAdapter;
private ArrayList<Fragment> fragments;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
radioGroup= (RadioGroup) findViewById(R.id.radiogroup);
viewPager= (ViewPager) findViewById(R.id.viewpager);
myFragment1=new MyFragment1();
myFragment2=new MyFragment2();
myFragment3=new MyFragment3();
fragments=new ArrayList<>();
fragments.add(myFragment1);
fragments.add(myFragment2);
fragments.add(myFragment3);
fragmentManager=getSupportFragmentManager();
myFragmentAdapter=new MyFragmentAdapter(fragmentManager,fragments);
viewPager.setAdapter(myFragmentAdapter);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId){
case R.id.radiobutton1:
viewPager.setCurrentItem(0);
break;
case R.id.radiobutton2:
viewPager.setCurrentItem(1);
String text=myFragment3.getText();
myFragment2.setTextView(text);
break;
case R.id.radiobutton3:
viewPager.setCurrentItem(2);
break;
default:
break;
}
}
});
radioGroup.check(R.id.radiobutton1);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
switch (position){
case 0:
radioGroup.check(R.id.radiobutton1);
break;
case 1:
radioGroup.check(R.id.radiobutton2);
break;
case 2:
radioGroup.check(R.id.radiobutton3);
break;
default:
break;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
}
运行结果:实现了滑动切换碎片,也可以点击切换碎片。