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
Layout when fast refresh is done by commenting and uncommenting the TouchableOpacity's
width
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
if your problem solved with commenting width, so instead of {{width:’100%’}} use {{width}} =>
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 :
see this old SO answer for Java equivalent, hope it helps !