Fragment一定要有一个无参的构造方法!
因为当Activity因屏幕旋转或者因内存不足被系统杀死时,会导致Activity被重新创建,而当Activity被重建时,FragmentManager会首先去获取保存下来的fragment队列,重建fragment队列,进而恢复fragment的状态。

但是当重建Fragment时,调用的是Fragment的无参的构造方法,如果不存在无参的构造方法(比如定义了有参的构造方法后没有再显示的定义无参的构造方法),那么会导致异常,这时整个Activity就崩溃了。
另外,如果定义了有参的构造方法后又定义了无参的构造方法,那么由于重建Fragment时,调用的是Fragment的无参的构造方法,所以此Fragment会由于缺少必要的参数而导致显示数据异常。
所以:一定要通过setArguments传递参数,而不要通过构造方法传递!

个人总结的由一个Activity跳到另一个Activity时,Activity加载的是指定Fragment页面的方法
  • 1、如果能拿到此Activity的实例,可以直接调用相应的方法加载此Fragment,当跳到此Activity时它显示的就已经是某个Fragment了
  • 2、通过startActivity先跳到此页面,并传递过来一个参数,在Activity的oncreate方法中提取此参数,满足条件时加载需要的Fragment
  • 3、通过EventBus等发送一条事件,当Activity收到后加载需要的Fragment

* BaseActivity 管理fragment的创建,防止屏幕旋转等情况下fragment重叠现象


/**
 * 抽象一个Activity托管我们的Fragment
 * @author 白乾涛
 */
public abstract class BaseFragmentActivity extends Activity {
    protected abstract Fragment createFragment();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_single_fragment);
        Fragment fragment = getFragmentManager().findFragmentById(R.id.id_fragment_container);
        if (fragment == null) {
            //为什么要在创建fragment前判断它是否为null?
            //当【Activity】因为屏幕旋转或者因内存不足被系统杀死时,会导致Activity被重新创建,但是这时我们的【fragment】是会被完整保存下来的(系统机制)
            //并且当Activity被重建时,FragmentManager会首先去获取保存下来的fragment队列,重建fragment队列,因此就可以恢复之前的状态了
            //所以这里需要判断fragment是否为null,不为空就表明fragment是已经创建过的,此时不需要(也不能)再创建新的fragment,否则会出现多个fragment重叠现象
            fragment = createFragment();
            //add方法中id的作用:1、告知fm此fragment的位置;2、此后可以通过findFragmentById找到它
            getFragmentManager().beginTransaction().add(R.id.id_fragment_container, fragment).commit();
        }
        //做你需要的其他事情
    }
}

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是标题,我下面是一个用于填充Fragment的容器(FrameLayout)"
        android:textColor="#f00"
        android:textSize="12sp" />
    <!-- 填充Fragment的容器 -->
    <FrameLayout
        android:id="@+id/id_fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

* 两个Activity 只负责返回具体的fragment,但不负责fragment的创建细节


public class MainActivity extends BaseFragmentActivity {
    @Override
    protected Fragment createFragment() {
        return new ListTitleFragment(); //当创建的Fragment 不需要参数时,可以直接new
    }
}
public class ContentActivity extends BaseFragmentActivity {
    @Override
    protected Fragment createFragment() {
        //获取从fragment中传递过来的数据
        String title = getIntent().getStringExtra(ContentFragment.ARGUMENT);
        return ContentFragment.newInstance(title);//当创建的Fragment需要参数(数据)时,最好交给Fragment自己去处理
    }
}

* Fragment1-标题列表 跳转到Activity 并获取返回的数据

public class ListTitleFragment extends ListFragment {//public class ListFragment  extends Fragment
    /**结果码*/
    public static final int REQUEST_DETAIL = 0x110;
    private List<String> mTitles = Arrays.asList("包青天", "白乾涛", "baiqiantao", "0909082401");
    private int mCurrentPos;
    private ArrayAdapter<String> mAdapter;
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        setListAdapter(mAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, mTitles));
    }
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        mCurrentPos = position;
        //可以从Fragment中跳转到其他Activity
        Intent intent = new Intent(getActivity().getApplicationContext(), ContentActivity.class);
        //可以携带数据
        intent.putExtra(ContentFragment.ARGUMENT, mTitles.get(position));
        //并且可以获取反馈
        startActivityForResult(intent, REQUEST_DETAIL);
    }
    @Override
    //获取由此Fragment启动的另一个Activity中的一个ContentFragment结束时,ContentFragment返回的数据(数据结束时返回的)
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_DETAIL && data != null) {
            String responseEvaluate = data.getStringExtra(ContentFragment.RESPONSE);
            if (TextUtils.isEmpty(responseEvaluate)) responseEvaluate = "你还没有评价";
            mTitles.set(mCurrentPos, mTitles.get(mCurrentPos) + " ___ " + responseEvaluate);
            mAdapter.notifyDataSetChanged();
        } else Toast.makeText(getActivity(), "你还没有评价哦~", Toast.LENGTH_SHORT).show();
    }
}

