3

I am trying to add a custom view class to go above my camera preview.

But I cant get it to work.Even adding just customview = new CustomView(this) does not work. I get error: CustomView(com.example.android.camera2video.Camera2VideoFragment) CustomView cannot be applied to (com.example.android.camera2video.CameraAvticity)

Here is my code,

CustomView.java

public class CustomView extends SurfaceView {

    private final Paint paint;
    private final SurfaceHolder mHolder;
    private final Context context;

    public CustomView(Camera2VideoFragment context) {
        super(context.getActivity().getBaseContext());
        mHolder = getHolder();
        mHolder.setFormat(PixelFormat.TRANSPARENT);
        this.context = context.getActivity().getBaseContext();
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.STROKE);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            invalidate();
            if (mHolder.getSurface().isValid()) {
                final Canvas canvas = mHolder.lockCanvas();
                Log.d("touch", "touchRecieved by camera");
                if (canvas != null) {
                    Log.d("touch", "touchRecieved CANVAS STILL Not Null");
                    canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
                    canvas.drawColor(Color.TRANSPARENT);
                    canvas.drawCircle(event.getX(), event.getY(), 100, paint);
                    mHolder.unlockCanvasAndPost(canvas);
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            Canvas canvas1 = mHolder.lockCanvas();
                            if(canvas1 !=null){
                                canvas1.drawColor(0, PorterDuff.Mode.CLEAR);
                                mHolder.unlockCanvasAndPost(canvas1);
                            }

                        }
                    }, 1000);

                }
                mHolder.unlockCanvasAndPost(canvas);


            }
        }


        return false;

CameraActivity.java

package com.example.android.camera2video;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;

public class CameraActivity extends Activity {
    private  Context context;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        customview = new CustomView(this);
        setContentView(R.layout.activity_camera);
        if (null == savedInstanceState) {
            getFragmentManager().beginTransaction()
                    .replace(R.id.container, Camera2VideoFragment.newInstance())
                    .commit();
        }
    }

}
David
  • 315
  • 3
  • 14
  • You made a constructor that takes a Camera2VideoFragment as argument but in code you pass it a MainActivity instance. – RobCo May 27 '17 at 08:21
  • Read https://stackoverflow.com/questions/12273976/camera-tutorial-for-android-using-surfaceview – IntelliJ Amiya May 27 '17 at 08:51

3 Answers3

2

Constructor permits widening conversions to occur when matching the actual parameters to newInstance() with the underlying constructor's formal parameters . So A class contains constructors that are invoked to create objects from the class blueprint .

Do Not

 public CustomView(Camera2VideoFragment context) 
   {
    super(context.getActivity().getBaseContext());  
    ........

Your Constructor expects Activity Context instead of Fragment getactivity .

DO

 public CustomView(Context context) {
 super(context);

FYI

It will be better if you call customview after setContentView.

    setContentView(R.layout.activity_camera);
    customview = new CustomView(this);
IntelliJ Amiya
  • 74,896
  • 15
  • 165
  • 198
  • got it thanks.. now it runs but i see the layout in black and when i touch it the app crashes, ill make a question regarding it. off topic for this therad – David May 27 '17 at 09:42
1

You have created a custom view by customview = new CustomView(this); but you are not adding this view to your layout. You have to add this view where you want. Maybe add it to your root ViewGroup. In other words you haven't used this customView anywhere, thats why its not showing.

Change your constructor to this..

 public CustomView(Context context) {
    super(context);
    mHolder = getHolder();
    mHolder.setFormat(PixelFormat.TRANSPARENT);
    this.context = context;
    paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setColor(Color.WHITE);
    paint.setStyle(Paint.Style.STROKE);

}

To add it to your rootview

final ViewGroup viewGroup = (ViewGroup) ((ViewGroup) this.findViewById(android.R.id.content)).getChildAt(0);
viewGroup.addView(new CustomView(this));
Hammad Akram
  • 573
  • 3
  • 9
  • even before adding it to layout, upon adding customview = new CustomView(this); to OnCreate, I get error: Custom View(com.example.android.camera2video.Camera2VideoFragment) CustomView cannot be applied to (com.example.android.camera2video.CameraAvticity) – David May 27 '17 at 08:18
  • i changed the class as you said, can you tell me what to change in the OnCredate method plz? – David May 27 '17 at 08:41
  • I gave you a view group code for on create. Use that. – Hammad Akram May 27 '17 at 09:08
  • Can you explain where to put the view code (just add to oncreate method?) and how does it work with the layout xml? Do i add anything in layout? I never tried to do view over another view – David May 27 '17 at 11:56
1

It doesn't work because your custom view constructor takes a Camera2VideoFragment class instead of an activity.

public CustomView(Camera2VideoFragment context) {...}

When you call new CustomView(this/* is Activity not Camera2VideoFragment */) you are passing an instance of Activity when it actually expects Camera2VideoFragment. There is no relationship of inheritance between the two so as a result, you get compile time error.
To make it work you have 3 options:

  1. Pass an instance of Camera2VideoFragment
  2. Change the constructor parameter from Camera2VideoFragment to Activity
  3. Make your activity to extend Camera2VideoFragment
Tudor
  • 1,510
  • 1
  • 18
  • 17
  • change it to customview = new CustomView(Camera2VideoFragment.newInstance()); is good? – David May 27 '17 at 08:28
  • no erros now, but when i add to layout i get error: failed to instantiate one or more classes. the CustomView class does not instantiate – David May 27 '17 at 08:31
  • you can't put that in XML because there you can't say that you want to pass the fragment as a context to the constructor...change the constructor of CustomView to Context then you can put it in XML. You don't use the fragment anyways inside the class. You actually need just the context so why pass something else in the constructor? – Tudor May 27 '17 at 08:33
  • hey mate, can you explain what should i change exactly? i got a little confused with it. i changed the constructor to get Context as the person below and you suggests. what to change in OnCreate? – David May 27 '17 at 08:39
  • the answers above look exactly at what you need to do. public CustomView(Context context) { super(context); mHolder = getHolder(); mHolder.setFormat(PixelFormat.TRANSPARENT); this.context = context; paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.WHITE); paint.setStyle(Paint.Style.STROKE); }. Then inside activity you can delete new CustomView(this) and put customView = (CustomView) findViewById(R.id.custom_view);... this will find the view in xml and bind it inside your activity – Tudor May 27 '17 at 08:43
  • How do i instantiate it inside OnCrate? customview = new CustomView(??); – David May 27 '17 at 08:48
  • customView = new CustomView(this); BUT CustomView(Context context) is the correct argument – Tudor May 27 '17 at 08:51
  • now i get error in layout: Custom view CustomView is not using the 2- or 3-argument View constructors; XML attributes will not work – David May 27 '17 at 08:56
  • because your custom view class is incomplete...you must have an attributeSet as the second parameter. Here is the documentation https://developer.android.com/training/custom-views/create-view.html . Or you can call super(context,null). Also check out this answer https://stackoverflow.com/questions/9195713/do-i-need-all-three-constructors-for-an-android-custom-view – Tudor May 27 '17 at 09:01