Xamarin Visual Studio不支持从Java构造泛型类型的实例

时间:2017-09-05 08:42:37

标签: java c# android generics

我很感激当前这个问题的一些帮助。我想我理解问题的原因,但我不知道如何解决它。我有两个自定义视图,一个实现ViewGroup,另一个实现View。

CameraSourcePreview和GraphicOverlay

然而,它们都是T的通用,其中T:GraphicOverlay< \ T> .Graphic

在BarcodeFragmentActivity中。第64行。 的setContentView(Resource.Layout.Barcode_Capture)

引发以下错误。

  

System.NotSupportedException:不支持从Java构造泛型类型的实例,因为无法确定类型参数。发生

我不确定如何创建完整的堆栈跟踪,因为我使用手机作为测试设备。程序不会在模拟器上运行。

Github上的代码:https://github.com/StormMaster12/StockApp。 认为在那里看到它比在我的所有代码中复制更容易。

编辑代码投掷错误。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Content.PM;

using Android.Gms.Vision.Barcodes;
using Android.Gms.Common.Apis;
using Android.Gms.Common;
using Android.Gms.Vision;

using Android.Hardware;

using Android.Support.V4.View;
using Android.Support.V4.App;
using Android.Support.V7.App;
using Android.Support.Design.Widget;

using StockApp.UI;
using Android.Util;

namespace StockApp.BarcodeReader
{
[Activity(Label = "Barcode Fragment Activity")]
class BarcodeFragmentActivity : AppCompatActivity
{
    private static string tag = "Barcode-Reader";
    private static int RC_HANDLE_GMS = 9001;
    private static int RC_HANDLE_CAMERA_PERM = 2;

    public static string AutoFocus = "AutoFocus";
    public static string UseFlash = "UseFlash";
    public static string BarcodeObject = "Barcode";

    private CameraSourcePreview<BarcodeGraphic> mPreview;
    private Android.Gms.Vision.CameraSource mCameraSource;
    private GraphicOverlay<BarcodeGraphic> mGraphicOverlay;

    private ScaleGestureDetector scaleGestureDetector;
    private GestureDetector getsureDetector;

    private View layout;
    private static BarcodeFragmentActivity thisInstance;

    public override View OnCreateView(View parent, string name, Context context, IAttributeSet attrs)
    {
        return base.OnCreateView(parent, name, context, attrs);
    }

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        thisInstance = this;

        SetContentView(Resource.Layout.Barcode_Capture);

        //LayoutInflater inflater = LayoutInflater.From(this);
        //ViewGroup viewGroup = (ViewGroup)FindViewById(Resource.Id.preview);
        //View child = inflater.Inflate(Resource.Layout.layout1, viewGroup, true);

        mPreview = (CameraSourcePreview<BarcodeGraphic>)FindViewById(Resource.Id.preview);
        mGraphicOverlay = (GraphicOverlay<BarcodeGraphic>)FindViewById(Resource.Id.graphicOverlay);

        bool autoFocus = Intent.GetBooleanExtra(AutoFocus, false);
        bool useFlash = Intent.GetBooleanExtra(UseFlash, false);

        int rc = (int) ActivityCompat.CheckSelfPermission(this, Manifest.Permission.Camera);
        if (rc == (int) Permission.Granted)
        {
            createCameraSource(autoFocus, useFlash);
        }
        else
        {
            requestCameraPermission(); 
        }

        getsureDetector = new GestureDetector(this, new CaptureGestureListener());
    }

    private void requestCameraPermission()
    {
        string[] permissions = new string[] { Manifest.Permission.CallPhone };
        if (ActivityCompat.ShouldShowRequestPermissionRationale(this, Manifest.Permission.Camera))
        {

            Snackbar.Make(layout, "Require Camera Permions To Read Barcodes", Snackbar.LengthIndefinite)
                .SetAction("Ok", new Action<View> (delegate(View obj)
                {
                    ActivityCompat.RequestPermissions(this, permissions, RC_HANDLE_CAMERA_PERM);
                }
                    )).Show();
        }
        else
        {
            ActivityCompat.RequestPermissions(this, permissions, RC_HANDLE_CAMERA_PERM);
        }

        //Activity thisActivity = this;
        //View.IOnClickListener listener = new View.IOnClickListener;

    }

