【安卓UI】Activity与Activity、Activity与Fragment、Fragment与Fragment之间数据传递与回传

1、activity –> activity 数据传递

两个activity,Activity a启动Activity b

方法1:Intent传递数据

可以使用 startActivity(Intent intent)方法来传入一个Intent对象。在这个Intent对象中指定activity是从a跳转到b,(也可以通过Intent对象来指定要完成的action操作),同时可以通过intent对象携带数据传递给b。在activity b中通过intent获取传递过来的数据。示例代码如下:

activity a中:


var intent= Intent(this,bActivity::class.java)  

intent.putExtra("msg","测试")  
//或者
var bundle = Bundle()
bundle.putString("msg", "测试")
intent.putExtra("bun", bundle)

startActivity(intent)

activity b中:


var msg = this.intent.getStringExtra("msg")

方法2:SharedPreferences传递数据 (SQLite、Content Provider和File也可以传递数据,数据持久化)

SharedPreferences类是Android平台轻量级的存储类,用来保存应用的一些常用配置,比如Activity状态,Activity暂停时,将此activity的状态保存到SharedPereferences中;当Activity重载,系统回调方法onSaveInstanceState时,再从SharedPreferences中将值取出。SharedPreferences保存的数据会以键值对的形式保存到安卓系统文件/data/data/包名/shared_prefs目录下的xml文件。示例代码如下:

activity a 中:


var sp = this.getSharedPreferences("info", Context.MODE_PRIVATE)
//获取sp编辑器
var edit = sp.edit()
edit.putString("msg", "测试")
edit.commit()

var intent = new Intent(this,bActivity::class.java)
startActivity(intent)

activity b 中:


var sp = getSharedPreferences("info", Context.MODE_PRIVATE)
var value = sp.getString("msg","Null")

方法3:静态变量传递数据

在被启动的类中定义静态变量并赋值,示例代码如下:

activity a中:


bActivity.msg="测试"

var intent = new Intent(this,bActivity::class.java)
startActivity(intent)

activity b中:


companion object{
    var msg:String?=null
}

方法4:使用全局变量传递数据

定义一个继承自Application的类,这个类中的变量即为全局变量,有全局的生命周期。示例代码如下:

扫描二维码关注公众号,回复: 1941987 查看本文章

Application自定义类:


class MyApp:Application(){

    private var msg:String?=null

    fun setMsg(msg:String){
        this.msg=msg
    }
    fun getMsg():String?{
        return this.msg
    }
}

activity a中:


var app = this.application as MyApp
app.setMsg("测试")

var intent = new Intent(this,bActivity::class.java)
startActivity(intent)

activity b中:


var app = this.application as MyApp
var msg = app.getMsg()

方法5:使用系统粘贴板传递数据

activity a中:


var clipboardManager = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
var description = ClipDescription("来自用户的输入", arrayOf(ClipDescription.MIMETYPE_TEXT_PLAIN))
var clipData = ClipData(description,ClipData.Item("测试"))
clipboardManager.primaryClip = clipData

var intent = new Intent(this,bActivity::class.java)
startActivity(intent)

activity b中:


var clipboardManager = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
var clipData = clipboardManager.primaryClip
var clipText = ""
if(clipData.itemCount>0){
   clipText=clipData.getItemAt(0).text.toString()
}

2、activity –> activity 数据回传

通过调用startActivity(Intent intent)方法实现返回跳转的,依旧可以使用以上5种方法实现。

这里的数据回传是指,不通过调用startActivity(Intent intent)方法跳转,而是调用调用finish()方法结束被启动activity b的生命周期,而重新返回到activity a。具体细节见如下示例代码:

activity a中:


class QuestionActivity : AppCompatActivity() {

