Kotlin 片段可以触发 activity 的 onNewIntent
Kotlin can a fragment trigger an activity's onNewIntent
我目前正在开发一款使用 Zebra SDK 的扫描仪应用程序。
在我找到的示例和文档中,onTouchListener 创建了一个新的 Intent(扫描)并广播它。在重写的 onNewIntent 方法中,意图被解码并返回扫描值。
只要我使用 1 activity 并且没有片段,这一切都很好,但是对于我正在创建的应用程序,我希望有 1 activity 和多个片段。
目前一切都发生在 1 activity(和一个视图)中,但这有点混乱并且不是做事的理想方式,所以我最终会拆分 activity。
我尝试创建片段并使用 safeargs 在它们之间传递数据。但我无法弄清楚如何启动意图并从片段中捕获结果。我尝试在我的片段中添加一个 onTouchListener,
下面是 activity 中的当前代码。我没有任何碎片,因为到目前为止我所有的尝试都失败了。
override fun onTouch(view: View?, motionEvent: MotionEvent?): Boolean {
if (view?.getId() == R.id.btnScanner) {
if (motionEvent?.getAction() == MotionEvent.ACTION_DOWN) {
// Button pressed, start scan
val dwIntent = Intent()
dwIntent.action = "com.symbol.datawedge.api.ACTION"
dwIntent.putExtra("com.symbol.datawedge.api.SOFT_SCAN_TRIGGER", "START_SCANNING")
dwIntent.putExtra("Type", "START")
sendBroadcast(dwIntent)
} else if (motionEvent?.getAction() == MotionEvent.ACTION_UP) {
// Button released, end scan
val dwIntent = Intent()
dwIntent.action = "com.symbol.datawedge.api.ACTION"
dwIntent.putExtra("com.symbol.datawedge.api.SOFT_SCAN_TRIGGER", "STOP_SCANNING")
dwIntent.putExtra("Type", "END")
sendBroadcast(dwIntent)
}
}
return true
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
if (intent.getStringExtra("Type") != "START") {
//This would be for the first fragment
if (personId.text.toString().isEmpty()) {
val id = decodeScan((intent))
personId.text = id
lockId()
} else {
//This would be in the second fragment, after the user signed in by scanning his personal barcode
if (productId.hasFocus() || productId.text.isEmpty()) {
val res = decodeScan(intent)
productId.text = res
} else if (locationId.hasFocus() || (locationId.text.isEmpty() && productId.text.isNotEmpty())) {
val res = decodeScan(intent)
val location = (locations.filter { x -> x.contains(res) }).first()
locationId.setText(location)
}
}
}
}
onNewIntent 方法属于 Activity,因此您不能在片段中使用它。您可以做的是,在提供的 onNewIntent 调用时将数据传递给您的片段,您可以引用该片段。
var fragment; //assign default value to fragment
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
// you can add fragment based checks in this method
to work as you want
if (fragment is YourFragment) {
if (intent.getStringExtra("Type") != "START") {
//This would be for the first fragment
if (personId.text.toString().isEmpty()) {
val id = decodeScan((intent))
personId.text = id
lockId()
}
}
}else if (fragment is YourSecondFragment) {{
if (productId.hasFocus() || productId.text.isEmpty()) {
val res = decodeScan(intent)
productId.text = res
} else if (locationId.hasFocus() || (locationId.text.isEmpty() &&
productId.text.isNotEmpty())) {
val res = decodeScan(intent)
val location = (locations.filter { x -> x.contains(res) }).first()
locationId.setText(location)
}
}
}
}
onNewIntent
仅在 Activity 中可用,因此您需要使意图对片段可用。
为此,您可以使用 MutableLiveData 和 ViewModel。
class MyViewModel: ViewModel() {
val intent = MutableLiveData<Intent?>()
}
然后
class MyActivity: AppCompatActivity() {
private val myViewModel by viewModels<MyViewModel>()
override fun onCreate( savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.my_activity)
val myViewModel = myViewModel
myViewModel.intent = intent
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
myViewModel.intent = intent
}
}
和
class MyFragment: Fragment() {
private val MyViewModel by activityViewModels<MyViewModel>()
...
}
并且您可以使用生命周期所有者 this
在 onCreate 中观察当前意图。
我目前正在开发一款使用 Zebra SDK 的扫描仪应用程序。
在我找到的示例和文档中,onTouchListener 创建了一个新的 Intent(扫描)并广播它。在重写的 onNewIntent 方法中,意图被解码并返回扫描值。
只要我使用 1 activity 并且没有片段,这一切都很好,但是对于我正在创建的应用程序,我希望有 1 activity 和多个片段。 目前一切都发生在 1 activity(和一个视图)中,但这有点混乱并且不是做事的理想方式,所以我最终会拆分 activity。
我尝试创建片段并使用 safeargs 在它们之间传递数据。但我无法弄清楚如何启动意图并从片段中捕获结果。我尝试在我的片段中添加一个 onTouchListener,
下面是 activity 中的当前代码。我没有任何碎片,因为到目前为止我所有的尝试都失败了。
override fun onTouch(view: View?, motionEvent: MotionEvent?): Boolean {
if (view?.getId() == R.id.btnScanner) {
if (motionEvent?.getAction() == MotionEvent.ACTION_DOWN) {
// Button pressed, start scan
val dwIntent = Intent()
dwIntent.action = "com.symbol.datawedge.api.ACTION"
dwIntent.putExtra("com.symbol.datawedge.api.SOFT_SCAN_TRIGGER", "START_SCANNING")
dwIntent.putExtra("Type", "START")
sendBroadcast(dwIntent)
} else if (motionEvent?.getAction() == MotionEvent.ACTION_UP) {
// Button released, end scan
val dwIntent = Intent()
dwIntent.action = "com.symbol.datawedge.api.ACTION"
dwIntent.putExtra("com.symbol.datawedge.api.SOFT_SCAN_TRIGGER", "STOP_SCANNING")
dwIntent.putExtra("Type", "END")
sendBroadcast(dwIntent)
}
}
return true
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
if (intent.getStringExtra("Type") != "START") {
//This would be for the first fragment
if (personId.text.toString().isEmpty()) {
val id = decodeScan((intent))
personId.text = id
lockId()
} else {
//This would be in the second fragment, after the user signed in by scanning his personal barcode
if (productId.hasFocus() || productId.text.isEmpty()) {
val res = decodeScan(intent)
productId.text = res
} else if (locationId.hasFocus() || (locationId.text.isEmpty() && productId.text.isNotEmpty())) {
val res = decodeScan(intent)
val location = (locations.filter { x -> x.contains(res) }).first()
locationId.setText(location)
}
}
}
}
onNewIntent 方法属于 Activity,因此您不能在片段中使用它。您可以做的是,在提供的 onNewIntent 调用时将数据传递给您的片段,您可以引用该片段。
var fragment; //assign default value to fragment
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
// you can add fragment based checks in this method
to work as you want
if (fragment is YourFragment) {
if (intent.getStringExtra("Type") != "START") {
//This would be for the first fragment
if (personId.text.toString().isEmpty()) {
val id = decodeScan((intent))
personId.text = id
lockId()
}
}
}else if (fragment is YourSecondFragment) {{
if (productId.hasFocus() || productId.text.isEmpty()) {
val res = decodeScan(intent)
productId.text = res
} else if (locationId.hasFocus() || (locationId.text.isEmpty() &&
productId.text.isNotEmpty())) {
val res = decodeScan(intent)
val location = (locations.filter { x -> x.contains(res) }).first()
locationId.setText(location)
}
}
}
}
onNewIntent
仅在 Activity 中可用,因此您需要使意图对片段可用。
为此,您可以使用 MutableLiveData 和 ViewModel。
class MyViewModel: ViewModel() {
val intent = MutableLiveData<Intent?>()
}
然后
class MyActivity: AppCompatActivity() {
private val myViewModel by viewModels<MyViewModel>()
override fun onCreate( savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.my_activity)
val myViewModel = myViewModel
myViewModel.intent = intent
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
myViewModel.intent = intent
}
}
和
class MyFragment: Fragment() {
private val MyViewModel by activityViewModels<MyViewModel>()
...
}
并且您可以使用生命周期所有者 this
在 onCreate 中观察当前意图。