Fragment是什么?
Fragment(片段,碎片),正如其翻译那样,它在一个activity里面表示一个行为或者用户接口的一部分(碎片表示轻量级和灵活)。我们可以将不同的Fragments组合起来放到一个activity中,或者在不同的activity中重用一个fragment。你可以将一个fragment看成是一个activity中的一个片段,它有自己的生命周期(如何从创建到销毁),接受它自己的输入事件,并且可以在activity运行时动态的添加或者移除一个fragment(类似一个可以在不同的activity中重用的子activity)。
Fragment静态用法
把Fragment当成普通的控件,直接写在Activity的布局文件中。
要导入v4的包以便兼容
import android.support.v4.app.Fragment
实现代码如下:
Activity代码:
<?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:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.androidthree.Main3Activity">
<fragment
android:id="@+id/blank_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.androidthree.fragment.BlankFragment"
></fragment>
</LinearLayout>
Fragment代码:
<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="#0ff"
tools:context="com.example.androidthree.fragment.BlankFragment">
<!-- 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来通信的,通过接口回调的方式来通信
Activity—>Fragment:在activity中创建Bundle数据包,并调用fragment的setArguments(Bundle bundle)方法
fragment—>Activity:在fragment类中定义一个接口,并在他所属的activity中实现该接口,fragment在他的onAttach()方法执行期间捕获该接口的实现,然后就可以调用该接口方法,以便跟activity通信。
实现代码如下:
Activity:
<?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:layout_height="match_parent"
android:orientation="horizontal"
tools:context="com.example.androidthree.Main3Activity">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn1_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="红色"/>
<Button
android:id="@+id/btn2_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="蓝色"/>
</LinearLayout>
<FrameLayout
android:id="@+id/main3_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
效果如图:
Java代码:
package com.example.androidthree;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.example.androidthree.fragment.BlueFragment2;
import com.example.androidthree.fragment.RedFragment2;
public class Main3Activity extends AppCompatActivity implements View.OnClickListener{
private Button btn1_fragment,btn2_fragment;
private RedFragment2 redFragment2;
private BlueFragment2 blueFragment2;
private FragmentManager fragmentManager;
private FragmentTransaction fragmentTransaction;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
btn1_fragment=findViewById(R.id.btn1_fragment);
btn1_fragment.setOnClickListener(this);
btn2_fragment=findViewById(R.id.btn2_fragment);
btn2_fragment.setOnClickListener(this);
fragmentManager=getFragmentManager();
fragmentTransaction=fragmentManager.beginTransaction();
redFragment2=new RedFragment2();
blueFragment2=new BlueFragment2();
}
@Override
public void onClick(View view) {
fragmentTransaction=fragmentManager.beginTransaction();
switch (view.getId()){
case R.id.btn1_fragment:
if (redFragment2==null){
redFragment2=new RedFragment2();
}
fragmentTransaction.replace(R.id.main3_frame,redFragment2);
break;
case R.id.btn2_fragment:
if (blueFragment2==null){
blueFragment2=new BlueFragment2();
}
fragmentTransaction.replace(R.id.main3_frame,blueFragment2);
break;
default:
break;
}
fragmentTransaction.commit();
}
}
效果如图:
ViewPage+Fragment实现页面切换
实现代码如下:
Activity:
<?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:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.androidthree.Main2Activity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="@+id/main2_tv1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="第一"
android:textSize="25dp"
android:gravity="center"/>
<TextView
android:id="@+id/main2_tv2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="第二"
android:textSize="25dp"
android:gravity="center"/>
<TextView
android:id="@+id/main2_tv3"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="第三"
android:textSize="25dp"
android:gravity="center"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="2dp"
android:orientation="horizontal">
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#1d1dc7"
android:id="@+id/view_one"
></View>
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#1d1dc7"
android:id="@+id/view_two"
></View>
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#1d1dc7"
android:id="@+id/view_three"
></View>
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="@+id/main2_vp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="7"
>
</android.support.v4.view.ViewPager>
</LinearLayout>
Adapter:
package com.example.androidthree.adapter;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.widget.BaseAdapter;
import java.util.List;
/**
* Created by lenovo on 2018/6/5.
*/
public class Main2Adapter extends FragmentPagerAdapter {
private List<Fragment> fragmentList;
public Main2Adapter(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();
}
}
Java:
package com.example.androidthree;
import android.graphics.Color;
import android.support.v4.app.Fragment;
import android.support.v4.app.ListFragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import com.example.androidthree.adapter.Main2Adapter;
import com.example.androidthree.fragment.BlankFragment;
import com.example.androidthree.fragment.HolleFragment;
import com.example.androidthree.fragment.RaidFragment;
import java.util.ArrayList;
import java.util.List;
public class Main2Activity extends AppCompatActivity implements View.OnClickListener{
private ViewPager main2_vp;
private View view_one,view_two,view_three;
private TextView main2_t1,main2_t2,main2_t3;
private HolleFragment holleFragment;
private RaidFragment raidFragment;
private BlankFragment blankFragment;
private List<Fragment> fragmentList=new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
bindID();
//初始虚线颜色
view_one.setBackgroundColor(Color.RED);
holleFragment=new HolleFragment();
raidFragment=new RaidFragment();
blankFragment=new BlankFragment();
fragmentList.add(holleFragment);
fragmentList.add(raidFragment);
fragmentList.add(blankFragment);
Main2Adapter main2Adapter=new Main2Adapter(getSupportFragmentManager(),fragmentList);
main2_vp.setAdapter(main2Adapter);
main2_vp.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
view_one.setBackgroundColor(Color.BLUE);
view_two.setBackgroundColor(Color.BLUE);
view_three.setBackgroundColor(Color.BLUE);
switch (position){
case 0:
view_one.setBackgroundColor(Color.RED);
break;
case 1:
view_two.setBackgroundColor(Color.RED);
break;
case 2:
view_three.setBackgroundColor(Color.RED);
break;
default:
break;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
private void bindID() {
main2_vp=findViewById(R.id.main2_vp);
view_one=findViewById(R.id.view_one);
view_two=findViewById(R.id.view_two);
view_three=findViewById(R.id.view_three);
main2_t1=findViewById(R.id.main2_tv1);
main2_t2=findViewById(R.id.main2_tv2);
main2_t3=findViewById(R.id.main2_tv3);
main2_t1.setOnClickListener(this);
main2_t2.setOnClickListener(this);
main2_t3.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.main2_tv1:
main2_vp.setCurrentItem(0);
break;
case R.id.main2_tv2:
main2_vp.setCurrentItem(1);
break;
case R.id.main2_tv3:
main2_vp.setCurrentItem(2);
break;
default:
break;
}
}
}
效果如图:
Fragment生命周期
生命周期图
onAttach():执行该方法时,Fragment与Activity已经完成绑定,该方法有一个Activity类型的参数,代表绑定的Activity,这时候你可以执行诸如mActivity = activity的操作。
onCreate():初始化Fragment。可通过参数savedInstanceState获取之前保存的值。
onCreateView():初始化Fragment的布局。加载布局和findViewById的操作通常在此函数内完成,但是不建议执行耗时的操作,比如读取数据库数据列表。
onActivityCreated():执行该方法时,与Fragment绑定的Activity的onCreate方法已经执行完成并返回,在该方法内可以进行与Activity交互的UI操作,所以在该方法之前Activity的nCreate方法并未执行完成,如果提前进行交互操作,会引发空指针异常。
onStart():执行该方法时,Fragment由不可见变为可见状态。
onResume():执行该方法时,Fragment处于活动状态,用户可与之交互。
onPause():执行该方法时,Fragment处于暂停状态,但依然可见,用户不能与之交互。
onSaveInstanceState():保存当前Fragment的状态。该方法会自动保存Fragment的状态,比如EditText键入的文本,即使Fragment被回收又重新创建,一样能恢复EditText之前键入的文本。
onStop():执行该方法时,Fragment完全不可见。
onDestroyView():销毁与Fragment有关的视图,但未与Activity解除绑定,依然可以通过onCreateView方法重新创建视图。通常在ViewPager+Fragment的方式下会调用此方法。
onDestroy():销毁Fragment。通常按Back键退出或者Fragment被回收时调用此方法。
onDetach():解除与Activity的绑定。在onDestroy方法之后调用。
Fragment通信
所谓Fragment通信,就是将Activity中的值传入Fragment里。同理,也能将Fragment里的值传入Activity中。
首先来说说如何将Activity中的值传入Fragment里:
1.将你要传的值存入Bundle中,代码如下:
Bundle bundle=new Bundle();
bundle.putString("name","张三");
blankFragment.setArguments(bundle);
2.在Fragment中获取存入Bundle的值,再传入Fragment的控件中实现。代码如下:
Bundle bundle=getArguments();
String name=bundle.getString("name");
btn_blank.setText(name);
效果如图:
那么将Fragment里的值传入Activity中是如何实现的呢。
1.首先要获取Fragment中你的控件的id,代码如下:
View view=inflater.inflate(R.layout.fragment_holle, container, false);
btn_friend=view.findViewById(R.id.btn_friend);
return view;
2.将你想要传入Activity的值,通过一个单击事件来实现,代码如下:
btn_friend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Main2Activity main2Activity= (Main2Activity) getActivity();
main2Activity.nodify("Hello");
}
});
3在Java代码中新建一个nodify方法来接收Fragment传入的值,代码如下:
public void nodify(String title){
main2_tv.setText(title);
}
效果如图: