如何将数据从片段传递到活动,当活动不是片段的父级时

huangapple go评论67阅读模式
英文:

How to pass data from fragment to activity, when activity is not a parent of fragment

问题

问题是什么:

我想要从Fragment传递特定的“taskId”到Activity。问题是这个Activity不是Fragment的父级,因此我无法传递数据。

我尝试过的方法:

  1. 使用Intent发送数据
  2. 使用Bundle发送数据
  3. 接口(我认为接口只能在Activity是Fragment的父级时进行通信?)
  4. SharedViewModel
  5. 使用本地广播管理器传递数据

我认为主要问题在于生命周期。

在我的Fragment中,我可以像这样获取数据并正常工作:

mTaskContext = (activity as TaskActivityInterface).taskContext
	override fun onOptionsItemSelected(item: MenuItem?): Boolean {
		when (item?.itemId) {
			R.id.barcode_icon -> showScanActivity()
		}
		return super.onOptionsItemSelected(item)
	}

这里是一个简单的Intent,但我尝试将数据附加到它并在Activity中接收它,但不幸的是,在Activity中值已经为null(在Fragment中不为null):

	private fun showScanActivity() {
		startActivity(Intent(context, TransferScanActivity::class.java))
	}

这是使用广播管理器的示例(此时数据已正确发送,我在调试模式下检查过):

	private fun showScanActivity() {
		sendDataToActivity(mTaskContext.id)
		startActivity(Intent(context, TransferScanActivity::class.java))
	}

	private fun sendDataToActivity(data: Long) {
		val intent = Intent("SEND_TASKID")
		intent.putExtra("TASK_ID", data)
		LocalBroadcastManager.getInstance(requireContext()).sendBroadcast(intent)
	}
}

在Activity中,我在onStart等地注册广播接收器,但我什么都没收到:

    private val mTaskIdBroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            Log.d("TaskIdA", "Received broadcast")
                val data = intent?.getLongExtra("TASK_ID", 0)
                Log.d("TaskIdA", "onReceive: $data")
        }
    }
}
英文:

What is the issue:

I want to pass certain "taskId" from Fragment to the Activity. The problem is that this Activity is not a parent of the Fragment, therefore I am unable to pass the data.

What I've tried:

  1. Sending data using intent
  2. Sending data using bundle
  3. Interface (i think interfaces can communicate only when activity is a parent of the fragment?)
  4. SharedViewModel
  5. Passing using local broadcast manager

I guess the main issue is with lifecycle.

In my fragment, I can get data as such and it works:

mTaskContext = (activity as TaskActivityInterface).taskContext
	override fun onOptionsItemSelected(item: MenuItem?): Boolean {
		when (item?.itemId) {
			R.id.barcode_icon -> showScanActivity()
		}
		return super.onOptionsItemSelected(item)
	}

And here is simple intent, but I've tried attaching data to it and receive it in activity, but unfortunately, the value is already null in Activity (it is not null in Fragment)

	private fun showScanActivity() {
		startActivity(Intent(context, TransferScanActivity::class.java))
	}

Here is example with broadcast manager (data is correctly being sent at this point, I've checked it in debug mode):

	private fun showScanActivity() {
		sendDataToActivity(mTaskContext.id)
		startActivity(Intent(context, TransferScanActivity::class.java))
	}


	private fun sendDataToActivity(data: Long) {
		val intent = Intent("SEND_TASKID")
		intent.putExtra("TASK_ID", data)
		LocalBroadcastManager.getInstance(requireContext()).sendBroadcast(intent)
	}
}

and here in activity I register the broadcast receiver in onStart etc, but i dont get anything:

    private val mTaskIdBroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            Log.d("TaskIdA", "Received broadcast")
                val data = intent?.getLongExtra("TASK_ID", 0)
                Log.d("TaskIdA", "onReceive: $data")
        }
    }

答案1

得分: 0

创建一个在片段中的接口

public interface TaskIdListener {
    void onTaskIdReceived(int taskId);
}

之后将它添加到活动中

public class MyActivity implements TaskIdListener {
    @Override
    public void onTaskIdReceived(int taskId) {
        // 在这里处理接收到的任务ID
    }
}

在片段中添加以下代码

private TaskIdListener mListener;

最后将它添加到onAttach()方法中

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    try {
        mListener = (TaskIdListener) context;
    } catch (ClassCastException e) {
        throw new ClassCastException(context.toString()
                + "必须实现TaskIdListener");
    }
}
英文:

Create an interface in the fragment

public interface TaskIdListener {
    void onTaskIdReceived(int taskId);
}

After that add it in activity

public class MyActivity implements TaskIdListener {
    @Override
    public void onTaskIdReceived(int taskId) {
        // Handle the received taskId here
    }
}

In the fragment add this.

private TaskIdListener mListener;

Finally add it nAttach() method

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    try {
        mListener = (TaskIdListener) context;
    } catch (ClassCastException e) {
        throw new ClassCastException(context.toString()
                + " must implement TaskIdListener");
    }
}

答案2

得分: 0

我找到了一个解决方案。

解决方案是将其作为一个意图传递,但你必须注意尝试获取这个意图的位置。在这种特殊情况下,当你尝试从片段传递数据到与这个片段没有任何连接的新活动时,你必须从新活动的onCreate()方法中获取这个意图。

活动

private var taskId = 0L

override fun onCreate(savedStateInstance: Bundle?) {
    super.onCreate(savedStateInstance)
    setContentView(R.layout.activity_transfer_scan)
    taskId = intent.getLongExtra("data", 0)
    setUpUi()
}

片段:

private fun showScanActivity(data: Long) {
    val intent = Intent(requireContext(), TransferScanActivity::class.java)
    intent.putExtra("data", data)
    startActivity(intent)
}
英文:

I've found a solution.

The solution is to simply pass it as an intent, but you have to watch where you try to get this intent. In this particular case, when you try to pass data from fragment to new activity, that is not connected in any way with this fragment, you have to get this intent from onCreate() in new activity.

Activity:

private var taskId = 0L

override fun onCreate(savedStateInstance: Bundle?) {
        super.onCreate(savedStateInstance)
        setContentView(R.layout.activity_transfer_scan)
        taskId = intent.getLongExtra("data", 0)
        setUpUi()
    }

Fragment:

	private fun showScanActivity(data: Long) {
		val intent = Intent(requireContext(), TransferScanActivity::class.java)
		intent.putExtra("data", data)
		startActivity(intent)
	}

答案3

得分: 0

这是 Intent 在 Activity 和 Fragment 中的使用方法:

Activity:

Intent(this, MainActivity::class.java).apply {
    putExtra("data", data)
    startActivity(this)
}

Fragment:

Intent(requireContext(), MainActivity::class.java).apply {
    putExtra("data", data)
    startActivity(this)
}
英文:

This is how Intent work both Activity and Fragment:

Activity:

Intent(this, MainActivity::class.java).apply {
                putExtra("data",data)
                startActivity(this)
}

Fragment:

Intent(requireContext(), MainActivity::class.java).apply { 
         putExtra("data",data)
         startActivity(this)
 }

huangapple
  • 本文由 发表于 2023年3月7日 17:48:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/75660318.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定