Fragment的基本使用方法与通信
来源:互联网 发布:nginx http 307 编辑:程序博客网 时间:2024/05/20 18:16
Fragment的基本使用方法与通信
一、Fragment知识概要
1. Fragment可以作为Activity界面的一部分出现2. 可以在一个Activity中同时多个Fragment,并且一个Fragment也可以在多个Activity中使用3. 在Activity运行过程中可以添加、移除或替换Fragment4. Fragment可以相应自己的输入事件,并且有自己的生命周期并且它的生命周期受宿主Activity的影响
二、Fragment的静态加载
要导入v4的包以便向下兼容
import android.support.v4.app.Fragment;
在Activity的layout文件中声明Fragment,需要特别注意fragment标签中的android:name属性指定了在layout中实例化的Fragment类
缺点:布局写死了使用不灵活
(1) 定义一个布局并创建Fragment类(布局代码就不给出来了很简单一个TextView一个Button)
public class MyFragment extends Fragment { private String text1; public String getText1() { return text1; } public void setText1(String text1) { this.text1 = text1; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { /** * resource:Fragment需要加载的布局 * root:加载layout的父ViewGroup * attachToRoot:false不反回父ViewGroup */ View view = inflater.inflate(R.layout.fragment,container, false);//把layout布局文件转换成View对象 TextView textView = (TextView) view.findViewById(R.id.textView1); Button button = (Button) view.findViewById(R.id.button1); button.setText("获取内容"); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String value = getText1(); Toast.makeText(getActivity(), "value"+value, 0).show(); } }); return view; }
}
(2) 在布局文件中声明Fragment
<?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" > <fragment android:id="@+id/fragment" android:layout_width="wrap_content" android:layout_height="wrap_content" android:name="com.example.fragment.MyFragment" /></LinearLayout>
(3) 在Activity中使用该Fragment
public class MainActivity2 extends Activity { private TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main2);//已经加载fragment中的布局文件可以直接findViewById它里面的控件 Button button = (Button) findViewById(R.id.button1); tv = (TextView) findViewById(R.id.textView1); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { tv.setText("textview改变了!"); } }); }}
三、Fragment的动态加载
优点:运行时Activity允许动态的移除或者替换Fragment
Fragment事务:根据用户的交互情况,对Fragment进行添加、移除、替换、以及执行其他动作,提交给Activity的每一套变化被称作一个事务。每一个事务都是同时执行一套变化,可以在一个事务中设置你想执行的变化,包括add()、remove()、replace(),然后提交给Activity,必须调用commit()方法。如果允许用户通过back键退回到前一个Fragment状态,调用commit()之前可以加入addToBackStack()方法。
注意:Activity动态的添加Fragment必需有一个容器View来容纳Fragment的layout布局
创建两个Fragment类(如上所示就不给出示例代码了)接下来就可以在Fragment中动态加载了:
public class MainActivity3 extends Activity { private Button button; private Fragment fragment; private boolean flag = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main3); init(); button = (Button) findViewById(R.id.button); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { FragmentManager manager = getFragmentManager(); FragmentTransaction fragmentTransaction = manager.beginTransaction(); if (flag) { MyFragment4 fragment4 = new MyFragment4(); //containerViewId ,fragment fragmentTransaction.replace(R.id.layout, fragment4); flag = false; }else{ MyFragment3 fragment3 = new MyFragment3(); fragmentTransaction.replace(R.id.layout, fragment3); flag = true; } fragmentTransaction.commit(); } }); } public void init(){ FragmentManager manager = getFragmentManager(); FragmentTransaction fragmentTransaction = manager.beginTransaction(); MyFragment3 fragment3 = new MyFragment3(); fragmentTransaction.add(R.id.layout, fragment3); fragmentTransaction.commit(); }}
四、Fragment的通信
1.动态加载的Fragment通信
fragment之间永远不能通信都是通过他们所依附的Activity来通信的,通过接口回调的方式来通信
Activity--->Fragment:在activity中创建Bundle数据包,并调用fragment的setArguments(Bundle bundle)方法
fragment--->Activity:在fragment类中定义一个接口,并在他所属的activity中实现该接口,fragment在他的onAttach()方法执行期间捕获该接口的实现,然后就可以调用该接口方法,以便跟activity通信。
下面的代码实现了在一个Activity下有两个Fragment,在一个Fragment中输入值在另一个Fragment显示
public class MainActivity extends Activity implements MyListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FragmentManager manager = getFragmentManager(); FragmentTransaction fragmentTransaction = manager.beginTransaction(); Fragment1 fragment1 = new Fragment1(); fragmentTransaction.add(R.id.layout1, fragment1); fragmentTransaction.commit(); } //在mainActivity中实现MyListener接口并实现它未实现的方法,在该方法中传递数据 @Override public void send(String info) { Toast.makeText(this, "Activity成功接收" + info, 0).show(); Fragment2 fragment2 = new Fragment2(); Bundle bundle = new Bundle(); bundle.putString("name", info); fragment2.setArguments(bundle); FragmentManager manager = getFragmentManager(); FragmentTransaction fragmentTransaction = manager.beginTransaction(); //替换该Fragment fragmentTransaction.replace(R.id.layout2, fragment2, "fragment2"); fragmentTransaction.commit(); }}
上面的MainActivity布局就是添加两个Linearlayout,下面是创建两个Fragment,Fragment1的布局就是一个EditText一个Button,Fragment2的布局就是一个TextView。
public class Fragment1 extends Fragment { EditText et; Button enter; private String info; @Override public void onAttach(Activity activity) { listener = (MyListener) activity; super.onAttach(activity); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment1_lay,container, false); et = (EditText) view.findViewById(R.id.et); enter = (Button) view.findViewById(R.id.enter); enter.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { info = et.getText().toString(); listener.send(info); } }); return view; } public MyListener listener; //定义一个接口 public interface MyListener{ public void send(String info); }}
public class Fragment2 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment2_lay,container, false); TextView tv = (TextView) view.findViewById(R.id.tv); tv.setText(getArguments().get("name")+"");//获取传递的值 Toast.makeText(getActivity(), "fragment"+getArguments().get("name")+"", 0).show(); return view; }}
2.静态加载的fragment通信
- fragment可以调用getActivity()方法获取他所在的Activity
- Activity可以调用FragmentManager的findFragmentById()或findFragmentByTag()方法获取Fragment
如果是静态加载的Fragmentn那么向Activity传递数据就很简单了,在MainActivity的onCreate方法中:
FragmentManager fragmentManager = getFragmentManager(); Fragment fragment = fragmentManager.findFragmentById(R.id.frag);//静态加载在Activity布局中设置的Fragment的ID MyFragment frag = (MyFragment) fragment; frag.setText1("fragment静态传值");
在Fragment类中设置它的get、set方法,
private String text1; public String getText1() { return text1; } public void setText1(String text1) { this.text1 = text1; }
下面直接调用就可以了:
String value = getText1();
****纠正对Fragment Transaction BackStack的误解
目前在开发APP时,Fragment已经被开发者广泛使用,但Fragment的BackStack却被很多开发者误解。所以这篇博客就讨论下Fragment的BackStack及一些相关的常用接口。首先需要明确的是,FragmentActivity的FragmentManager是处理Fragment Transaction的而不是处理Fragment。BackStack内部的一个Transaction可以包含一个或多个和Fragment相关的操作。
上面的一个FragmentTransaction既包含add操作又包含replace操作。
- FragmentTransaction ft = getFragmentManager().beginTransaction();
- ft.add(restId, fragmentA);
- ft.replace(fragmentB);
- ft.commit();
FragmentTransaction默认并不会主动被加入到BackStack中,除非开发者调用了addToBackStack(String tag)方法。参数'tag'将作为本次加入BackStack的Transaction的标志。
- FragmentTransaction ft = getFragmentManager().beginTransaction();
- ft.add(resId, fragmentA);
- ft.replace(resId, fragmentB);
- ft.addToBackstack("tag");
- ft.commit();
和addToBackStack相对应的接口方法是popBackStack(),调用该方法后会将事物操作插入到FragmentManager的操作队列,只有当轮询到该事物时才能执行。所以Google还提供了可以立刻执行的接口
- popBackStackImmediate()
下面举例说明Transaction BackStack的进栈和出栈。
如下图,使用FragmentActivity的FragmentManager创建Trasaction1并提交,使页面显示AFragment。这时调用popBackStack()就会移除AFragment并返回FragmentActivity。
- @Override
- public void addFragment(BaseFragment baseFragment) {
- FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
- ft.replace(R.id.home_frame_layout_for_fragments, baseFragment, baseFragment.getTagText());
- ft.addToBackStack(baseFragment.getTagText());
- ft.commit();
- }
在AFragment已经在栈顶的情况下,我们再创建Transation2并提交,Transaction 2添加了两个Fragment,提交后页面显示的是CFragment,这时调用popBackStack()就会将Transaction2从BackStack移除,即将CFragment和BFragment同时移除,页面将显示AFragment。
参考资料:
- @Override
- public void addMultipleFragments(BaseFragment[] baseFragments) {
- FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
- for(int i = 0 ; i < baseFragments.length ; i++) {
- ft.replace(R.id.home_frame_layout_for_fragments, baseFragments[i], baseFragments[i].getTagText());
- }
- ft.addToBackStack(baseFragments[0].getTagText());
- ft.commit();
- }
Transaction BackStack and its management
- Fragment的基本使用方法与通信
- Fragment基本使用方法和与activity的通信
- Fragment的基本使用方法
- ViewPager与Fragment组合时的基本使用方法
- Fragment与Fragment之间的通信
- Fragment 与Fragment之间的通信
- Fragment与Fragment的通信交互Demo
- Fragment与Fragment之间的通信
- Fragment与Fragment之间的通信
- Fragment与Activity的通信:
- Fragment与Activity的通信
- Fragment与Activity的通信
- Activity与Fragment,Fragment与Fragment之间的通信
- ViewPager+Fragment基本使用方法
- ViewPager+Fragment基本使用方法
- Fragment—基本使用方法
- Fragment与Activity之前的通信已经Fragment的生命周期
- fragment的实现与互相通信
- translate xml参数讲解
- 黑马程序员--Java编程之常见对象
- Facebook开源《AsyncDisplayKit介绍》翻译
- [数据结构]双机调度问题
- vi编辑器技巧总结(更新中)
- Fragment的基本使用方法与通信
- Socket
- android设备终端与蓝牙模块(HC-06)的通讯编程思路
- iOS9模拟器无法进行HTTP网络请求的解决方案
- android - Notifications
- Android进阶之Service远程通信AIDL
- ros由indigo版本升级至jade版本的烦恼
- iOS集成支付宝
- #学习笔记#(13)仿 kugou-logo-phptoshop