I'm getting the following error when trying to get a Module working after updating to React Native 0.18:
com.lwansbrough.RCTCamera.RCTCameraViewManager cannot be cast to
com.facebook.react.uimanager.ViewGroupmanager
What causes this type of error, and how can it be resolved?
Here is the code for RCTCameraViewManager:
package com.lwansbrough.RCTCamera;
import android.support.annotation.Nullable;
import com.facebook.react.uimanager.*;
public class RCTCameraViewManager extends SimpleViewManager<RCTCameraView> {
private static final String REACT_CLASS = "RCTCameraView";
#Override
public String getName() {
return REACT_CLASS;
}
#Override
public RCTCameraView createViewInstance(ThemedReactContext context) {
return new RCTCameraView(context);
}
#ReactProp(name = "aspect")
public void setAspect(RCTCameraView view, int aspect) {
view.setAspect(aspect);
}
#ReactProp(name = "captureMode")
public void setCaptureMode(RCTCameraView view, int captureMode) {
// TODO - implement video mode
}
#ReactProp(name = "captureTarget")
public void setCaptureTarget(RCTCameraView view, int captureTarget) {
// No reason to handle this props value here since it's passed again to the RCTCameraModule capture method
}
#ReactProp(name = "type")
public void setType(RCTCameraView view, int type) {
view.setCameraType(type);
}
#ReactProp(name = "torchMode")
public void setTorchMode(RCTCameraView view, int torchMode) {
view.setTorchMode(torchMode);
}
#ReactProp(name = "flashMode")
public void setFlashMode(RCTCameraView view, int flashMode) {
view.setFlashMode(flashMode);
}
#ReactProp(name = "orientation")
public void setOrientation(RCTCameraView view, int orientation) {
view.setOrientation(orientation);
}
#ReactProp(name = "captureAudio")
public void setCaptureAudio(RCTCameraView view, boolean captureAudio) {
// TODO - implement video mode
}
}
I also got this error, my solution was to change the
public class RCTCameraViewManager extends SimpleViewManager<RCTCameraView>
to
public class RCTCameraViewManager extends ViewGroupManager<RCTCameraView>
Related
How are you? I have a some issues in my project.
Here is my code.
public class ViewManager extends ViewGroupManager<FrameLayout> {
public static final String REACT_CLASS = "RNNativeFlip";
public final int COMMAND_CREATE = 1;
private ReactApplicationContext context;
public ViewManager(ReactApplicationContext context) {
this.context = context;
}
#NonNull
#Override
public String getName() {
return REACT_CLASS;
}
#Override
protected FrameLayout createViewInstance(ThemedReactContext reactContext) {
return new FrameLayout(reactContext);
}
#Nullable
#Override
public Map<String, Integer> getCommandsMap() {
return MapBuilder.of("create", COMMAND_CREATE);
}
#Override
public void receiveCommand(
#NonNull FrameLayout root,
int commandId,
#Nullable ReadableArray args
) {
super.receiveCommand(root, commandId, args);
int reactNativeViewId = args.getInt(0);
int commandIdInt = commandId;
switch (commandIdInt) {
case COMMAND_CREATE:
createFragment(root, reactNativeViewId);
break;
default: {}
}
}
public void createFragment(FrameLayout root, int reactNativeViewId) {
final MainFragment myFragment = new MainFragment();
FragmentActivity activity;
activity = (FragmentActivity) this.context.getCurrentActivity();
activity.getSupportFragmentManager()
.beginTransaction()
.replace(reactNativeViewId, myFragment, String.valueOf(reactNativeViewId))
.commit();
}
}
No longer possible to access Activity from getCurrentActivity()
I know one method to use ReactContextBaseJavaModule but I don't know how to use this in ViewManger.
Please help me. Thank you
I'm getting NullPointerException while using setText() inside OnBindViewHolder() while implementing recyclerview. I've debugged the entire code but not getting the solution. Please Explain why the 'holder.articleName' is thrown as null object?
Adapter Class:
public class ArticleListAdapter extends RecyclerView.Adapter<ArticleItemViewHolder> {
String[] articles = {
"article1",
"article2",
"article3",
"article4",
"article5"
};
#NonNull
#Override
public ArticleItemViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_article_list, parent, false);
return new ArticleItemViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ArticleItemViewHolder holder, final int position) {
holder.articleName.setText(articles[position]);
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(ArticleListActivity.this, "Article Clicked", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return articles.length;
}
}
ViewHolder Class:
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
public class ArticleItemViewHolder extends RecyclerView.ViewHolder{
TextView articleName;
CardView cardView;
public ArticleItemViewHolder(View itemView) {
super(itemView);
this.articleName = itemView.findViewById(R.id.articleName);
this.cardView = itemView.findViewById(R.id.cardView);
}
}
Make sure the layout which has the TextView articleName is in the Layout page referenced here R.layout.activity_article_list and not any other layout page!
I know when we need a nativeUI component we need override function
getName()and
createViewInstance(ThemedReactContext context) But when I use a dependence about map. The API need me use the component like this
#Override
protected void onDestroy() {
super.onDestroy();
//在activity执行onDestroy时执行mMapView.onDestroy(),
mMapView.onDestroy();
}
#Override
protected void onResume() {
super.onResume();
//在activity执行onResume时执行mMapView. onResume (),
mMapView.onResume();
}
#Override
protected void onPause() {
super.onPause();
//在activity执行onPause时执行mMapView. onPause (),
mMapView.onPause();
}
}
I override the function getetName()and
createViewInstance(ThemedReactContext context) like this
#Override
public String getName() {
return REACT_CLASS;
}
#Override
public MapView createViewInstance(ThemedReactContext context) {
final ThemedReactContext mapContext = context;
bdMapViewInstance = new MapView(context);
bdMapViewInstance.getMap().setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
ShopResponseInfo shopResponseInfo = (ShopResponseInfo) marker.getExtraInfo().getSerializable(INDENTIFY);
if(shopResponseInfo != null){
String id = shopResponseInfo.getShop_id() + "";
String shop_name = shopResponseInfo.getShop_name() + "";
onReceiveNativeEvent(mapContext,bdMapViewInstance,id,shop_name);
}
return true;
}
});
return bdMapViewInstance;
}
Finally There are some performance question in my app. I don't know whether it is affect on my app's performance. And I don't know how to meet the official suggestion. I don't know how to control the life cycle of nativeUI component for android. Very Thanks.
You can listen to activity life cycle like this in your createViewInstance. You probably want to keep track of listeners and remove them appropriately based on you keep track of your instances.
LifecycleEventListener lifecycleEventListener = new LifecycleEventListener() {
#Override
public void onHostResume() {
}
#Override
public void onHostPause() {
}
#Override
public void onHostDestroy() {
}
};
getReactApplicationContext().addLifecycleEventListener(lifecycleEventListener);
An example of TestModule as explained in the docs of RN. PS Don't forget to use implements LifecycleEventListener
package com.testpackage;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.LifecycleEventListener;
import java.util.Map;
import java.util.HashMap;
public class TestModule extends ReactContextBaseJavaModule implements LifecycleEventListener {
public TestModule(ReactApplicationContext reactContext) {
super(reactContext);
reactContext.addLifecycleEventListener(this);
}
#Override
public void onHostResume() {
}
#Override
public void onHostPause() {
}
#Override
public void onHostDestroy() {
}
}
Intially i was using volley mainly for JSONObject. the following was my singleton
package com.simha.yatras;
import android.app.Application;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
public class MyApplication extends Application {
private RequestQueue mRequestQueue;
private static MyApplication mInstance;
#Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
public static synchronized MyApplication getInstance() {
return mInstance;
}
public RequestQueue getReqQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToReqQueue(Request<T> req, String tag) {
getReqQueue().add(req);
}
public <T> void addToReqQueue(Request<T> req) {
getReqQueue().add(req);
}
public void cancelPendingReq(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}
Now i want to use volley for bitmap imagerequest. I want the images to be cached so that i need not load them everytime.
So what should be the singleton code be.
You can use Volley provide ImageRequest class:
ImageView mImageView;
String url = "http://i.imgur.com/7spzG.png";
mImageView = (ImageView) findViewById(R.id.myImage);
// Retrieves an image specified by the URL, displays it in the UI.
ImageRequest request = new ImageRequest(url,
new Response.Listener<Bitmap>() {
#Override
public void onResponse(Bitmap bitmap) {
mImageView.setImageBitmap(bitmap);
}
}, 0, 0, null,
new Response.ErrorListener() {
public void onErrorResponse(VolleyError error) {
mImageView.setImageResource(R.drawable.image_load_error);
}
});
// Access the RequestQueue through your singleton class.
MySingleton.getInstance(this).addToRequestQueue(request);## Heading ##
I have made a Simple drawing application in android for the learning purpose..In that i have taken diffrent colorbuttons just like a colorpicker in horizontalscrollview,Now i need is when one of them is clicked that particular color should be chosen and pencolor od drawing pen should be changed..I have tried as below,but its not working..Please help me for the same,Thanx in advance...!
main.java
public void onClick(View v) {
switch (v.getId()) {
case R.id.black:
myplate.setVisibility(View.GONE);
mDrawView.setColor(SingleTouchView.DrawingColors.Black);
break;
case R.id.blue:
myplate.setVisibility(View.GONE);
mDrawView.setColor(SingleTouchView.DrawingColors.Blue);
break;
...so on...for other colors
MyView.java
package com.example.singletouch;
import java.util.AbstractMap;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;
import android.R.color;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.Toast;
public class SingleTouchView extends View {
public static int width;
public int height;
public Bitmap mBitmap;
public Canvas mCanvas;
public Path mPath;
public Paint mBitmapPaint;
Context context;
public Paint mPaint;
public Paint circlePaint;
public Path circlePath;
public enum DrawingPens {
PEN_1(6), PEN_2(4), PEN_3(2), PEN_4(1);
public Paint mPaint;
private DrawingPens(final int width) {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(width);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
}
Paint getPaint() {
return mPaint;
}
}
public enum DrawingColors{
Black(Color.parseColor("#000000")),Blue(Color.parseColor("#0000FF")),Cofee(Color.parseColor("#D2691E")),Cyan(Color.parseColor("#00FFFF"))
,Fuchiya(Color.parseColor("#FF00FF")),Gray(Color.parseColor("#808080")),Green(Color.parseColor("#00FF00")),Indigo(Color.parseColor("#4B0082")),
Khaki(Color.parseColor("#F0E68C")),Lavendar(Color.parseColor("#E6E6FA")),Magenta(Color.parseColor("#FF00FF")),Mango(Color.parseColor("#FF8C00"))
,Maroon(Color.parseColor("#800000")),Orange(Color.parseColor("#FFA500")),Pink(Color.parseColor("#FFC0CB")),Pista(Color.parseColor("#9ACD32")),
Purple(Color.parseColor("#800080")),Red(Color.parseColor("#FF0000")),Tan(Color.parseColor("#0000A0")),Yellow(Color.parseColor("#FFD801"));
public Paint mPaint;
private DrawingColors(final int color) {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(width);
mPaint.setColor(color);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
}
Paint getPaint() {
return mPaint;
}
}
public SingleTouchView(final Context context) {
super(context);
init(context);
}
public SingleTouchView(final Context context, final AttributeSet attrs) {
super(context, attrs);
init(context);
mBitmap = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFFFF0000);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
}
public SingleTouchView(final Context context, final AttributeSet attrs,
final int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private ConcurrentLinkedQueue<Map.Entry<Path, DrawingPens>> mPaths = new ConcurrentLinkedQueue<Map.Entry<Path, DrawingPens>>();
private ConcurrentLinkedQueue<Map.Entry<Path, DrawingColors>> mPaths1 = new ConcurrentLinkedQueue<Map.Entry<Path, DrawingColors>>();
private Path mCurrentPath;
private void init(final Context context) {
setPen(DrawingPens.PEN_1);
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (Map.Entry<Path, DrawingPens> entry : mPaths) {
canvas.drawPath(entry.getKey(), entry.getValue().getPaint());
}
}
#Override
public boolean onTouchEvent(MotionEvent me) {
float eventX = me.getX();
float eventY = me.getY();
switch (me.getAction()) {
case MotionEvent.ACTION_DOWN:
mCurrentPath.moveTo(eventX, eventY);
return true;
case MotionEvent.ACTION_MOVE:
mCurrentPath.lineTo(eventX, eventY);
break;
case MotionEvent.ACTION_UP:
break;
}
invalidate();
return true;
}
public void setPen(final DrawingPens pen) {
mCurrentPath = new Path();
mPaths.add(new AbstractMap.SimpleImmutableEntry<Path, DrawingPens>(
mCurrentPath, pen));
}
public void eraser() {
// TODO Auto-generated method stub
mPaint = new Paint();
/* Toast.makeText(getContext(), "eraser", Toast.LENGTH_LONG).show();
mPaint.setXfermode(null);
mPaint.setAlpha(0x00FFFFFF);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));*/
// invalidate();
}
public void setColor(final DrawingColors color ) {
mCurrentPath = new Path();
mPaths1.add(new AbstractMap.SimpleImmutableEntry<Path, DrawingColors>(
mCurrentPath, color));
}
}
Please help me friends..please...
still a bit unclear but I will try to give you a direction. What happens if you try the below onDraw method? I have a feeling you have not set the colors. The code is a bit messy and not clear to read. Don't worry for now about the performance, creating a new paint every time, just want to make sure it give's you the wanted result.
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
for (Map.Entry<Path, DrawingPens> entry : mPaths) {
canvas.drawPath(entry.getKey(), paint);
}
}