    private lateinit var etNumA:EditText
    private lateinit var etNumB:EditText
    private lateinit var tvResult:TextView
    private lateinit var btnCompute:Button
    private var numA:Int?= null
    private var numB:Int?= null
    private val  REQUEST_CODE = 1

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_question)

        this.title = "activity a"

        //获取控件
        etNumA = findViewById(R.id.et_num_a)
        etNumB = findViewById(R.id.et_num_b)
        tvResult = findViewById(R.id.tv_num_result)
        btnCompute = findViewById(R.id.btn_num_compute)

        btnCompute.setOnClickListener {
            //获取文本值
            numA = etNumA?.text?.toString()?.toInt()
            numB = etNumB?.text?.toString()?.toInt()

            var intent = Intent(this@QuestionActivity,AnswerActivity::class.java)
            intent.putExtra("numA",numA)
            intent.putExtra("numB",numB)

            /*
            * 注意点1:必须是调用startActivityForResult方法(不是startActivity方法)。
            * 这个方法的用意是被启动activity生命周期结束时,通过一些操作会把数据传递给启动activity。
            * 启动activity通过onActivityResult来接收数据。
            */
            this@QuestionActivity.startActivityForResult(intent,REQUEST_CODE)
        }

    }

    /*
     * 注意点2: 
     * 接收从Activity b回传的数据
     * 启动activity通过onActivityResult来接收数据,所以需要重写对回传的数据进行处理
     */
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if(resultCode== 2 && requestCode == REQUEST_CODE){
            tvResult.text = data?.getIntExtra("result",0).toString()
        }
    }
}

activity b中:


class AnswerActivity : AppCompatActivity() {

    private lateinit var tvNumA: TextView
    private lateinit var tvNumB: TextView
    private lateinit var etResult: EditText
    private lateinit var btnReturnResult: Button

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_answer)

        this.title = "activity b"

        //获取控件
        tvNumA = findViewById(R.id.tv_num_a)
        tvNumB = findViewById(R.id.tv_num_b)
        etResult = findViewById(R.id.et_num_result)
        btnReturnResult = findViewById(R.id.btn_num_result)

        //获取值
        var numA = intent.getIntExtra("numA",0)
        var numB = intent.getIntExtra("numB",0)

        //设置值
        tvNumA.text = numA?.toString()
        tvNumB.text = numB?.toString()

        btnReturnResult.setOnClickListener {

            var result = etResult.text.toString().toInt()

            var intent = Intent()
            var bundle= Bundle()
            bundle.putInt("result",result)
            intent.putExtras(bundle)

             /*
              * 注意点3:必须调用这个方法,把这个意图设置为返回结果,当此Activity生命周期结束时会把这个意图作为响应返回
              */
            this.setResult(2,intent)
            /*
             * 注意点4:结束当前Activity生命周期,结合setResult()方法实现数据回传
             */
            this.finish()
        }

    }
}

3、activity –> fragment 数据传递

方法1:arguments传递数据

示例代码如下:

activity中:


var bundle = Bundle()
bundle.putString("title","我是来自activity的信息1111")
var fragment = Fragment05()
fragment.arguments = bundle
fragmentManager.beginTransaction().add(R.id.fragment_activity_interactive_f5,fragment).commit()

fragment中:


 override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {

        var view = inflater?.inflate(R.layout.fragment05, container, false)
        var titleTV=view.findViewById<TextView>(R.id.fragment_activity_interactive_title5)
        //从arguments中获取数据
        titleTV.text = arguments.getString("title")
        return view
    }

方法2:构建返回Fragment对象的静态方法传递数据

activity中:


fragmentManager.beginTransaction()
.add(R.id.fragment_activity_interactive_f7,Fragment07.getInstance("我是来自activity的信息3333"))
.commit()

fragment中:


override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        //引用创建好的xml布局
        var view = inflater?.inflate(R.layout.fragment07, container, false)
        var titleTV=view.findViewById<TextView>(R.id.fragment_activity_interactive_title7)
        titleTV.text = arguments?.getString("title")
        return view
    }

    companion object {
        fun getInstance(msg:String):Fragment07{
            var fragment = Fragment07()
            var bundle = Bundle()
            bundle.putString("title",msg)
            fragment.arguments = bundle
            return fragment
        }
    }

其本质还是通过arguments传递数据。

方法3:activity中创建方法传递数据

与activity绑定的所有fragment都可以轻松获取到activity对象实例,通过在activity中构建方法可以很方便传递数据。示例代码如下:

activiy中:


fragmentManager.beginTransaction().add(R.id.fragment_activity_interactive_f6,Fragment06()).commit()

fun getMsg():String{
        return "我是来自activity的信息2222"
}

fragment中:


var msg = (activity as MainActivity)?.getMsg()

4、fragment –> activity 数据回传

方法1:回调接口传递数据

fragment定义回调接口,activity实现回调接口,通过这种方式实现fragment向activity回传数据。

示例场景是fragment视图中有一个button按钮,点击按钮向activity传递数据。示例代码代码如下:

fragment中:


