Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package com.rcttabview

import android.content.res.ColorStateList
import android.graphics.Color
import android.util.Log
import android.view.View.MeasureSpec
import com.facebook.react.bridge.ReadableArray
import com.facebook.react.common.MapBuilder
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.LayoutShadowNode
import com.facebook.react.uimanager.SimpleViewManager
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.UIManagerHelper
import com.facebook.react.uimanager.UIManagerModule
import com.facebook.react.uimanager.annotations.ReactProp
import com.facebook.react.uimanager.events.EventDispatcher
Expand All @@ -24,16 +23,14 @@ data class TabInfo(
val badge: String
)

@ReactModule(name = RCTTabViewViewManager.NAME)
class RCTTabViewViewManager :
SimpleViewManager<ReactBottomNavigationView>() {
private lateinit var eventDispatcher: EventDispatcher
class RCTTabViewImpl {

override fun getName(): String {
private lateinit var eventDispatcher: EventDispatcherWrapper
private var tabView: ReactBottomNavigationView? = null
fun getName(): String {
return NAME
}

@ReactProp(name = "items")
fun setItems(view: ReactBottomNavigationView, items: ReadableArray) {
val itemsArray = mutableListOf<TabInfo>()
for (i in 0 until items.size()) {
Expand All @@ -50,20 +47,19 @@ class RCTTabViewViewManager :
view.updateItems(itemsArray)
}

@ReactProp(name = "selectedPage")

fun setSelectedPage(view: ReactBottomNavigationView, key: String) {
view.items?.indexOfFirst { it.key == key }?.let {
view.selectedItemId = it
}
}


@ReactProp(name = "labeled")
fun setLabeled(view: ReactBottomNavigationView, flag: Boolean?) {
view.setLabeled(flag)
}

@ReactProp(name = "icons")

fun setIcons(view: ReactBottomNavigationView, icons: ReadableArray?) {
view.setIcons(icons)
}
Expand All @@ -80,85 +76,45 @@ class RCTTabViewViewManager :
view.setRippleColor(color)
}
}

@ReactProp(name = "translucent")
fun setTranslucentview(view: ReactBottomNavigationView, translucent: Boolean?) {
}

public override fun createViewInstance(context: ThemedReactContext): ReactBottomNavigationView {
eventDispatcher = context.getNativeModule(UIManagerModule::class.java)!!.eventDispatcher

fun createViewInstance(context: ThemedReactContext): ReactBottomNavigationView {
val view = ReactBottomNavigationView(context)
view.onTabSelectedListener = { data ->
tabView = view
eventDispatcher = EventDispatcherWrapper(context)
view?.onTabSelectedListener = { data ->
data.getString("key")?.let {
eventDispatcher.dispatchEvent(PageSelectedEvent(viewTag = view.id, key = it))
}
}
return view
}


class TabViewShadowNode() : LayoutShadowNode(),
YogaMeasureFunction {
private var mWidth = 0
private var mHeight = 0
private var mMeasured = false

init {
initMeasureFunction()
}

private fun initMeasureFunction() {
setMeasureFunction(this)
}

override fun measure(
node: YogaNode,
width: Float,
widthMode: YogaMeasureMode,
height: Float,
heightMode: YogaMeasureMode
): Long {
if (mMeasured) {
return YogaMeasureOutput.make(mWidth, mHeight)
}

val tabView = ReactBottomNavigationView(themedContext)
val spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
tabView.measure(spec, spec)
this.mWidth = tabView.measuredWidth
this.mHeight = tabView.measuredHeight
this.mMeasured = true

return YogaMeasureOutput.make(mWidth, mHeight)
}
}

override fun createShadowNodeInstance(): LayoutShadowNode {
return TabViewShadowNode()
fun getViewInstance(): ReactBottomNavigationView? {
return if(tabView!=null)
tabView
else
null
}

companion object {
const val NAME = "RCTTabView"
}
// iOS Props

override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any>? {
return MapBuilder.of(
PageSelectedEvent.EVENT_NAME,
MapBuilder.of("registrationName", "onPageSelected"),
)
fun setSidebarAdaptable(view: ReactBottomNavigationView, flag: Boolean) {
}

// iOS Props
fun setScrollEdgeAppearance(view: ReactBottomNavigationView, value: String) {

@ReactProp(name = "sidebarAdaptable")
fun setSidebarAdaptable(view: ReactBottomNavigationView, flag: Boolean) {
}

@ReactProp(name = "ignoresTopSafeArea")
fun setIgnoresTopSafeArea(view: ReactBottomNavigationView, flag: Boolean) {
}

@ReactProp(name = "disablePageAnimations")

fun setDisablePageAnimations(view: ReactBottomNavigationView, flag: Boolean) {
}
}
2 changes: 1 addition & 1 deletion android/src/main/java/com/rcttabview/RCTTabViewPackage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import java.util.ArrayList
class RCTTabViewPackage : ReactPackage {
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
val viewManagers: MutableList<ViewManager<*, *>> = ArrayList()
viewManagers.add(RCTTabViewViewManager())
viewManagers.add(RCTTabViewManager(reactContext))
return viewManagers
}

Expand Down
43 changes: 43 additions & 0 deletions android/src/main/java/com/rcttabview/TabViewShadowNode.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.rcttabview

import android.view.View.MeasureSpec
import com.facebook.react.uimanager.LayoutShadowNode
import com.facebook.yoga.YogaMeasureFunction
import com.facebook.yoga.YogaMeasureMode
import com.facebook.yoga.YogaMeasureOutput
import com.facebook.yoga.YogaNode

class TabViewShadowNode(tabview: ReactBottomNavigationView?) : LayoutShadowNode(),
YogaMeasureFunction {
private var mWidth = 0
private var mHeight = 0
private var mMeasured = false
private var mTabView = tabview
init {
initMeasureFunction()
}

private fun initMeasureFunction() {
setMeasureFunction(this)
}

override fun measure(
node: YogaNode,
width: Float,
widthMode: YogaMeasureMode,
height: Float,
heightMode: YogaMeasureMode
): Long {
if (mMeasured) {
return YogaMeasureOutput.make(mWidth, mHeight)
}
val tempTabView = mTabView?: ReactBottomNavigationView(themedContext)
val spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
tempTabView.measure(spec, spec)
this.mWidth = tempTabView.measuredWidth
this.mHeight = tempTabView.measuredHeight
this.mMeasured = true

return YogaMeasureOutput.make(mWidth, mHeight)
}
}
79 changes: 79 additions & 0 deletions android/src/main/jni/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
cmake_minimum_required(VERSION 3.13)
set(CMAKE_VERBOSE_MAKEFILE ON)

set(LIB_LITERAL RCTTabView)
set(LIB_TARGET_NAME react_codegen_${LIB_LITERAL})

set(LIB_ANDROID_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
set(LIB_COMMON_DIR ${LIB_ANDROID_DIR}/../common/cpp)
set(LIB_ANDROID_GENERATED_JNI_DIR ${LIB_ANDROID_DIR}/build/generated/source/codegen/jni)
set(LIB_ANDROID_GENERATED_COMPONENTS_DIR ${LIB_ANDROID_GENERATED_JNI_DIR}/react/renderer/components/${LIB_LITERAL})

add_compile_options(
-fexceptions
-frtti
-std=c++20
-Wall
-Wpedantic
-Wno-gnu-zero-variadic-macro-arguments
)

file(GLOB LIB_CUSTOM_SRCS CONFIGURE_DEPENDS *.cpp ${LIB_COMMON_DIR}/react/renderer/components/${LIB_LITERAL}/*.cpp)
file(GLOB LIB_CODEGEN_SRCS CONFIGURE_DEPENDS ${LIB_ANDROID_GENERATED_JNI_DIR}/*.cpp ${LIB_ANDROID_GENERATED_COMPONENTS_DIR}/*.cpp)

add_library(
${LIB_TARGET_NAME}
SHARED
${LIB_CUSTOM_SRCS}
${LIB_CODEGEN_SRCS}
)

target_include_directories(
${LIB_TARGET_NAME}
PUBLIC
.
${LIB_COMMON_DIR}
${LIB_ANDROID_GENERATED_JNI_DIR}
${LIB_ANDROID_GENERATED_COMPONENTS_DIR}
)

target_link_libraries(
${LIB_TARGET_NAME}
fbjni
folly_runtime
glog
jsi
react_codegen_rncore
react_debug
react_render_componentregistry
react_render_core
react_render_debug
react_render_graphics
react_render_imagemanager
react_render_mapbuffer
react_render_textlayoutmanager
react_utils
react_nativemodule_core
rrc_image
turbomodulejsijni
rrc_text
rrc_textinput
rrc_view
yoga
)

target_compile_options(
${LIB_TARGET_NAME}
PRIVATE
-DLOG_TAG=\"ReactNative\"
-fexceptions
-frtti
-std=c++20
-Wall
)

target_include_directories(
${CMAKE_PROJECT_NAME}
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)
19 changes: 19 additions & 0 deletions android/src/main/jni/RCTTabView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include <ReactCommon/JavaTurboModule.h>
#include <ReactCommon/TurboModule.h>
#include <jsi/jsi.h>
#include <react/renderer/components/RCTTabView/RCTTabViewComponentDescriptor.h>

namespace facebook
{
namespace react
{

JSI_EXPORT
std::shared_ptr<TurboModule> RCTTabView_ModuleProvider(
const std::string &moduleName,
const JavaTurboModule::InitParams &params);

} // namespace react
} // namespace facebook
13 changes: 13 additions & 0 deletions android/src/newarch/EventDispatcherWrapper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.rcttabview

import com.facebook.react.bridge.ReactContext
import com.facebook.react.uimanager.UIManagerHelper
import com.facebook.react.uimanager.events.Event
import com.facebook.react.uimanager.events.EventDispatcher

class EventDispatcherWrapper(context: ReactContext) {
var context: ReactContext = context
fun dispatchEvent(event: Event<PageSelectedEvent>) {
UIManagerHelper.getEventDispatcherForReactTag(context, event.viewTag)?.dispatchEvent(event)
}
}
Loading
Loading