Fragment 详解二
来源:互联网 发布:php实现pdf在线阅读 编辑:程序博客网 时间:2024/06/01 08:00
本篇讲的是Fragment数据的传递、onBackPress()的拦截、replace的坑
一. setArguments 传递
特点,第一次初始化的时候使用。 google官方推荐,值得拥有。先看下如何使用的, 下面为创建的FragmentTwo
package com.example.stormxz.fragmenttwo;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;import android.widget.TextView;/** * Created by stormxz on 2017/9/5. */public class FragmentTwo extends Fragment { private TextView textView = null; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_second, container, false); textView = view.findViewById(R.id.second_text); String text = getArguments().getString("stormxz"); //通过key,将数据取出,并使用 textView.setText(text); return view; } public static FragmentTwo newInstance(String text){ FragmentTwo fragmentTwo = new FragmentTwo(); Bundle bundle = new Bundle(); //通过bundle进行数据的存储 bundle.putString("stormxz", text); fragmentTwo.setArguments(bundle); return fragmentTwo; }}
MainActivity.java FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTwo fragmentTwo = FragmentTwo.newInstance(text); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(R.id.frame, fragmentTwo); fragmentTransaction.commit();
疑问?为什么不直接使用FragmentTwo的构造方法进行数据传递呢?
正解:
当FragmentTwo 在旋转屏时,构造方法传递过来的数据不能保持,而setArguments的数据可以保持
跟着源码走:
1. FragmentActivity.java onCreate()中 会对fragment进行重新创建
mFragments.restoreAllState(p, nc != null ? nc.fragments : null);
2. FragmentController.java restoreAllState过度一下
public void restoreAllState(Parcelable state, FragmentManagerNonConfig nonConfig) {
mHost.mFragmentManager.restoreAllState(state, nonConfig);
}
3. FragmentManager.java restoreAllState Fragment的创建
Fragment f = fs.instantiate(mHost, mContainer, mParent, childNonConfig);
4. FragmentState.java
FragmentState 的构造方法获得之前的bundle
mArguments = in.readBundle();
instantiate
mInstance = Fragment.instantiate(context, mClassName, mArguments);
5. Fragment.java
public static Fragment instantiate(Context context, String fname, @Nullable Bundle args) { try { Class<?> clazz = sClassMap.get(fname); if (clazz == null) { // Class not found in the cache, see if it's real, and try to add it clazz = context.getClassLoader().loadClass(fname); sClassMap.put(fname, clazz); } Fragment f = (Fragment)clazz.newInstance(); if (args != null) { args.setClassLoader(f.getClass().getClassLoader()); f.setArguments(args); //将对应的bundle设置到fragment中,待getArguments } return f; } }
二、 同一个Activity,不同容器
1. 在Activity中,通过findViewById,获得控件实例,再操作2. 在Fragment中onActivityCreated中,通过getActivity().findViewById() 获得控件实例,再进行操作
3. 在各自fragment中使用,通过回调实现
思路: 在FragmentFirst中创建回调接口以及方法, 在fragmentFirst中调用; Activity 实现该接口,和方法,并进行其他操作即可
比如下面FragmentFirst:
package com.example.stormxz.fragmenttwo;import android.app.Activity;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;import android.widget.Button;import android.widget.EditText;/** * Created by stormxz on 2017/9/5. */public class FragmentFirst extends Fragment { private TextCallBack textCallBack = null; private Button button = null; private EditText editText = null; public interface TextCallBack{ //创建的接口,和方法 public void textCallBack(String text); } @Override public void onAttach(Activity activity) { super.onAttach(activity); textCallBack = (TextCallBack) activity; //初始化textCallBack实例 } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_first, container, false); button = view.findViewById(R.id.button); editText = view.findViewById(R.id.first_text); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { textCallBack.textCallBack(editText.getText().toString()); //调用该方法,此时会在实现该接口的地方调用 } }); return view; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); }}
MainActivity.java
package com.example.stormxz.fragmenttwo;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentTransaction;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;/** * Created by stormxz on 2017/9/5. */ //实现FragmentFirst中的接口public class MainActivity extends AppCompatActivity implements FragmentFirst.TextCallBack{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FragmentManager fragmentManager = getSupportFragmentManager(); FragmentFirst fragmentFirst = new FragmentFirst(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(R.id.frame, fragmentFirst, "first"); fragmentTransaction.commit(); }//重写该方法,并处理相关事件。当FragmentFirst中调用textCallBack时,触发该方法。 对应的FragmentTwo和第一个一样,此时不写了。 @Override public void textCallBack(String text) { if (text != null) { FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTwo fragmentTwo = FragmentTwo.newInstance(text); Fragment fragmentFirst = fragmentManager.findFragmentByTag("first"); //通过tag,取出栈中的FragmentFirst FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); if (fragmentFirst != null){ fragmentTransaction.hide(fragmentFirst); //隐藏了FragmentFirst } fragmentTransaction.add(R.id.frame1, fragmentTwo); fragmentTransaction.commit(); } }}
三、 如何拦截fragment的回退事件
fragment 本身就是一个控件,没有拦截onBackPress事件的功能。可以通过Activity的onBackPress事件进行调用fragment的自己写的onBackPress().这里需将fragment的实例传递出去,或者在外部创建fragment实例都行。
FragmentThird.java中的操作
package com.example.stormxz.fragmenttwo;import android.app.Activity;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;import android.widget.TextView;/** * Created by stormxz on 2017/9/12. */public class FragmentThrid extends Fragment { private TextView textView = null; private MyInstance myInstance = null; public interface MyInstance{ //自定义接口和方法 public void setFragmentThird(FragmentThrid fragmentThird); } @Override public void onAttach(Activity activity) { super.onAttach(activity); myInstance = (MyInstance) activity; } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_third, container, false); return view; } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); textView = view.findViewById(R.id.thrid_text); textView.setText("i am third fragment"); } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); myInstance.setFragmentThird(this); //将对象传递出去 } public boolean onBackPress(){ textView.setText("就不给你退"); return false; }}
MainActivity.java 中的操作
package com.example.stormxz.fragmenttwo;import android.os.Bundle;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentTransaction;import android.support.v7.app.AppCompatActivity;/** * Created by stormxz on 2017/9/12. */public class MainThridFragment extends AppCompatActivity implements FragmentThrid.MyInstance{ private FragmentThrid fragmentThridd = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FragmentManager fragmentManager = getSupportFragmentManager(); FragmentThrid fragmentThrid = new FragmentThrid(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(R.id.frame, fragmentThrid, "third"); fragmentTransaction.commit(); } //获得Fragmen对象 @Override public void setFragmentThird(FragmentThrid fragmentThird) { if (fragmentThird != null) { fragmentThridd = fragmentThird; } } //进行事件的拦截 @Override public void onBackPressed() { if (fragmentThridd == null || fragmentThridd.onBackPress()) { super.onBackPressed(); } }}
四、repalce的一个问题
在使用replace之后,会将栈中前面的fragment的视图销毁,那么如何对之前的视图数据进行保存呢?1. 通过变量,将数据保存,比如string
2. 给控件添加id即可
3. 将视图保留
public View getPersistentView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState, int layout) { if (rootView == null) { // Inflate the layout for this fragment rootView = inflater.inflate(layout, container,false); } else { ((ViewGroup) rootView.getParent()).removeView(rootView); } return rootView; }
阅读全文
0 0
- android fragment 详解(二)
- Fragment 详解二
- 二 Fragment 面试详解
- Fragment详解(二)--->生命周期详解
- Fragment详解(二)--->生命周期详解
- Fragment详解系列二ViewPager
- Android Fragment详解(二):Fragment创建及其生命周期
- Android Fragment详解(二):Fragment创建及其生命周期
- Android Fragment详解(二):Fragment创建及其生命周期
- Android Fragment详解(二):Fragment创建及其生命周期
- Android Fragment详解(二):Fragment创建及其生命周期
- Android Fragment详解(二):Fragment创建及其生命周期
- Android Fragment详解(二):Fragment创建及其生命周期
- Android Fragment详解(二):fragment创建及其生命周期
- Fragment详解(二):Fragment 与支持库
- android Fragments详解二:创建Fragment
- android Fragments详解二:创建Fragment
- android Fragments详解二:创建Fragment
- 高斯过程
- 如何正确配置Nginx+PHP
- React Native仿美团下拉菜单
- Android Framework------之PowerManagerService的功能
- Combinations
- Fragment 详解二
- 分享一道百度笔试程序题
- 安装SQL Server Express及用SQL Server Management Studio连接
- python读出mysql数据写出到csv文件中[整理]
- ucos-iii学习之栈空间大小的确定与检测任务堆栈的溢出
- 详解spl_autoload_register()函数以及自动加载不同目录的类
- Kubernetes集群架构图
- 站在集成平台的角度去看待医院系统的查询需求
- EventBus学习记录