can a SurfaceView be rendered inside a RecyclerView
EDIT: even this fails to render inside of a RecyclerView: https://github.com/android/ndk-samples/tree/master/hello-gl2
EDIT2: https://github.com/mgood7123/RecyclerViewSurfaceViewGrid minimal example demonstrating the issue
// public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback2 {
// class GL2JNIView extends GLSurfaceView {
GL2JNIView mView;
public ViewGroup onViewRequest(Context mContext) {
if (context == null) context = mContext;
mView = new GL2JNIView(context);
RelativeLayout rel = new RelativeLayout(context);
rel.addView(mView);
mView.onResume();
return rel;
}
public ViewGroup onViewRequest_(Context mContext) {} // old openGL Cube
what i am trying to do is make a Grid of SurfaceView's
@Keep
public class NativeView {
String TAG = "EglSample";
public static native void nativeOnStart();
public static native void nativeOnResume();
public static native void nativeOnPause();
public static native void nativeOnStop();
// this is part of graphics manager
public native void nativeSetSurface(Surface surface);
View surfaceView = null;
SurfaceHolderCallback surfaceHolderCallback = null;
public NativeView(Context context) {
System.loadLibrary("nativeegl");
surfaceHolderCallback = new SurfaceHolderCallback();
surfaceView = new View(surfaceHolderCallback, context);
}
class View extends SurfaceView {
public View(SurfaceHolder.Callback callback, Context context) {
super(context);
getHolder().addCallback(callback);
}
public View(SurfaceHolder.Callback callback, Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(callback);
}
public View(SurfaceHolder.Callback callback, Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
getHolder().addCallback(callback);
}
public View(SurfaceHolder.Callback callback, Context context, AttributeSet attrs, int defStyle, int defStyleRes) {
super(context, attrs, defStyle, defStyleRes);
getHolder().addCallback(callback);
}
}
class SurfaceHolderCallback implements SurfaceHolder.Callback {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
nativeSetSurface(holder.getSurface());
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
nativeSetSurface(null);
}
}
}
public ViewGroup onViewRequest(Context mContext) {
if (context == null) context = mContext;
if (n == null) n = new NativeView(context);
Log.i(n.TAG, "onViewRequest(Activity, Context)");
// build layout
RelativeLayout rel = new RelativeLayout(context);
rel.addView(n.surfaceView);
n.surfaceView.setOnClickListener(new MyListener());
// set text
TextView text = new TextView(context);
text.setText("Hello World! Try clicking the screen");
text.setTextSize(60f);
text.setTextColor(Color.WHITE);
rel.addView(text);
Log.i(n.TAG, "onCreate()");
// build layout
NativeView.nativeOnStart();
NativeView.nativeOnResume();
return rel;
}
full:
as it renders corrupted in a recycler view (text but no surface view) (you can barely make out the white text but the fact that it is there means the view heirarchy IS being drawn)
(set USE_RECYCLER_VIEW = true)
Boolean USE_RECYCLER_VIEW = false;
public LinearLayout getView() {
// this assumes the first available "*\.addons\.*" package
if (!USE_RECYCLER_VIEW) {
VST pkg = mVstMan.loadPackage(mActivity, mVstMan.getPackages(mActivity)[0].packageName, false);
VST.CLASS vstClass = mVstMan.loadClass(pkg, "main");
Object vstClassInstance = mVstMan.newInstance(vstClass, "main");
// android.widget.RelativeLayout cannot be cast to android.widget.LinearLayout
LinearLayout x = new LinearLayout(mActivity);
x.addView((ViewGroup) mVstMan.invokeMethod(
vstClass, vstClassInstance,
"onViewRequest", Context.class,
pkg.activityApplicationContext
)
);
return x;
} else {
if (recyclerViewMain == null)
recyclerViewMain = (LinearLayout) LayoutInflater.from(mActivity.getApplicationContext())
.inflate(R.layout.vst_grid, null, false);
if (recyclerView == null) {
recyclerView = recyclerViewMain
.findViewById(R.id.VstGrid);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerView.setHasFixedSize(true);
}
if (layoutManager == null) {
// use a linear layout manager
layoutManager = new GridLayoutManager(mActivity, 1);
recyclerView.setLayoutManager(layoutManager);
}
if (mAdapter == null) {
// specify an adapter (see also next example)
mAdapter = new VstGridAdapter(mActivity, mVstMan, mVstUI);
recyclerView.setAdapter(mAdapter);
}
mAdapter.update();
return recyclerViewMain;
}
}
// Create new views (invoked by the layout manager)
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
VST pkg = mVstMan.loadPackage(mActivity, mVstMan.getPackages(mActivity)[0].packageName, false);
VST.CLASS vstClass = mVstMan.loadClass(pkg, "main");
Object vstClassInstance = mVstMan.newInstance(vstClass, "main");
// android.widget.RelativeLayout cannot be cast to android.widget.LinearLayout
LinearLayout x = new LinearLayout(mActivity);
x.addView((ViewGroup) mVstMan.invokeMethod(
vstClass, vstClassInstance,
"onViewRequest", Context.class,
pkg.activityApplicationContext
)
);
return new MyViewHolder(x);
}
meanwhile it renders perfectly fine if NOT in a recycler view (leave USE_RECYCLER_VIEW as false)
why?
apparently in order to get it to display i needed to give the view fixed size layout paramaters: mView.setLayoutParams(new ViewGroup.LayoutParams(500, 500));