    public override bool OnTouchEvent(MotionEvent e)
    {
        bool b = scaleGestureDetector.OnTouchEvent(e);
        bool c = getsureDetector.OnTouchEvent(e);
        return b || c || base.OnTouchEvent(e);
    }

    private void createCameraSource(bool autoFocus, bool useFlash)
    {
        Context context = ApplicationContext;

        BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(context).Build();
        BarcodeTrackerFactory barcodeFactory = new BarcodeTrackerFactory(mGraphicOverlay);
        barcodeDetector.SetProcessor(
            new MultiProcessor.Builder(barcodeFactory).Build());

        if (!barcodeDetector.IsOperational)
        {
            IntentFilter lowstorageFilter = new IntentFilter(Intent.ActionDeviceStorageLow);
            bool hasLowStorage = RegisterReceiver(null, lowstorageFilter) != null;

            if (hasLowStorage)
            {
                Toast.MakeText(this, "Low Storage Error", ToastLength.Long);
            }
        }

        Android.Gms.Vision.CameraSource.Builder builder = new Android.Gms.Vision.CameraSource.Builder(base.ApplicationContext, barcodeDetector)
            .SetFacing(Android.Gms.Vision.CameraFacing.Back)
            .SetRequestedPreviewSize(1600, 1024)
            .SetRequestedFps(15.0f)
            .SetAutoFocusEnabled(true);

        mCameraSource = builder.Build();




    }

    private void startCameraSource()
    {
        int code = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(ApplicationContext);

        if(code != ConnectionResult.Success)
        {
            Dialog dig = GoogleApiAvailability.Instance.GetErrorDialog(this, code, RC_HANDLE_GMS);
            dig.Show();
        }

        if (mCameraSource != null)
        {
            try
            {
                mPreview.start(mCameraSource, mGraphicOverlay);
            }
            catch (InvalidOperationException)
            {
                mCameraSource.Release();
                mCameraSource = null;
            }
        }
    }

    private bool OnTap(float rawX, float rawY)
    {
        int[] location = new int[2];
        mGraphicOverlay.GetLocationOnScreen(location);
        float x = (rawX - location[0]);
        float y = (rawY - location[1]);

        Barcode best = null;
        float bestDistance = float.MaxValue;

        foreach (BarcodeGraphic graphic in mGraphicOverlay.getGraphics())
        {
            Barcode barcode = graphic.GetBarcode();

            if(barcode.BoundingBox.Contains((int)x,(int)y))
            {
                best = barcode;
                break;
            }

            float dx = x - barcode.BoundingBox.CenterX();
            float dy = y - barcode.BoundingBox.CenterY();

            float distance = (dx * dx) + (dy * dy);

            if ( distance > bestDistance)
            {
                best = barcode;
                bestDistance = distance;
            }

            if (best != null)
            {
                Intent data = new Intent();
                data.PutExtra(BarcodeObject, best);
                SetResult(CommonStatusCodes.Success, data);
                Finish();
                return true;
            }

        }
        return false;

    }

    protected override void OnResume()
    {
        base.OnResume();
        startCameraSource();
    }

    protected override void OnPause()
    {
        base.OnPause();
        if (mPreview != null)
        {
            mPreview.stop();
        }
    }

    protected override void OnDestroy()
    {
        base.OnDestroy();
        if(mPreview != null)
        {
            mPreview.release();
        }
    }

    private class CaptureGestureListener : GestureDetector.SimpleOnGestureListener
    {
        public override bool OnSingleTapConfirmed(MotionEvent e)
        {
            return thisInstance.OnTap(e.RawX, e.RawY) || base.OnSingleTapConfirmed(e);
        }
    }

    private class ScaleListener : ScaleGestureDetector.IOnScaleGestureListener
    {
        public IntPtr Handle => throw new NotImplementedException();

        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public bool OnScale(ScaleGestureDetector detector)
        {
            return false;
        }

