03、Activity和Fragment

126 阅读4分钟

1 Activity

1.1 Activity的生命周期

activity生命周期.png

注:

onPause()和onStop()被调用的前提是: 打开了一个新的Activity!而前者是旧Activity还可见的状态;后者是旧Activity已经不可见!

另外:AlertDialog和PopWindow是不会触发onPause()和onStop()回调方法的

2.2 Activity的启动方式

1. 显式启动:通过包名来启动,写法如下:

①最常见的:

startActivity(new Intent(当前Act.this,要启动的Act.class));

②通过Intent的ComponentName:

ComponentName cn = new ComponentName("当前Act的全限定类名","启动Act的全限定类名") ;
Intent intent = new Intent() ;
intent.setComponent(cn) ;
startActivity(intent) ;

③初始化Intent时指定包名:

Intent intent = new Intent("android.intent.action.MAIN");
intent.setClassName("当前Act的全限定类名","启动Act的全限定类名");
startActivity(intent);

2.隐式启动:通过Intent-filter的Action,Category或data来实现 这个是通过Intent的 intent-filter来实现的

2.3 两个Activity之间的数据传递

1.使用Intent传递
向目标Activity传递数据

Intent intent = new Intent(this, MainActivity2.class);
intent.putExtra("BUTTON_TITLE","hello");
startActivity(intent);

在目标Activity中取出数据

//用getXxxExtra()取出对应类型的数据。取出String只需要指定key,
//取出int要指定key,还要设置默认值,当intent中没有该key对应的value时,返回设置的默认值
if (getIntent() != null){
   getIntent().getStringExtra("BUTTON_TITLE");
}

2.使用Bundle传递数据
向目标Activity传递数据

Intent intent = new Intent(this, MainActivity2.class);
Bundle bundle = new Bundle();
bundle.putString("BUTTON_TITLE","hello");
intent.putExtra("BUTTON_TITLE",bundle);
startActivity(intent);

在目标Activity中取出数据

if (getIntent() != null){
    Bundle bundle = getIntent().getBundleExtra("BUTTON_TITLE");
    if (bundle != null){
        String button_title = bundle.getString("BUTTON_TITLE");
        btn1.setText(button_title);
    }
}

3.目标Activity销毁时,回传数据给上一个Activity
启动目标Activity,并设置一个请求码标识当前Activity

Intent intent = new Intent(this, MainActivity2.class);
//startActivityForResult()方法可以启动一个Activity,并可以设置一个int型的请求码标识当前Activity
startActivityForResult(intent, 999);

在目标Activity中回传数据,回传时会把请求码、结果码、Intent数据封装为一个整体回传,请求码+结果码唯一标识回传的Intent

//回传数据用得Intent可以新建,也可以用getIntent()
Intent intent = new Intent();
//设置要回传的数据
intent.putExtra("word","数据回传成功!!!");
//设置结果码标识当前Activity,回传数据。不管多早调用这句代码,这句代码在当前Activity销毁时才会执行,即此Activity销毁时才会回传数据。请求码和结果码不必相同。
setResult(RESULT_OK,intent);

在上一级Activity中取出回传的数据

上一级Activity使用 startActivityForResult() 开启目标Activity后,当目标Activity销毁时,会向上一级Activity回传数据,并回调上一级 Activity的 onActivityResult() 方法。需要重写上一级Activity的 onActivityResult() 方法获取回传数据。

//三个形参,请求码、结果码、目标Activity回传的Intent
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 999 && resultCode == RESULT_OK){
        if (data != null){
            Toast.makeText(this,data.getStringExtra("word"),Toast.LENGTH_SHORT).show();
        }
    }
}

2 Fragment

2.1 Fragment的核心要点

fragment的生命周期.png

  • 3.0版本后引入,即minSdk要大于11
  • Fragment需要嵌套在Activity中使用
  • 实现三个方法:onCreate( )、onCreateView( )、OnPause( )
  • Fragment的生命周期

2.2 Fragment的加载

2.2.1 静态加载

实现流程:

定义Fragment的布局,就是fragment显示内容的

<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"
    app:layoutManager="LinearLayoutManager"
    tools:context=".fragment.ListFragment" >
​
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#fff000"/>
</LinearLayout>

自定义一个Fragment类,需要继承Fragment或者他的子类,重写onCreateView( )方法在该方法中调用:inflater.inflate( )方法加载Fragment的布局文件,接着返回加载的view对象

public class ListFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_list, container, false);
        return view;
    }
}

在需要加载Fragment的Activity对应的布局文件中添加fragment的标签,name属性是全限定类名哦,就是要包含Fragment的包名,如:

<fragment
    android:id="@+id/listFragment"
    android:name="com.example.demo4.fragment.ListFragment"
    android:layout_width="200dp"
    android:layout_height="150dp"
    android:layout_centerInParent="true"/>

Activity在onCreate( )方法中调用setContentView()加载布局文件即可

2.2.2 动态加载

定义Fragment的布局,自定义一个Fragment类,需要继承Fragment或者他的子类,重写onCreateView( )方法在该方法中调用:inflater.inflate( )方法加载Fragment的布局文件,接着返回加载的view对象

通过修改Activity的布局文件,使用布局标签把刚才创建的Fragment和Activity关联起来

<LinearLayout 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"
    tools:context=".activity.DynamicLoadFragmentActivity">
    <LinearLayout
        android:id="@+id/linearLayout"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

在Activity的代码中使用FragmentManager的相关方法来加载Fragment

public class DynamicLoadFragmentActivity extends AppCompatActivity {
​
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dynamic_load_fragment);
​
        ListFragment listFragment = new ListFragment();
        getSupportFragmentManager()
                .beginTransaction()
                .add(R.id.linearLayout,listFragment)
                .commit();
    }
}

2.3 Fragment和Activity交互

2.3.1 组件获取

Fragment获得Activity中的组件:getActivity().findViewById(R.id.list); Activity获得Fragment中的组件:getFragmentManager.findFragmentByid(R.id.fragment);

2.3.2 Activityt向Fragment传值

2.3.2 Fragment向Activityt传值