* Fragment2-内容 创建带参数的Fragment 启动另一个Fragment 获取返回数据、返回数据

public class ContentFragment extends Fragment {
    /**构造时传入的值**/
    private String mArgument;
    /**构造时传入的参数**/
    public static final String ARGUMENT = "argument";
    /**当前Fragment返回结果时的返回值对应的Tag*/
    public static final String RESPONSE = "response";
    /**为启动的DialogFragment设置一个Tag,方便以后通过findFragmentByTag(tag)找到此Fragment*/
    public static final String EVALUATE_DIALOG = "evaluate_dialog";
    /**启动另一个Fragment时的请求码*/
    public static final int REQUEST_CODE_EVALUATE = 0X110;
    /**构造时把传入的参数带进来,注意一定要通过Bundle及setArguments传递数据*/
    public static ContentFragment newInstance(String argument) {
        //把所有需要传递的数据都放在Bundle中
        Bundle bundle = new Bundle();
        bundle.putString(ARGUMENT, argument);
        ContentFragment contentFragment = new ContentFragment();
        //通过setArguments把Bundle传递过去
        contentFragment.setArguments(bundle);
        return contentFragment;
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       //获取传递过来的数据
        Bundle bundle = getArguments();
        if (bundle != null) mArgument = bundle.getString(ARGUMENT);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        TextView tv = new TextView(getActivity());
        tv.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        tv.setText(mArgument);
        //在一个Fragment中启动另一个Fragment
        tv.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                EvaluateDialog dialog = new EvaluateDialog();
                //注意要设置setTargetFragment,这里的参数表示【此Fragment返回时的目标Fragment】【启动此Fragment时的请求码】
                dialog.setTargetFragment(ContentFragment.this, REQUEST_CODE_EVALUATE);
                dialog.show(getFragmentManager(), EVALUATE_DIALOG);
            }
        });
        return tv;
    }
    @Override
    //当另一个Fragment结束时,接收其返回回来的数据
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_EVALUATE && data != null) {
            //根据返回数据的Fragment返回的数据中的Tag,获取返回数据中我们需要的值
            String evaluate = data.getStringExtra(EvaluateDialog.RESPONSE_EVALUATE);
            Toast.makeText(getActivity(), "你的评价为:" + evaluate, Toast.LENGTH_SHORT).show();
            //将获取到的结果返回
            Intent intent = new Intent();
            intent.putExtra(RESPONSE, evaluate);
            getActivity().setResult(ListTitleFragment.REQUEST_DETAIL, intent);//第一个参数代表结果码,在启动者中定义
        }
    }
}

DialogFragment 返回数据到目标Fragment

/**这是在同一个Activity中,由另一个Fragment启动的一个DialogFragment*/
public class EvaluateDialog extends DialogFragment {
    private String[] mEvaluteVals = new String[] { "优", "差", "良" };
    /**返回的数据的Key或Tag或Name*/
    public static final String RESPONSE_EVALUATE = "response_evaluate";
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("请选择评价 :")//
                .setCancelable(false)//
                .setOnCancelListener(null)//
                .setOnItemSelectedListener(null)//
                .setIcon(R.drawable.ic_launcher)//
                .setItems(mEvaluteVals, new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        setResult(which);
                    }
                });
        return builder.create();
    }
    // 设置返回数据
    protected void setResult(int which) {
        // 判断是否设置了targetFragment
        if (getTargetFragment() == null) return;
        Intent intent = new Intent();
        intent.putExtra(RESPONSE_EVALUATE, mEvaluteVals[which]);
        //手动调用onActivityResultt进行返回数据,【请求码:由目标Fragment决定】【响应码:由自身决定,要求不严格的话也可随便设置一个】
        getTargetFragment().onActivityResult(ContentFragment.REQUEST_CODE_EVALUATE, Activity.RESULT_OK, intent);
    }
}

附件列表