        public bool OnScaleBegin(ScaleGestureDetector detector)
        {
                    return true;
        }

        public void OnScaleEnd(ScaleGestureDetector detector)
        {
        }
    }

}
}

正在调用的代码。

CameraSourcePreview

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Gms.Vision;
using Android.Util;
using Android.Support.Annotation;
using Android.Gms.Common.Images;
using Android.Content.Res;
using Android.Graphics;

namespace StockApp.UI
{
[Register("stockapp.stockapp.ui.CameraSourcePreview")]
class CameraSourcePreview<T> : ViewGroup where T : GraphicOverlay<T>.Graphic
{
    private static string TAG = "CameraSourcePreview";

    private Context mContext;
    private SurfaceView mSurfaceView;
    public bool mStartRequested;
    private bool mSurfaceAvaialbe;

    private Android.Gms.Vision.CameraSource mCameraSource;
    private GraphicOverlay<T> mOverlay;

    private static CameraSourcePreview<T> Instance { get; set; }

    public CameraSourcePreview(Context context, IAttributeSet attrs) : base(context,attrs)
    {
        mContext = context;
        mStartRequested = false;
        mSurfaceAvaialbe = false;

        SurfaceCallback instance = new SurfaceCallback();

        mSurfaceView = new SurfaceView(context);
        mSurfaceView.Holder.AddCallback(instance);
        AddView(mSurfaceView);
    }


    public void start(Android.Gms.Vision.CameraSource cameraSource)
    {
        if (cameraSource == null)
        {
            stop();
        }

        mCameraSource = cameraSource;

        if(mCameraSource != null)
        {
            mStartRequested = true;
            startIfReady();
        }
    }

    public void start(Android.Gms.Vision.CameraSource cameraSource, GraphicOverlay<T> graphicOverlay)
    {
        mOverlay = graphicOverlay;
        start(cameraSource);
    }

    public void stop()
    {
        if(mCameraSource != null)
        {
            mCameraSource.Stop();
        }
    }

    public void release()
    {
        if(mCameraSource != null)
        {
            mCameraSource.Release();
            mCameraSource = null;
        }
    }

    private bool isPortaitMode()
    {
        int orientation = (int)mContext.Resources.Configuration.Orientation;
        if (orientation == (int)Android.Content.Res.Orientation.Landscape)
        {
            return false;
        }
        else if (orientation == (int)Android.Content.Res.Orientation.Portrait)
        {
            return true;
        }

        return false;
    }

    private void startIfReady()
    {
        if (mStartRequested && mSurfaceAvaialbe)
        {
            mCameraSource.Start(mSurfaceView.Holder);
            if (mOverlay != null)
            {
                Android.Gms.Common.Images.Size size = mCameraSource.PreviewSize;
                int min = Math.Min(size.Width, size.Height);
                int max = Math.Max(size.Width, size.Width);

                if(isPortaitMode())
                {
                    mOverlay.setCameraInfo(min, max, (int)mCameraSource.CameraFacing);
                }
                else
                {
                    mOverlay.setCameraInfo(max, min, (int)mCameraSource.CameraFacing);
                }
                mOverlay.Clear();
            }
            mStartRequested = false;
        }
    }

    protected override void OnLayout(bool changed, int l, int t, int r, int b)
    {
        int intWidth = 320;
        int intHeight = 240;

        if(mCameraSource != null)
        {
            Android.Gms.Common.Images.Size size = mCameraSource.PreviewSize;

            if(size != null)
            {
                intWidth = size.Width;
                intHeight = size.Height;
            }
        }

        if(isPortaitMode())
        {
            int tmp = intWidth;
            intHeight = intWidth;
            intWidth = tmp;
        }

        int layoutWidth =  l - r;
        int layoutHeight = t - b;

        int childWidth = layoutWidth;
        int childHeight = (int)(((float)layoutWidth / (float) intHeight)*intWidth);

        if (childHeight > layoutWidth)
        {
            childHeight = layoutHeight;
            childWidth = (int)(((float)layoutHeight / (float)intHeight) * intWidth);

        }

        for (int i =0 ; i < ChildCount; i++ )
        {
            GetChildAt(i).Layout(0, 0, childWidth, childHeight);
        }

        try
        {
            startIfReady();
        }
        catch (Exception e)
        {
            Log.Debug("Something went wrong", e.ToString());
        }
    }


