Fragment
- Fragment是什么
- Fragment静态加载怎么用
- Fragment动态加载怎么用
- ViewPager+Fragment实现页卡滑动
- Fragment生命周期
- Fragment通信
Fragment是什么
Fragment中文为“碎片”,它可以表示Activity中的行为或用户界面部分。我们可以在一个Activity中用多个Fragment组合来构建多窗格的UI,以及在多个Activity中重复使用某个Fragment。简单来说,Fragment可以理解为一个有生命周期的控件,有自己的处理输入事件能力和生命周期,且需依赖于Activity。
Fragment生命周期
如何用代码表现Fragment的生命周期:
public class Fragment1 extends Fragment {
public static final String TAG = "Fragment1";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG, "onCreateView");
return inflater.inflate(R.layout.fragment1, container, false);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.d(TAG, "onAttach");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d(TAG, "onActivityCreated");
}
@Override
public void onStart() {
super.onStart();
Log.d(TAG, "onStart");
}
@Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume");
}
@Override
public void onPause() {
super.onPause();
Log.d(TAG, "onPause");
}
@Override
public void onStop() {
super.onStop();
Log.d(TAG, "onStop");
}
@Override
public void onDestroyView() {
super.onDestroyView();
Log.d(TAG, "onDestroyView");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
}
@Override
public void onDetach() {
super.onDetach();
Log.d(TAG, "onDetach");
}
}
可以看到Fragment比Activity多了几个额外的生命周期回调方法:
onAttach(Activity)
当Fragment与Activity发生关联时调用。
onCreateView(LayoutInflater, ViewGroup,Bundle)
创建该Fragment的视图
onActivityCreated(Bundle)
当Activity的onCreate方法返回时调用
onDestoryView()
与onCreateView想对应,当该Fragment的视图被移除时调用
onDetach()
与onAttach相对应,当Fragment与Activity关联被取消时调用
注意:除了onCreateView,其他的所有方法如果你重写了,必须调用父类对于该方法的实现
Fragment静态加载
1、继承Fragment,重写onCreateView决定Fragemnt的布局
2、在Activity中声明此Fragment,就当和普通的View一样
布局文件:fragment1.xml
<FrameLayout 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:background="#18e780"
tools:context=".BlankFragment">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>
第二个布局文件:fragment2.xml
<FrameLayout 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:background="#c7d188dd"
tools:context=".BlankFragment2">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>
然后新建一个类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);
}
}
Fragment2同理,然后打开或新建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);
}
}
Fragment动态加载
我们可以在静态的基础上进行修改:打开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方法提交。
ViewPager+Fragment实现页卡滑动
布局文件:
<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:layout_height="match_parent"
android:orientation="vertical"
tools:context=".VPActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_1"
android:layout_weight="1"
android:text="联系人"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="30dp" />
<TextView
android:id="@+id/tv_2"
android:layout_weight="1"
android:text="联系人"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="30dp" />
<TextView
android:id="@+id/tv_3"
android:layout_weight="1"
android:text="朋友圈"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="30dp" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="@+id/view_1"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="2dp">
</View>
<View
android:id="@+id/view_2"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="2dp">
</View>
<View
android:id="@+id/view_3"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="2dp">
</View>
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="@+id/main_vp"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.support.v4.view.ViewPager>
</LinearLayout>
java:
public class VPActivity extends AppCompatActivity implements ViewPager.OnClickListener{
private ViewPager viewPager;
private BlankFragment blankFragment;
private BlankFragment2 blankFragment2;
private BlankFragment3 blankFragment3;
private View view1,view2,view3;
private TextView tv1,tv2,tv3;
private List<Fragment> fragmentList=new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_vp);
viewPager=findViewById(R.id.main_vp);
tv1=findViewById(R.id.tv_1);
tv2=findViewById(R.id.tv_2);
tv3=findViewById(R.id.tv_3);
tv1.setOnClickListener(this);
tv2.setOnClickListener(this);
tv3.setOnClickListener(this);
view1=findViewById(R.id.view_1);
view2=findViewById(R.id.view_2);
view3=findViewById(R.id.view_3);
blankFragment=new BlankFragment();
blankFragment2=new BlankFragment2();
blankFragment3=new BlankFragment3();
fragmentList.add(blankFragment);
fragmentList.add(blankFragment2);
fragmentList.add(blankFragment3);
view1.setBackgroundColor(Color.BLUE);
tv1.setTextColor(Color.BLUE);
MyPagerAdapter adapter=new MyPagerAdapter(getSupportFragmentManager(),fragmentList);
viewPager.setAdapter(adapter);
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
view1.setBackgroundColor(Color.GRAY);
view2.setBackgroundColor(Color.GRAY);
view3.setBackgroundColor(Color.GRAY);
tv1.setTextColor(Color.GRAY);
tv2.setTextColor(Color.GRAY);
tv3.setTextColor(Color.GRAY);
switch (position){
case 0:
view1.setBackgroundColor(Color.BLUE);
tv1.setTextColor(Color.BLUE);
break;
case 1:
view2.setBackgroundColor(Color.BLUE);
tv2.setTextColor(Color.BLUE);
break;
case 2:
view3.setBackgroundColor(Color.BLUE);
tv3.setTextColor(Color.BLUE);
default:
break;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.tv_1:
viewPager.setCurrentItem(0);
break;
case R.id.tv_2:
viewPager.setCurrentItem(1);
break;
case R.id.tv_3:
viewPager.setCurrentItem(2);
break;
}
}
}
适配器:
public class MyPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragmentList;
public MyPagerAdapter(FragmentManager fm, List<Fragment> fragmentList) {
super(fm);
this.fragmentList=fragmentList;
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
}
三个fragment.xml:
(1)
<FrameLayout 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:background="#18e780"
tools:context=".BlankFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>
(2)
<FrameLayout 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:background="#c7d188dd"
tools:context=".BlankFragment2">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>
(3)
<FrameLayout 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=".BlankFragment3"
android:background="#1bb6c1">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>
Fragment的通信
Fragment之间的桥梁Activity:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//[1]获取Fragment的管理者
FragmentManager fragmentManager = getFragmentManager();
//[2]开启事物
FragmentTransaction transaction = fragmentManager.beginTransaction();
//[3]动态替换
transaction.replace(R.id.ll1, new Fragment1(),"f1");
transaction.replace(R.id.ll2, new Fragment2(),"f2");
//[4]最后一步 记得commit
transaction.commit();
}
}
Fragment:
public class Fragment1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment1, null);
//[1]找到按钮设置点击事件
view.findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getActivity(), "jagjajgl", 1).show();
//[2]修改Fragment2里面textview的值
Fragment2 f2 = (Fragment2) getActivity().getFragmentManager().findFragmentByTag("f2");
f2.setText("haahha");
}
});
return view;
}
}
public class Fragment2 extends Fragment {
private TextView tView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment2, null);
tView = (TextView) view.findViewById(R.id.tv);
return view;
}
//修改textview值的方法
public void setText(String content){
tView.setText(content);
}
}