Fragment 创建 传递参数 跳转【典例】的更多相关文章

  1. Fragment 创建 传递参数 跳转 典例

    抽取的控制Fragment的父Activity /**  * 抽象一个Activity托管我们的Single Fragment  */ public abstract class SingleFrag ...

  2. Android——软键盘操作+fragment之间传递参数+TextView限制字数,显示"..."

    原文地址: Android 手动显示和隐藏软键盘 Android隐藏输入法键盘(hideSoftInputFromInputMethod没有效果) Android Fragment传递参数_Fragm ...

  3. Python Unittest根据不同测试环境跳过用例详解

    虽然现在用的Katalon,不过这篇Unittest基本的用法讲的还是不错的 转自:https://mp.weixin.qq.com/s/ZcrjOrJ1m-hAj3gXK9TjzQ 本文章会讲述以下 ...

  4. Fragment 回退栈 传递参数,点击切换图片使用Fragment ListView

    Fragment回退栈  类似与Android系统为Activity维护一个任务栈,我们也可以通过Activity维护一个回退栈来保存每次Fragment事务发生的变化. 如果你将Fragment任务 ...

  5. Android解惑 - 为什么要用Fragment.setArguments(Bundle bundle)来传递参数(转)

    Fragment在Android3.0开始提供,并且在兼容包中也提供了Fragment特性的支持.Fragment的推出让我们编写和管理用户界面更快捷更方便了.   但当我们实例化自定义Fragmen ...

  6. android fragment传递参数_fragment之间传值的两种方法

    在Activity中加载Fragment的时候.有时候要使用多个Fragment切换.并传值到另外一个Fragment.也就是说两个Fragment之间进行参数的传递.查了很多资料.找到两种方法.一种 ...

  7. [Xcode 实际操作]九、实用进阶-(24)使用Segue(页面的跳转连接)进行页面跳转并传递参数

    目录:[Swift]Xcode实际操作 本文将演示使用Segue(页面的跳转连接)进行页面跳转并传递参数. 参照结合:[Xcode10 实际操作]九.实用进阶-(23)多个Storyboard故事板中 ...

  8. 如何向一个Fragment传递参数---setArguments方法的介绍

    在我们平常开发中经常会用到Fragment,当我们使用Fragment时一般是通过new Fragment的构造方法来实现,如果我问你怎么向一个Fragment传递参数,你是不是会首先想到通过构造方法 ...

  9. js跳转传递参数

    额,利用j获取了GridView中选中行数据后,通过JavaScript做跳转,传递参数的时候发现,当参数有中文的时候就会乱码, 当然出现这种情况的时候就需要对跳转的url进行编码 var urlX ...

随机推荐

  1. java _循环练习和数组练习

    练习 1.输出所有的水仙花数,所谓水仙花数是指一个数3位数,其每位数字立方和等于其本身,如153 = 1*1*1 + 3*3*3 + 5*5*5(很经典的题目) 分析: 通过观察发现,本题目要实现打印 ...

  2. [BZOJ4556][TJOI2016&&HEOI2016]字符串(二分答案+后缀数组+RMQ+主席树)

    4556: [Tjoi2016&Heoi2016]字符串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1360  Solved: 545[S ...

  3. [BZOJ4553][TJOI2016&&HEOI2016]序列(CDQ分治)

    4553: [Tjoi2016&Heoi2016]序列 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1202  Solved: 554[Su ...

  4. [BZOJ4892][TJOI2017]DNA(后缀数组)

    题目描述 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个碱基,依然能够表现出吃藕的性状 ...

  5. Varnish与Squid的对比

    Varnish与Squid的对比 说到Varnish,就不能不提Squid.Squid是一个高性能的代理缓存服务器,它和Varnish相比较有诸多的异同点,下面进行分析. 下面是Varnish与Squ ...

  6. 2017-2018-1 JAVA实验站 冲刺 day07

    2017-2018-1 JAVA实验站 冲刺 day07 各个成员今日完成的任务 小组成员 今日工作 完成进度 张韵琪 写博客.进行工作总结 100% 齐力锋 部分按钮图片.对按钮图片进行ps 100 ...

  7. 【ArcGIS笔记】数据处理

    1.ARCGIS在导入Excel坐标点的时候出现"没有注册类"的情况怎么办? 确保你本机上装有office,并且版本要能够识别XLSX格式.2007以上. 2.导入excel时re ...

  8. MySQL数据库单例连接简单实现(MySQL扩展)

    <?php /** * MySQL数据库单例实现 * * @author shizq at 2015-04-22 * */ final class MySQLFactory { private ...

  9. CentOS的rpm常用命令(转)

    一.RPM 安装操作 命令: rpm -i 需要安装的包文件名 举例如下: rpm -i example.rpm 安装 example.rpm 包: rpm -iv example.rpm 安装 ex ...

  10. The useful App Paths registry key : HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths how to load BPLs without writ ...