    private class SurfaceCallback : ISurfaceHolderCallback
    {
        public IntPtr Handle => throw new NotImplementedException();

        public void Dispose()
        {
        }

        public void SurfaceChanged(ISurfaceHolder holder, [GeneratedEnum] Format format, int width, int height)
        {
        }

        public void SurfaceCreated(ISurfaceHolder holder)
        {
            Instance.mSurfaceAvaialbe = true;
            try
            {
                Instance.startIfReady(); 
            }
            catch (Exception e)
            {
                Log.Debug("Something went wrong",e.ToString());
            }
        }

        public void SurfaceDestroyed(ISurfaceHolder holder)
        {
            Instance.mSurfaceAvaialbe = false;
        }
    }
}
}

GraphicOverlay

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Gms.Vision;
using Android.Util;
using Android.Graphics;
using Java.Util;


namespace StockApp.UI
{
[Register("stockapp.stockapp.ui.GraphicOverlay")]
class GraphicOverlay<T> : View where T: GraphicOverlay<T>.Graphic
{
    public T tT ;
    private Object mLock = new object();
    private int mPreviewWidth { get; set; }
    private float mWidthScaleFactor { get; set; } = 1.0f;
    private int mPreviewHeight;
    private float mHeightScaleFactor { get; set; } = 1.0f;
    private int mFacing { get; set; } = (int)CameraFacing.Back;
    private HashSet<T> mGraphics = new HashSet<T>();

    public GraphicOverlay(Context context, IAttributeSet attrs)
        : base(context, attrs)
    {
    }

    public void Clear()
    {
        lock(mLock)
        {
            mGraphics.Clear();
        }
    }

    public void Add(T graphic)
    {
        lock(mLock)
        {
            mGraphics.Add(graphic);
        }
        PostInvalidate();
    }

    public void Remove(T graphic)
    {
        lock(mLock)
        {
            mGraphics.Remove(graphic);
        }
        PostInvalidate();
    }

    public List<T> getGraphics()
    {
        lock(mLock)
        {
            return mGraphics.ToList();
        }
    }

    public void setCameraInfo(int previewWidth, int previewHeight, int facing)
    {
        lock(mLock)
        {
            mPreviewHeight = previewHeight;
            mPreviewWidth = previewWidth;
            mFacing = facing;
        }

        PostInvalidate();
    }

    protected void onDraw(Canvas canvas)
    {
        base.OnDraw(canvas);
        lock(mLock)
        {
            if(mPreviewWidth !=0 && mPreviewHeight !=0)
            {
                mWidthScaleFactor = (float)canvas.Width / (float)mPreviewWidth;
                mHeightScaleFactor = (float)canvas.Height / (float)mPreviewHeight;
            }

            foreach (Graphic graphic in mGraphics)
            {
                graphic.Draw(canvas);
            }
        }
    }

    public abstract class Graphic
    {
        private GraphicOverlay<T> mOverlay;
        public Graphic(GraphicOverlay<T> overlay)
        {
            mOverlay = overlay;
        }

        public abstract void Draw(Canvas canvas);

        public float scaleX(float horizontal) { return horizontal * mOverlay.mWidthScaleFactor; }
        public float scaleY(float vertical) { return vertical * mOverlay.mHeightScaleFactor; }

        public float translateX(float x)
        {
            float scale = scaleX(x);

            if(mOverlay.mFacing == (int)CameraFacing.Front)
            {
                return mOverlay.Width - scale;
            }
            else
            {
                return scale;
            }
        }

        public float translateY(float y) { return scaleY(y); }

        public void postInvalidate() { mOverlay.PostInvalidate(); }
    }



}
}

0 个答案:

没有答案