Activity与Fragment数据传输

1.fragment生命周期

(1) 当一个fragment被创建的时候,它会经历以下状态.

  • onAttach()
  • onCreate()
  • onCreateView()
  • onActivityCreated()

(2) 当这个fragment对用户可见的时候,它会经历以下状态。

  • onStart()
  • onResume()

(3)当这个fragment进入“后台模式”的时候,它会经历以下状态。

  • onPause()
  • onStop()

(4)当这个fragment被销毁了(或者持有它的activity被销毁了),它会经历以下状态。

  • onPause()
  • onStop()
  • onDestroyView()
  • onDestroy()
  • onDetach()

(5)就像activitie一样,在以下的状态中,可以使用Bundle对象保存一个fragment的对象。

  • onCreate()
  • onCreateView()
  • onActivityCreated()

(6)fragment的大部分状态都和activitie很相似,但fragment有一些新的状态。

  • onAttached() —— 当fragment被加入到activity时调用(在这个方法中可以获得所在的activity)。
  • onCreateView() —— 当activity要得到fragment的layout时,调用此方法,fragment在其中创建自己的layout(界面)。
  • onActivityCreated() —— 当activity的onCreated()方法返回后调用此方法
  • onDestroyView() —— 当fragment中的视图被移除的时候,调用这个方法。
  • onDetach() —— 当fragment和activity分离的时候,调用这个方法。

一旦activity进入resumed状态(也就是running状态),你就可以自由地添加和删除fragment了。因此,只有当activity在resumed状态时,fragment的生命周期才能独立的运转,其它时候是依赖于activity的生命周期变化的。

感谢:https://www.cnblogs.com/purediy/p/3276545.html

2.Activity传递数据给Fragment

方法:Bundle;Activity中定义方法;

(1)Bundle

当在activity中启动fragment时,调用方法的顺序:

当activity在oncreate方法中设置传递的数据时,在fragment里,就可以通过Bundle获取到数据了。

activity中:

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        Fragment fragment = new MyFragment();
        Bundle bundle = new Bundle();
        bundle.putString("id", "ysl");
        fragment.setArguments(bundle);
        transaction.add(R.id.fragment, fragment);
        transaction.show(fragment);
        transaction.commit();

fragment中:在onAttach()、onCreate()、onCreateView()、onActivityCreated()也同样写了或数据的代码。

@Override
    public void onStart() {
        super.onStart();
        Log.d(TAG, "onStart is invoke");
        if (isAdded()){
            String id = getArguments().getString("id");
            Log.d(TAG, id);
        }
    }

结果:

可以发现在onAttach()、onCreate()的时候没有打印日志,isAdded方法的返回值还是false;在onCreateView()、onActivityCreated()、onStart()中才获取到了数据。所以,一般获取数据放在onActivityCreated()、onStart()方法中。

(2)Activity中定义方法;

activity中:

public String getTitles(){
        return "getTitle";
    }

fragment中:在onStart()、onCreate()、onCreateView()、onActivityCreated()也同样写了或数据的代码。

@Override
    public void onAttach(Context context) {
        super.onAttach(context);
        Log.d(TAG, "onAttach is invoke");
              String titles = ((MainActivity) context).getTitles();//通过强转成宿主activity,就可以获取到传递过来的数据
        Log.d(TAG, "onAttach is invoke context "+titles);
        String titles1 = ((MainActivity)getActivity()).getTitles();
        Log.d(TAG, "onAttach is invoke getActivity "+titles1);
    }

结果:

可以看到,这几个方法中都可以获取到数据。

3.Fragment传递数据给Activity

采用接口的方式传递:

fragment中:

package com.ysl.myapplication;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;

public class MyFragment extends Fragment {
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        if(context instanceof FragmentListener) {
            listener = (FragmentListener)context;
        } else{
            throw new IllegalArgumentException("activity must implements FragmentListener");
        }
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        listener.process("我是接口,在传数据呢。");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        listener = null;
    }

    private FragmentListener listener;
    public interface FragmentListener{
        void process(String str);
    }
}

activity中:

package com.ysl.myapplication;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity implements MyFragment.FragmentListener{

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        Fragment fragment = new MyFragment();
        transaction.add(R.id.fragment, fragment);
        transaction.show(fragment);
        transaction.commit();

    }

    @Override
    public void process(String str) {
        Log.d(TAG, str);
    }
}

原理:在fragment中定义接口,并让activity去实现这个接口。当fragment要传递数据的时候,就去调用这个接口的方法。刚好实现在activity中,所以在activity中就会触发接口方法,获取到相应的数据,做相应的逻辑处理。

其实,activity也可以使用这种方式传数据给fragment:

activity中:

private OnActivityDataChangedListener onActivityDataChangedListener;

    public interface OnActivityDataChangedListener {
        void onActivityDataChanged(String string);
    }

    public void setOnActivityDataChangedListener(OnActivityDataChangedListener onActivityDataChangedListener) {
        this.onActivityDataChangedListener = onActivityDataChangedListener;
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (onActivityDataChangedListener != null) {
            onActivityDataChangedListener.onActivityDataChanged("哈哈哈,activity的数据变了。");
        } else {
            throw new IllegalArgumentException("fragment must invoke setOnActivityDataChangedListener()");
        }
    }

fragment中:

@Override
    public void onAttach(Context context) {
        super.onAttach(context);

        ((MainActivity)getActivity()).setOnActivityDataChangedListener(new OnActivityDataChangedListener() {
            @Override
            public void onActivityDataChanged(String string) {
                Log.d(TAG, "收到activity的数据:"+string);
            }
        });
    }

同理,任意的两个类之间数据传输,或者是数据变化的监听,都可以使用这种方式。监听器很强大。

  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值