bounty将在4天后过期。回答此问题可获得+500声望奖励。BraveEvidence希望引起更多人关注此问题。
我正在尝试将Android Fragment与react native的新架构结构集成。我正在遵循here上的指南,不幸的是,他们没有指定任何用于集成fragment的文档,因此我正在here上从旧架构中获取帮助
我创建了以下Kotlin文件,添加typescript接口的其余代码保持不变
class CenteredText(context: Context): LinearLayout(context){
private var textView: TextView
private var secondtextView: TextView
init {
val layoutParams: ViewGroup.LayoutParams =
LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
setLayoutParams(layoutParams)
orientation = VERTICAL
textView = TextView(context)
addView(textView)
secondtextView = TextView(context)
addView(secondtextView)
secondtextView.text = "Hello I am second"
secondtextView.textSize = 25F
secondtextView.setTextColor(Color.RED)
}
fun configureText(text: String){
textView.text = text
}
}
class CenteredTextManager(private val context: ReactApplicationContext) :
ViewGroupManager<FrameLayout>() {
private val create = "create"
private var propWidth: Int? = null
private var propHeight: Int? = null
override fun getName(): String {
return NAME
}
override fun createViewInstance(reactContext: ThemedReactContext) = FrameLayout(reactContext)
companion object {
const val NAME = "RTNCenteredText"
private const val COMMAND_CREATE = 1
}
override fun getCommandsMap() = mapOf(create to COMMAND_CREATE)
override fun receiveCommand(root: FrameLayout, commandId: String?, args: ReadableArray?) {
super.receiveCommand(root, commandId, args)
val reactNativeViewId = requireNotNull(args).getInt(0)
Log.i("argumentsare", args.toString())
when (commandId?.toInt()) {
COMMAND_CREATE -> createFragment(root, reactNativeViewId)
}
}
private fun setupLayout(view: View) {
Choreographer.getInstance().postFrameCallback(object : Choreographer.FrameCallback {
override fun doFrame(frameTimeNanos: Long) {
manuallyLayoutChildren(view)
view.viewTreeObserver.dispatchOnGlobalLayout()
Choreographer.getInstance().postFrameCallback(this)
}
})
}
private fun manuallyLayoutChildren(view: View) {
// propWidth and propHeight coming from react-native props
val width = requireNotNull(propWidth)
val height = requireNotNull(propHeight)
view.measure(
View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)
)
view.layout(0, 0, width, height)
}
private fun createFragment(root: FrameLayout, reactNativeViewId: Int) {
val parentView = root.findViewById<ViewGroup>(reactNativeViewId)
setupLayout(parentView)
val myFragment = CenteredTextFragment()
val activity = context.currentActivity as FragmentActivity
activity.supportFragmentManager
.beginTransaction()
.replace(reactNativeViewId, myFragment, reactNativeViewId.toString())
.commit()
}
}
class CenteredTextFragment: Fragment() {
private lateinit var centeredText: CenteredText
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
super.onCreateView(inflater, container, savedInstanceState)
centeredText = CenteredText(requireNotNull(context))
return centeredText // this CustomView could be any view that you want to render
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
override fun onDestroy() {
super.onDestroy()
}
}
class CenteredTextPackage : ReactPackage {
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
return Collections.singletonList(CenteredTextManager(reactContext))
}
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
return emptyList()
}
}
完整的源代码在here
1条答案
按热度按时间kadbb4591#
尝试设置
com.facebook.react.bridge.UiThreadUtil#assertOnUiThread
在做之前
添加到后栈()。
另一个可能的解决方案是覆盖片段中的
onResume
和onPause
函数,并强制它们分别调用getReactInstanceManager().onHostResume(getActivity(), this);
和getReactInstanceManager().onHostPause(getActivity());
。或者,如果您不想使用Fabric,请更改应用程序onCreate方法
ReactNativeHost.getUseFabric()
以返回false
。