Fragment翻译即碎片,它被称为Android的第五大组件,主要用来附在activity上给UI进行灵活设置,模块化重复利用,支持回退栈。
与其他组件一样拥有着自己的生命周期,并且可以灵活的加载到Activity中,在开发中有很多用途。
其生命周期:
-
onAttach(activity: Activity)
将fragment与activity绑定时调用 -
onCreateView(nflater: LayoutInflater, container:ViewGroup?, savedInstanceState: Bundle?): View?
创建视图时调用 -
onActivityCreated(savedInstanceState: Bundle?)
与其绑定的Activity创建完成后调用 -
onDestroyView()
销毁时视图调用 -
onDetach()
与Activity解绑时调用
加载:
- 静态加载:
首先创建一个fragment布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00ff00" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is fragment 1"
android:textColor="#000000"
android:textSize="25sp" />
</LinearLayout>
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<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=".MainActivity"
android:id="@+id/ll"
android:orientation="vertical"
>
<fragment
android:id="@+id/fragment"
android:name="com.example.fragmentrecycle.MyFragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
</fragment>
</LinearLayout>
2. 动态加载:
activity_main.xml
<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=".MainActivity"
android:id="@+id/ll"
android:orientation="vertical"
>
<Button
android:onClick="click"
android:text="添加"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
</LinearLayout>
Mactivity.kt
fun click(view: View) {
//通过tag查找fragment管理者里有没有对应fragment
val findFragmentByTag = supportFragmentManager.findFragmentByTag("ss")
if(findFragmentByTag==null){
val beginTransaction = supportFragmentManager.beginTransaction()
val fragment = MyFragment()
beginTransaction.add(R.id.fragment, fragment, "ss")
beginTransaction.commit()
}
}
生命周期实验:
package com.example.fragmenttry
import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
println("Life Activity onCreate")
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onStart() {
println("Life Activity onStart")
super.onStart()
}
override fun onResume() {
println("Life Activity onResume")
super.onResume()
}
override fun onPause() {
println("Life Activity onPause")
super.onPause()
}
override fun onStop() {
println("Life Activity onStop")
super.onStop()
}
override fun onDestroy() {
println("Life Activity onDestroy")
super.onDestroy()
}
fun click(view: View) {
//通过tag查找fragment管理者里有没有对应fragment
val findFragmentByTag = supportFragmentManager.findFragmentByTag("ss")
if(findFragmentByTag==null){
val beginTransaction = supportFragmentManager.beginTransaction()
val fragment = MyFragment()
beginTransaction.add(R.id.ll, fragment, "ss")
beginTransaction.commit()
}
}
}
class MyFragment: Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
println("Life MyFragment onCreateView")
return inflater.inflate(R.layout.fragment1, container, false)
}
override fun onCreate(savedInstanceState: Bundle?) {
println("Life MyFragment onCreate")
super.onCreate(savedInstanceState)
}
override fun onAttach(context: Context) {
println("Life MyFragment onAttach")
super.onAttach(context)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
println("Life MyFragment onActivityCreated")
super.onActivityCreated(savedInstanceState)
}
override fun onStart() {
println("Life MyFragment onStart")
super.onStart()
}
override fun onResume() {
println("Life MyFragment onResume")
super.onResume()
}
override fun onPause() {
println("Life MyFragment onPause")
super.onPause()
}
override fun onStop() {
println("Life MyFragment onStop")
super.onStop()
}
override fun onDestroyView() {
println("Life MyFragment onDestroyView")
super.onDestroyView()
}
override fun onDetach() {
println("Life MyFragment onDetach")
super.onDetach()
}
override fun onDestroy() {
println("Life MyFragment onDestroy")
super.onDestroy()
}
}
第一次打开应用:
2020-11-29 14:44:14.949 17693-17693/com.example.fragmenttry I/System.out: Life Activity onCreate
2020-11-29 14:44:15.168 17693-17693/com.example.fragmenttry I/System.out: Life Activity onStart
2020-11-29 14:44:15.173 17693-17693/com.example.fragmenttry I/System.out: Life Activity onResume
点击按钮动态加载fragment
2020-11-29 14:46:06.875 18116-18116/com.example.fragmenttry I/System.out: Life MyFragment onAttach
2020-11-29 14:46:06.875 18116-18116/com.example.fragmenttry I/System.out: Life MyFragment onCreate
2020-11-29 14:46:06.876 18116-18116/com.example.fragmenttry I/System.out: Life MyFragment onCreateView
2020-11-29 14:46:06.883 18116-18116/com.example.fragmenttry I/System.out: Life MyFragment onActivityCreated
2020-11-29 14:46:06.883 18116-18116/com.example.fragmenttry I/System.out: Life MyFragment onStart
2020-11-29 14:46:06.883 18116-18116/com.example.fragmenttry I/System.out: Life MyFragment onResume
点击home键
2020-11-29 14:47:02.460 18116-18116/com.example.fragmenttry I/System.out: Life Activity onPause
2020-11-29 14:47:02.462 18116-18116/com.example.fragmenttry I/System.out: Life MyFragment onPause
2020-11-29 14:47:03.052 18116-18116/com.example.fragmenttry I/System.out: Life Activity onStop
2020-11-29 14:47:03.053 18116-18116/com.example.fragmenttry I/System.out: Life MyFragment onStop
回到应用:
2020-11-29 14:47:53.458 18116-18116/com.example.fragmenttry I/System.out: Life Activity onStart
2020-11-29 14:47:53.458 18116-18116/com.example.fragmenttry I/System.out: Life MyFragment onStart
2020-11-29 14:47:53.459 18116-18116/com.example.fragmenttry I/System.out: Life Activity onResume
2020-11-29 14:47:53.460 18116-18116/com.example.fragmenttry I/System.out: Life MyFragment onResume
退出应用
2020-11-29 14:48:35.523 18116-18116/com.example.fragmenttry I/System.out: Life Activity onPause
2020-11-29 14:48:35.523 18116-18116/com.example.fragmenttry I/System.out: Life MyFragment onPause
2020-11-29 14:48:36.111 18116-18116/com.example.fragmenttry I/System.out: Life Activity onStop
2020-11-29 14:48:36.112 18116-18116/com.example.fragmenttry I/System.out: Life MyFragment onStop
2020-11-29 14:48:36.114 18116-18116/com.example.fragmenttry I/System.out: Life Activity onDestroy
2020-11-29 14:48:36.114 18116-18116/com.example.fragmenttry I/System.out: Life MyFragment onDestroyView
2020-11-29 14:48:36.118 18116-18116/com.example.fragmenttry I/System.out: Life MyFragment onDestroy
2020-11-29 14:48:36.119 18116-18116/com.example.fragmenttry I/System.out: Life MyFragment onDetach
Fragment的显示和隐藏:
class MainActivity : AppCompatActivity() {
var fragment:Fragment? = null
var beginTransaction:FragmentTransaction? = null
override fun onCreate(savedInstanceState: Bundle?) {
println("Life Activity onCreate")
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onStart() {
println("Life Activity onStart")
super.onStart()
}
override fun onResume() {
println("Life Activity onResume")
super.onResume()
}
override fun onPause() {
println("Life Activity onPause")
super.onPause()
}
override fun onStop() {
println("Life Activity onStop")
super.onStop()
}
override fun onDestroy() {
println("Life Activity onDestroy")
super.onDestroy()
}
fun click(view: View) {
beginTransaction = supportFragmentManager.beginTransaction()
when(view.id){
R.id.add -> add()
R.id.hide -> hide()
R.id.show -> show()
}
beginTransaction?.commit()
}
private fun add() {
fragment = supportFragmentManager.findFragmentByTag("fragment")
if (fragment==null){
fragment = MyFragment()
beginTransaction?.add(R.id.ll, fragment!!, "fragment")
}
}
private fun hide() {
val fragment = supportFragmentManager.findFragmentByTag("fragment")
if (fragment!=null){
beginTransaction?.hide(fragment)
}
}
private fun show() {
val fragment = supportFragmentManager.findFragmentByTag("fragment")
if (fragment!=null){
beginTransaction?.show(fragment)
}
}
}
class MyFragment: Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
println("Life MyFragment onCreateView")
return inflater.inflate(R.layout.fragment1, container, false)
}
override fun onCreate(savedInstanceState: Bundle?) {
println("Life MyFragment onCreate")
super.onCreate(savedInstanceState)
}
override fun onAttach(context: Context) {
println("Life MyFragment onAttach")
super.onAttach(context)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
println("Life MyFragment onActivityCreated")
super.onActivityCreated(savedInstanceState)
}
override fun onStart() {
println("Life MyFragment onStart")
super.onStart()
}
override fun onResume() {
println("Life MyFragment onResume")
super.onResume()
}
override fun onPause() {
println("Life MyFragment onPause")
super.onPause()
}
override fun onStop() {
println("Life MyFragment onStop")
super.onStop()
}
override fun onDestroyView() {
println("Life MyFragment onDestroyView")
super.onDestroyView()
}
override fun onDetach() {
println("Life MyFragment onDetach")
super.onDetach()
}
override fun onDestroy() {
println("Life MyFragment onDestroy")
super.onDestroy()
}
}
从打印信息可以
- List item
看出它两并不会执行任何生命周期方法,就是凭空消失,如果上面有个按钮,隐藏后也点击不到!
remove(): 与add操作相反,将会销毁实例,但可以通过beginTransaction?.addToBackStack(null)
把该事务放入回退栈防止实例销毁
private fun remove() {
val fragment = supportFragmentManager.findFragmentByTag("fragment")
if (fragment!=null){
beginTransaction?.remove(fragment)
}
}
2020-11-29 15:25:59.939 25711-25711/com.example.fragmenttry I/System.out: Life MyFragment onPause
2020-11-29 15:25:59.940 25711-25711/com.example.fragmenttry I/System.out: Life MyFragment onStop
2020-11-29 15:25:59.941 25711-25711/com.example.fragmenttry I/System.out: Life MyFragment onDestroyView
2020-11-29 15:25:59.948 25711-25711/com.example.fragmenttry I/System.out: Life MyFragment onDestroy
replace(): 销毁原有,创建新的
private fun replace() {
fragment = supportFragmentManager.findFragmentByTag("fragment")
if (fragment!=null){
val fragment2 = MyFragment()
beginTransaction?.replace(R.id.ll, fragment2)
}
}
2020-11-29 15:29:46.353 27147-27147/com.example.fragmenttry I/System.out: Life MyFragment onAttach
2020-11-29 15:29:46.354 27147-27147/com.example.fragmenttry I/System.out: Life MyFragment onCreate
2020-11-29 15:29:46.355 27147-27147/com.example.fragmenttry I/System.out: Life MyFragment onPause
2020-11-29 15:29:46.356 27147-27147/com.example.fragmenttry I/System.out: Life MyFragment onStop
2020-11-29 15:29:46.356 27147-27147/com.example.fragmenttry I/System.out: Life MyFragment onDestroyView
2020-11-29 15:29:46.361 27147-27147/com.example.fragmenttry I/System.out: Life MyFragment onDestroy
2020-11-29 15:29:46.361 27147-27147/com.example.fragmenttry I/System.out: Life MyFragment onDetach
2020-11-29 15:29:46.362 27147-27147/com.example.fragmenttry I/System.out: Life MyFragment onCreateView
2020-11-29 15:29:46.374 27147-27147/com.example.fragmenttry I/System.out: Life MyFragment onActivityCreated
2020-11-29 15:29:46.374 27147-27147/com.example.fragmenttry I/System.out: Life MyFragment onStart
2020-11-29 15:29:46.375 27147-27147/com.example.fragmenttry I/System.out: Life MyFragment onResume
detach():销毁视图
2020-11-29 15:37:29.948 27626-27626/com.example.fragmenttry I/System.out: Life MyFragment onPause
2020-11-29 15:37:29.949 27626-27626/com.example.fragmenttry I/System.out: Life MyFragment onStop
2020-11-29 15:37:29.949 27626-27626/com.example.fragmenttry I/System.out: Life MyFragment onDestroyView
attach():重建视图
2020-11-29 15:39:49.454 28424-28424/com.example.fragmenttry I/System.out: Life MyFragment onCreateView
2020-11-29 15:39:49.466 28424-28424/com.example.fragmenttry I/System.out: Life MyFragment onActivityCreated
2020-11-29 15:39:49.466 28424-28424/com.example.fragmenttry I/System.out: Life MyFragment onStart
2020-11-29 15:39:49.467 28424-28424/com.example.fragmenttry I/System.out: Life MyFragment onResume
旋转屏幕:
2020-11-29 15:45:45.523 28424-28424/com.example.fragmenttry I/System.out: Life Activity onPause
2020-11-29 15:45:45.523 28424-28424/com.example.fragmenttry I/System.out: Life MyFragment onPause
2020-11-29 15:45:45.525 28424-28424/com.example.fragmenttry I/System.out: Life Activity onStop
2020-11-29 15:45:45.526 28424-28424/com.example.fragmenttry I/System.out: Life MyFragment onStop
2020-11-29 15:45:45.528 28424-28424/com.example.fragmenttry I/System.out: Life Activity onDestroy
2020-11-29 15:45:45.528 28424-28424/com.example.fragmenttry I/System.out: Life MyFragment onDestroyView
2020-11-29 15:45:45.530 28424-28424/com.example.fragmenttry I/System.out: Life MyFragment onDestroy
2020-11-29 15:45:45.530 28424-28424/com.example.fragmenttry I/System.out: Life MyFragment onDetach
2020-11-29 15:45:45.556 28424-28424/com.example.fragmenttry I/System.out: Life Activity onCreate
2020-11-29 15:45:45.558 28424-28424/com.example.fragmenttry I/System.out: Life MyFragment onAttach
2020-11-29 15:45:45.558 28424-28424/com.example.fragmenttry I/System.out: Life MyFragment onCreate
2020-11-29 15:45:45.600 28424-28424/com.example.fragmenttry I/System.out: Life Activity onStart
2020-11-29 15:45:45.600 28424-28424/com.example.fragmenttry I/System.out: Life MyFragment onCreateView
2020-11-29 15:45:45.603 28424-28424/com.example.fragmenttry I/System.out: Life MyFragment onActivityCreated
2020-11-29 15:45:45.604 28424-28424/com.example.fragmenttry I/System.out: Life MyFragment onStart
2020-11-29 15:45:45.605 28424-28424/com.example.fragmenttry I/System.out: Life Activity onResume
2020-11-29 15:45:45.606 28424-28424/com.example.fragmenttry I/System.out: Life MyFragment onResume
发现Activity和fragment同时销毁重建,但是fragment提供了一个retainInstance,当它等于true时j
两个fragment传递数据方式
-
方式一:在activity中操作,
val arrayAdapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mString); val listView = findViewById<ListView>(R.id.list) listView?.adapter = arrayAdapter val mFragment2_tv = findViewById<TextView>(R.id.fragment2_tv) listView.setOnItemClickListener { parent, view, position, id -> mFragment2_tv.text = mString[position] }
-
方式二:在各自fragment中操作
//从父布局找到另一个fragment的控件 val textView = activity?.findViewById<TextView>(R.id.fragment2_tv) val listView = view?.findViewById<ListView>(R.id.list) val arrayAdapter = activity?.let { ArrayAdapter<String>(it, android.R.layout.simple_list_item_1, mString) }; listView?.adapter = arrayAdapter listView?.setOnItemClickListener { parent, view, position, id -> textView?.text = mString[position]
-
方式三:通过接口
interface titleSelectInterface { fun onTitleSelect(title: String?) }
Activity实现接口方法,在方法里调用fragment2内方法,fragment1调用activity里实现的接口方法
Fragment1:
override fun onAttach(activity: Activity) {
super.onAttach(activity)
try {
mSelectInterface = activity as titleSelectInterface
} catch (e: Exception) {
throw ClassCastException(activity.toString() + "must implement OnArticleSelectedListener")
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
mSelectInterface?.onTitleSelect(str)
}
与ViewPager的使用方法:
看看我写了什么:
class MyFragmentAdapter(fm: FragmentManager, var fragmentList: List<Fragment>) : FragmentPagerAdapter(fm) {
override fun getItem(position: Int): Fragment {
return fragmentList.get(position)
}
override fun getCount(): Int {
return fragmentList.size
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
return super.instantiateItem(container, position)
}
}
class MyFragment1: Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment1, container, false)
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initView()
}
private fun initView() {
var fragmentList = ArrayList<Fragment>()
fragmentList.add(MyFragment1())
fragmentList.add(MyFragment2())
fragmentList.add(MyFragment3())
fragmentList.add(MyFragment4())
fragmentList.add(MyFragment5())
val viewPager = findViewById<ViewPager>(R.id.viewPager);
viewPager.adapter = MyFragmentAdapter(supportFragmentManager, fragmentList)
}
}
activit_main.xml:
<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=".MainActivity"
android:id="@+id/ll"
android:orientation="vertical"
>
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"></androidx.viewpager.widget.ViewPager>
</LinearLayout>
结果:
处理重写这两个关键方法,我们平时还会重写其他方法,这里我们直接用了Google写好的:
public Object instantiateItem(@NonNull ViewGroup container, int position) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
final long itemId = getItemId(position);
// Do we already have this fragment?
String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if (fragment != null) {
if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
mCurTransaction.attach(fragment);
} else {
fragment = getItem(position);
if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
mCurTransaction.add(container.getId(), fragment,
makeFragmentName(container.getId(), itemId));
}
if (fragment != mCurrentPrimaryItem) {
fragment.setMenuVisibility(false);
if (mBehavior == BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
mCurTransaction.setMaxLifecycle(fragment, Lifecycle.State.STARTED);
} else {
fragment.setUserVisibleHint(false);
}
}
return fragment;
}
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
Fragment fragment = (Fragment) object;
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
+ " v=" + (fragment.getView()));
mCurTransaction.detach(fragment);
if (fragment == mCurrentPrimaryItem) {
mCurrentPrimaryItem = null;
}
}
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return ((Fragment)object).getView() == view;
}
FragmentPagerAdapter 和FragmentStatePagerAdapter区别:
FragmentPagerAdapter一般用于少量界面的ViewPager,划过的Fragment会一直保存在内存中不会被销毁,但会销毁视图。
而FragmentStatePagerAdapter适用于界面较多的ViewPager,它会保存当前的界面以及下一个界面和上一个界面,默认最多保存三个,其他的会在destroyItem()方法中被销毁掉
如何做炫酷的滑动效果:
需要在viewpager添加Transformer
viewPager.setPageTransformer(true, ZoomOutPageTransformer())viewPager.setPageTransformer(true, ZoomOutPageTransformer())
public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.85f;
private static final float MIN_ALPHA = 0.5f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if (position < -1) { // [-Infinity,-1) 不可见状态
// This page is way off-screen to the left.
view.setAlpha(0); //透明度设置为0
} else if (position <= 1) { // [-1,1] 可见状态,设置动画效果
// Modify the default slide transition to shrink the page as well
float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
float vertMargin = pageHeight * (1 - scaleFactor) / 2;
float horzMargin = pageWidth * (1 - scaleFactor) / 2;
if (position < 0) {
view.setTranslationX(horzMargin - vertMargin / 2);
} else {
view.setTranslationX(-horzMargin + vertMargin / 2);
}
// Scale the page down (between MIN_SCALE and 1)
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
// Fade the page relative to its size.
view.setAlpha(MIN_ALPHA +
(scaleFactor - MIN_SCALE) /
(1 - MIN_SCALE) * (1 - MIN_ALPHA));
} else { // (1,+Infinity] 不可见状态
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
position即该pager左边框的位置 =0时刚好贴在屏幕边框, =-1时,该pager的右边框刚好贴在屏幕左边框
startActivityForResult在FragmentActivity和Fragment中的区别
我们编写的MainActivity就是一个FragmentActivity
首先看个程序:
class ActivityTwo : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_two)
setResult(10, Intent().putExtra("msg","yes"))
finish()
}
}
class Fragment1 : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment1, container, false)
val button = view.findViewById<Button>(R.id.btn)
button.setOnClickListener{
startActivityForResult(Intent(context, ActivityTwo::class.java), 100)
}
return view
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == 10){
val stringExtra = data?.getStringExtra("msg")
Toast.makeText(context, "Fragment "+ stringExtra+"==requestCode:"+requestCode, Toast.LENGTH_SHORT).show()
}
super.onActivityResult(requestCode, resultCode, data)
}
}
class MainActivity : AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main3)
val button = findViewById<Button>(R.id.btnn)
button.setOnClickListener{
startActivityForResult(Intent(this, ActivityTwo::class.java), 100)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == 10){
val stringExtra = data?.getStringExtra("msg")
Toast.makeText(this, "FragmentActivity "+ stringExtra+"==requestCode:"+requestCode, Toast.LENGTH_SHORT).show()
}
super.onActivityResult(requestCode, resultCode, data)
}
}
运行结果:
我们发现再FragmentActivity中嵌套Fragment时调用Fragment的startActivityForResult时,FragmentActivity也会拿到返回信息,但是requestCode时不一样的,是个比100大很多的Int,
而再FragmentActivity调用startActivityForResult时,Fragment是拿不到返回信息的。
分析:
Fragment的startActivityForResult()
public void startActivityForResult(Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
/**
* Call {@link Activity#startActivityForResult(Intent, int, Bundle)} from the fragment's
* containing Activity.
*/
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mHost == null) {
throw new IllegalStateException("Fragment " + this + " not attached to Activity");
}
mHost.onStartActivityFromFragment(this /*fragment*/, intent, requestCode, options);
}
mHost是FragmentActivity的一个内部类FragmentActivity.HostCallbacks
进去看看onStartActivityFromFragment(this , intent, requestCode, options);
@Override
public void onStartActivityFromFragment(
Fragment fragment, Intent intent, int requestCode, @Nullable Bundle options) {
FragmentActivity.this.startActivityFromFragment(fragment, intent, requestCode, options);
}
public void startActivityFromFragment(Fragment fragment, Intent intent,
int requestCode, @Nullable Bundle options) {
mStartedActivityFromFragment = true;
try {
if (requestCode == -1) {
ActivityCompat.startActivityForResult(this, intent, -1, options);
return;
}
//判断RequestCode是否越界
checkForValidRequestCode(requestCode);
int requestIndex = allocateRequestIndex(fragment);
ActivityCompat.startActivityForResult(
this, intent, ((requestIndex + 1) << 16) + (requestCode & 0xffff), options);
} finally {
mStartedActivityFromFragment = false;
}
}
最重要的一句话:
ActivityCompat.startActivityForResult(
this, intent, ((requestIndex + 1) << 16) + (requestCode & 0xffff), options);
requestIndex 是请求序号,由0递增,
简化就是(requestIndex+1)65536+requestCode,
我们上面131172 = 265536+100得来的
原因:使用一个简单的映射规则,把来自Fragment的请求和来自FragmentActivity自身请求区分开来,无需用户自行判断。