class Fragment08 : Fragment(),View.OnClickListener{

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        var view = inflater?.inflate(R.layout.fragment08, container, false)
        return view
    }

    override fun onResume() {
        super.onResume()
        this.view.findViewById<Button>(R.id.fragment_activity_interactive_fa1).setOnClickListener(this)
    }

    override fun onClick(v: View?) {
        println("2================${activity}===============")
        if(this.activity!=null){
            /*
             * 注意点2:activity调用实现了的回调接口的方法,实现在fragment中向activity传递数据
             */
            (activity as FragmentMain6Activity).process("我是来自fragment的信息aaaa")
        }
    }

    /*
    * 注意点1:回调接口,供activity实现
    */
    interface Fragment07Interface{
        fun process(msg:String)
    }

}

activity中:

class MainActivity : AppCompatActivity(), Fragment08.Fragment07Interface{

    override fun process(msg: String) {
        var view = findViewById<TextView>(R.id.fragment_activity_interactive_f8)
        view.text = msg
    }

}

5、fragment –> fragment 数据传递与数据回传

5.1 同个container不同fragment之间数据传递

方法1:activity中定义方法

不同fragment通过获取到的activity对象操作这个方法,实现传递数据。

方法2:同样可以通过arguments传递数据

方法3:被传递数据的frament定义返回fragment对象的静态方法

companion object {
        fun getInstance(msg:String):Fragment07{
            var fragment = Fragment07()
            var bundle = Bundle()
            bundle.putString("title",msg)
            fragment.arguments = bundle
            return fragment
        }
 }

通过定义类似示例方法,然后调用该方法实现数据传递。也可以定义别的类似方法。

方法4:同样可以通过类似上面的回调接口传递数据。

原理类似fragment向activity回传数据,fragment a定义回调接口,activity实现回调接口,fragment a把数据传递给activity,fragment b从activity中获取数据。

方法5:开源框架EventBus发布订阅模式传递数据

看官方demo

5.2 同个container不同fragment之间数据回传

一个fragment生命周期结束时把数据回传给目标fragment。

注意三点:

  • 在启动到另一个fragment之前调用setTargetFragment方法指定要把数据回传到的目标fragment

示例代码如下:


var fragment10 = Fragment10()
//设置目标fragment,并设置请求码
fragment10.setTargetFragment(this@Fragment09, REQUEST_CODE)
fragmentManager.beginTransaction().hide(this).add(R.id.activity_container_2fragment_container,fragment10,"fragment10").addToBackStack(null).commit()
  • 目标fragment重写onActivityResult方法,实现接收另一个fragment回传过来的数据

示例代码如下,目标fragment:


override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if(resultCode == RESULT_OK && data!=null){
            if (requestCode == REQUEST_CODE){
                view.findViewById<TextView>(R.id.activity_container_fragment1_msg).text = data.getStringExtra("msg")
                view.findViewById<ImageView>(R.id.activity_container_fragment1_image).setImageResource(data.getIntExtra("image",0))
            }
        }
    }
  • 另一个fragment生命周期结束时,调用目标fragment方法onActivityResult,把数据回传给目标fragment

示例代码如下:


var fragment9 = Fragment09()
var intent = Intent()
var bundle=Bundle()
bundle.putInt("image",image)
bundle.putString("msg","这是一张图片")
intent.putExtras(bundle)

//调用方法,回传数据给目标fragment
this.targetFragment.onActivityResult(Fragment09.REQUEST_CODE,Activity.RESULT_OK,intent)
//当前fragment出栈,生命周期结束
fragmentManager.popBackStack()

5.3 同个activity不同container的fragment之间数据传递

由于讨论的是不同container中的fragment,所以一般出现在同一个布局中,所处的生命周期一致。直接获取两个fragment中控件进行数据操作即可。

[完整demo]


参考资料:

1、SharedPreferences的用法以及详解

2、关于Android Activity之间传递数据的6种方式

3、老罗安卓开发

4、Activity之间数据传递(一)(简单传递,数据包Bundle,传递对象)

5、Activity 之间传值的几种方式

6、Android 基础:Fragment,看这篇就够了 (上)

7、Fragment之间传递参数和Fragment返回上一个Fragment传回数据

8、Fragment之间传递参数和Fragment返回上一个Fragment传回数据

9、Fragment详解(系列)

猜你喜欢

转载自blog.csdn.net/u012995888/article/details/80428712
今日推荐