I am creating android native components to be used in my react-native project.My native component is composed of parent view and one child button. I want to add listener on the button that will pass data on react-native side when click.
I follow this blog: native-components in android
here is the xml file:
<com.rnlibraryplayground.MyCustomView xmlns:android="http://schemas.android.com/apk/res/android" android:minHeight="150dp" android:minWidth="150dp" android:background="#FD5C08" android:layout_width="fill_parent" android:layout_height="fill_parent"><Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button" /></com.rnlibraryplayground.MyCustomView >
MyCustomView.java
package com.rnlibraryplayground;import android.content.Context;import android.util.Log;import android.view.LayoutInflater;import android.widget.Button;import android.graphics.Color;import android.util.AttributeSet;import android.view.View;import android.widget.RelativeLayout;import com.facebook.react.bridge.Arguments;import com.facebook.react.bridge.LifecycleEventListener;import com.facebook.react.bridge.ReactContext;import com.facebook.react.bridge.WritableMap;import com.facebook.react.uimanager.events.RCTEventEmitter;public class MyCustomView extends RelativeLayout implements LifecycleEventListener { public MyCustomView view; public Object jsonData; public String data; public String sample; private Context mainContext; private Button isButton; private boolean status = false; public MyCustomView(ReactContext context) { super(context); LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = (MyCustomView)inflater.inflate(R.layout.custom_view, null); context.addLifecycleEventListener(this); } public MyCustomView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public MyCustomView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onFinishInflate() { super.onFinishInflate(); isButton = view.findViewById(R.id.button); isButton.setText("Click Me"); isButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { clickItem(); } }); } public void setStatus(boolean status) { this.status = status; setBackgroundColor( this.status ? Color.GREEN : Color.RED); } public void clickItem() { Log.d("MyView", "item clicked"); final Context context = getContext(); if (context instanceof ReactContext) { WritableMap event = Arguments.createMap(); event.putString("custom view", "customview press"); ((ReactContext) context).getJSModule(RCTEventEmitter.class) .receiveEvent(getId(),"clickItem", event); } } @Override public void onHostResume() { } @Override public void onHostPause() { } @Override public void onHostDestroy() { }}
MyCustomViewManager.java
package com.rnlibraryplayground;import androidx.annotation.Nullable;import com.facebook.react.uimanager.ViewGroupManager;import com.facebook.react.common.MapBuilder;import com.facebook.react.uimanager.ThemedReactContext;import com.facebook.react.uimanager.annotations.ReactProp;import java.util.Map;public class MyCustomViewManager extends ViewGroupManager<MyCustomView> { public static final String REACT_CLASS = "RCTTouchView"; @Override public String getName() { return REACT_CLASS; } @Override public MyCustomView createViewInstance(ThemedReactContext context) { MyCustomView customView = new MyCustomView(context); return customView.view; } @ReactProp(name = "status") public void setStatus(MyCustomView view, Boolean status){} @Override public @Nullable Map getExportedCustomDirectEventTypeConstants() { return MapBuilder.of("clickItem", MapBuilder.of("registrationName", "clickItem") ); }}
Here, I added my button listener inside onFinishInflate()
method. But it's not working.