skip to Main Content

I have created native android view and it needs to wrap child components from react-native

I am using a TouchableOpacity as a child to the native android view which I created. When the screen loads the TouchableOpacity takes the whole width and height and which is not what I want but as soon as I comment and uncomment the width style of TouchableOpacity it relayout correctly. So in short as soon as Fast refresh is done the layout looks proper, not sure what the issue here is. Even giving a fix height to TouchableOpacity does not work

Layout when the app first loads

enter image description here

Layout when fast refresh is done by commenting and uncommenting the TouchableOpacity's width

enter image description here

Here is the code

class CealGradientView(context: Context): LinearLayout(context){

    fun configureViews(color: ReadableArray){
        val layoutParams: ViewGroup.LayoutParams =
            LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
        setLayoutParams(layoutParams)


        val colorsCollection: ArrayList<Int> = ArrayList()
        for (i in 0 until color.size()) {
            colorsCollection.add(Color.parseColor(color.getString(i)))
        }
        val colors = colorsCollection.stream().mapToInt { i -> i }.toArray()
        val gradientDrawable = GradientDrawable(
            GradientDrawable.Orientation.TOP_BOTTOM,
            colors
        )
        background = gradientDrawable
}

class CealGradientManager(private val reactApplicationContext: ReactApplicationContext):
    ViewGroupManager<CealGradientView>() {

    private val cealGradientView = "CealGradientView"

    override fun getName() = cealGradientView

    override fun createViewInstance(reactContext: ThemedReactContext): CealGradientView {
        return CealGradientView(reactContext)
    }

    @ReactProp(name = "colors")
    fun configureView(view: CealGradientView, color: ReadableArray) {
        view.configureViews(color)
    }
}

<CealGradientView colors={[theme.Primary_50, theme.Information]} style={styles.linearGradient}>
<BorderButton text={EXISTING_USER} onPress={() => {}} isDarkMode={isDarkMode} />
    </CealGradientView>

const BorderButton = ({ text, isDarkMode, onPress }: Props) => {
  const theme = THEME_COLOR.SET(isDarkMode)

  return (
    <TouchableOpacity style={[styles.buttonStyle, { borderColor: theme.White }]} onPress={onPress}>
      <Text style={[styles.textStyle, { color: theme.White }]}>{text}</Text>
    </TouchableOpacity>
  )
}

const styles = StyleSheet.create({
  buttonStyle: {
    width: '100%',
    borderRadius: 8,
    alignItems: 'center',
    borderWidth: 1,
  },
  textStyle: {
    fontFamily: Fonts.InterSemiBold,
    fontSize: 16,
    lineHeight: 48,
    textTransform: 'uppercase',
  },
})

I have trying following this issue and tried some of the solutions mentioned but no luck

Sample reo https://github.com/PritishSawant/NativeAndroidLinearGradient

I have also tried adding following code but it does not work

private fun setupLayout() {
        Choreographer.getInstance().postFrameCallback(object: Choreographer.FrameCallback {
            override fun doFrame(frameTimeNanos: Long) {
                manuallyLayoutChildren()
                viewTreeObserver.dispatchOnGlobalLayout()
                Choreographer.getInstance().postFrameCallback(this)
            }
        })
    }

    /**
     * Layout all children properly
     */
    private fun manuallyLayoutChildren() {
        for (i in 0 until childCount) {
            val child = getChildAt(i)
            child.measure(MeasureSpec.makeMeasureSpec(measuredWidth, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(measuredHeight, MeasureSpec.EXACTLY))
            child.layout(0, 0, child.measuredWidth, child.measuredHeight)
        }
    }

2

Answers


  1. if your problem solved with commenting width, so instead of {{width:’100%’}} use {{width}} =>

    const {width, height} = Dimensions.get('window');
    
    Login or Signup to reply.
  2. I already encountered a similar problem, but working in Java. So i’ll try my best to help you but my code may contains mistakes.

    I resolved it by adding self measuring logic to my Layout, you can try adding it too and see if it helps.

    Add the following methods to your CealGradientView class :

    override fun requestLayout() {
        super.requestLayout()
        post(measureAndLayout)
    }
    
    private val measureAndLayout = Runnable {
        measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY))
        layout(left, top, right, bottom)
    }
    

    see this old SO answer for Java equivalent, hope it helps !

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search