Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot compile this class with Android SDK > API 23 #644

Closed
NickIliev opened this issue Dec 1, 2016 · 2 comments
Closed

Cannot compile this class with Android SDK > API 23 #644

NickIliev opened this issue Dec 1, 2016 · 2 comments
Assignees
Labels

Comments

@NickIliev
Copy link

From @alexrainman on November 30, 2016 23:49

I have this class:

var CirclePageIndicatorClass;
function ensureCirclePageIndicatorClass() {

    if (CirclePageIndicatorClass) {
        return;
    }

    class CirclePageIndicatorInner extends android.view.View
    {
        HORIZONTAL : number = 0;
        VERTICAL : number = 1;
        
        private mViewPager : android.support.v4.view.ViewPager;
        private mPageSize : number;

        public mCurrentPage : number;
        public mSnapPage : number;
        public mCurrentOffset : number;
        public mScrollState : number;

        public mCentered : boolean;
        public mPaintFill : android.graphics.Paint;
        public mPaintPageFill : android.graphics.Paint;
        public mOrientation : number;
        public mRadius : number;
        public mSnap : boolean;
        public mPaintStroke : android.graphics.Paint;

        constructor(context: android.content.Context)
        {
            super(context, null);

            this.mCentered = true;

            this.mPaintFill = new android.graphics.Paint(android.graphics.Paint.ANTI_ALIAS_FLAG);
            this.mPaintFill.setStyle(android.graphics.Paint.Style.FILL);
            this.mPaintFill.setColor(android.graphics.Color.parseColor("#808080"));

            this.mPaintPageFill = new android.graphics.Paint(android.graphics.Paint.ANTI_ALIAS_FLAG);
            this.mPaintPageFill.setStyle(android.graphics.Paint.Style.FILL);
            this.mPaintPageFill.setColor(android.graphics.Color.parseColor("#c0c0c0"));

            this.mOrientation = this.HORIZONTAL;
            this.mRadius = this.dpToPx(3);
            this.mSnap = true;

            this.mPaintStroke = new android.graphics.Paint(android.graphics.Paint.ANTI_ALIAS_FLAG);
            this.mPaintStroke.setStyle(android.graphics.Paint.Style.STROKE);
            this.mPaintStroke.setColor(android.graphics.Color.parseColor("#FFFFFFFF"));
            this.mPaintStroke.setStrokeWidth(0);

            let p = this.dpToPx(15);
            global.__native(this).setPadding(p,p,p,p);
            global.__native(this).setBackgroundColor(android.graphics.Color.TRANSPARENT);

            return global.__native(this);
        }

        public SetViewPager(view: android.support.v4.view.ViewPager, initialPosition: number) : void
        {
            if (view.getAdapter() == null)
            {
                throw new java.lang.IllegalStateException("ViewPager does not have adapter instance.");
            }
            this.mViewPager = view;
            this.UpdatePageSize();

            this.SetCurrentItem(initialPosition);
        }

        public SetCurrentItem(item: number) : void
        {
            if (this.mViewPager == null)
            {
                throw new java.lang.IllegalStateException("ViewPager has not been bound.");
            }
            this.mViewPager.setCurrentItem(item);
            this.mCurrentPage = item;
            this.invalidate();
        }

        public UpdatePageSize() : void
        {
            if (this.mViewPager != null)
            {
                this.mPageSize = (this.mOrientation == this.HORIZONTAL) ? this.mViewPager.getWidth() : this.mViewPager.getHeight();
            }
        }

        public dpToPx(dp: number) : number
        {
            var res = android.content.res.Resources;
            return dp * res.getSystem().getDisplayMetrics().density;
        }

        protected onDraw(canvas: android.graphics.Canvas): void
        {
            super.onDraw(canvas);

            if (this.mViewPager == null)
            {
                return;
            }
            let count = this.mViewPager.getAdapter().getCount();
            if (count == 0)
            {
                return;
            }

            if (this.mCurrentPage >= count)
            {
                this.SetCurrentItem(count - 1);
                return;
            }

            let longSize;
            let longPaddingBefore;
            let longPaddingAfter;
            let shortPaddingBefore;
            if (this.mOrientation == this.HORIZONTAL)
            {
                longSize = this.getWidth();
                longPaddingBefore = this.getPaddingLeft();
                longPaddingAfter = this.getPaddingRight();
                shortPaddingBefore = this.getPaddingTop();
            }
            else {
                longSize = this.getHeight();
                longPaddingBefore = this.getPaddingTop();
                longPaddingAfter = this.getPaddingBottom();
                shortPaddingBefore = this.getPaddingLeft();
            }

            let threeRadius = this.mRadius * 4; // dots separation
            let shortOffset = shortPaddingBefore + this.mRadius;
            let longOffset = longPaddingBefore + this.mRadius;
            if (this.mCentered)
            {
                longOffset += ((longSize - longPaddingBefore - longPaddingAfter) / 2.0) - ((count * threeRadius) / 2.0);
            }

            let dX;
            let dY;

            let pageFillRadius = this.mRadius;
            if (this.mPaintStroke.getStrokeWidth() > 0)
            {
                pageFillRadius -= this.mPaintStroke.getStrokeWidth() / 2.0;
            }

            //Draw stroked circles
            for (var iLoop = 0; iLoop < count; iLoop++)
            {
                let drawLong = longOffset + (iLoop * threeRadius);
                if (this.mOrientation == this.HORIZONTAL)
                {
                    dX = drawLong;
                    dY = shortOffset;
                }
                else {
                    dX = shortOffset;
                    dY = drawLong;
                }
                // Only paint fill if not completely transparent
                if (this.mPaintPageFill.getAlpha() > 0)
                {
                    canvas.drawCircle(dX, dY, pageFillRadius, this.mPaintPageFill);
                }

                // Only paint stroke if a stroke width was non-zero
                if (pageFillRadius != this.mRadius)
                {
                    canvas.drawCircle(dX, dY, this.mRadius, this.mPaintStroke);
                }
            }

            //Draw the filled circle according to the current scroll
            let cx = (this.mSnap ? this.mSnapPage : this.mCurrentPage) * threeRadius;
            if (!this.mSnap && (this.mPageSize != 0))
            {
                cx += (this.mCurrentOffset * 1.0 / this.mPageSize) * threeRadius;
            }
            if (this.mOrientation == this.HORIZONTAL)
            {
                dX = longOffset + cx;
                dY = shortOffset;
            }
            else {
                dX = shortOffset;
                dY = longOffset + cx;
            }
            canvas.drawCircle(dX, dY, this.mRadius, this.mPaintFill);
        }

        protected onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void
        {
            if (this.mOrientation == this.HORIZONTAL)
            {
                this.setMeasuredDimension(this.MeasureLong(widthMeasureSpec), this.MeasureShort(heightMeasureSpec));
            }
            else {
                this.setMeasuredDimension(this.MeasureShort(widthMeasureSpec), this.MeasureLong(heightMeasureSpec));
            }
        }

        private MeasureLong(measureSpec: number) : number
        {
            let result = 0;
            var specMode = android.view.View.MeasureSpec.getMode(measureSpec);
            var specSize = android.view.View.MeasureSpec.getSize(measureSpec);

            if ((specMode == android.view.View.MeasureSpec.EXACTLY) || (this.mViewPager == null) || (this.mViewPager.getAdapter() == null))
            {
                //We were told how big to be
                result = specSize;
            }
            else {
                //Calculate the width according the views count
                let count = this.mViewPager.getAdapter().getCount();
                result = <number>(this.getPaddingLeft() + this.getPaddingRight()
                        + (count * 2 * this.mRadius) + (count - 1) * this.mRadius + 1);
                //Respect AT_MOST value if that was what is called for by measureSpec
                if (specMode == android.view.View.MeasureSpec.AT_MOST)
                {
                    result = java.lang.Math.min(result, specSize);
                }
            }
            return result;
        }

        private MeasureShort(measureSpec : number) : number
        {
            let result = 0;
            var specMode = android.view.View.MeasureSpec.getMode(measureSpec);
            var specSize = android.view.View.MeasureSpec.getSize(measureSpec);

            if (specMode == android.view.View.MeasureSpec.EXACTLY)
            {
                //We were told how big to be
                result = specSize;
            }
            else {
                //Measure the height
                result = <number>(2 * this.mRadius + this.getPaddingTop() + this.getPaddingBottom() + 1);
                //Respect AT_MOST value if that was what is called for by measureSpec
                if (specMode == android.view.View.MeasureSpec.AT_MOST)
                {
                    result = java.lang.Math.min(result, specSize);
                }
            }
            return result;
        }

        protected onRestoreInstanceState(state: android.os.IParcelable) : void
        {
            try
            {
                var bundle = state as android.os.Bundle;
                if (bundle != null)
                {
                    var superState = <android.os.IParcelable>bundle.getParcelable("base");
                    if (superState != null)
                        super.onRestoreInstanceState(superState);
                    this.mCurrentPage = bundle.getInt("mCurrentPage", 0);
                    this.mSnapPage = bundle.getInt("mCurrentPage", 0);
                }
            }
            catch(e)
            {
                super.onRestoreInstanceState(state);
                // Ignore, this needs to support IParcelable...
            }

            this.requestLayout();
        }

        protected onSaveInstanceState() : android.os.IParcelable
        {
            var superState = super.onSaveInstanceState();
            var state = new android.os.Bundle();
            state.putParcelable("base", superState);
            state.putInt("mCurrentPage", this.mCurrentPage);

            return state;
        }
    }

    CirclePageIndicatorClass = CirclePageIndicatorInner;
}

But i cannot use it with any Android SDK > API23:

ensureCirclePageIndicatorClass();
var dots = new CirclePageIndicatorClass(application.android.currentContext);
var layoutParams = new android.widget.RelativeLayout.LayoutParams(android.widget.RelativeLayout.LayoutParams.MATCH_PARENT, android.widget.RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(android.widget.RelativeLayout.ALIGN_PARENT_BOTTOM);
dots.SetViewPager(this._viewPager, this.position);
dots.mSnapPage = this.position;
this._android.addView(dots, layoutParams);

Then i get this exception:

An uncaught Exception occurred on "main" thread.
java.lang.RuntimeException: Unable to resume activity {org.nativescript.CarouselViewDemo/com.tns.NativeScriptActivity}: com.tns.NativeScriptException: 
Calling js method onCreateView failed

Error: java.lang.NoSuchFieldError: no "I" field "DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION" in class "Landroid/view/View;" or its superclasses
    com.tns.Runtime.callJSMethodNative(Native Method)
    com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1022)
    com.tns.Runtime.callJSMethodImpl(Runtime.java:907)
    com.tns.Runtime.callJSMethod(Runtime.java:895)
    com.tns.Runtime.callJSMethod(Runtime.java:879)
    com.tns.Runtime.callJSMethod(Runtime.java:871)
    com.tns.FragmentClass.onCreateView(android.app.Fragment.java)
    android.app.Fragment.performCreateView(Fragment.java:2220)
    android.app.FragmentManagerImpl.moveToState(FragmentManager.java:973)
    android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148)
    android.app.BackStackRecord.run(BackStackRecord.java:793)
    android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1535)
    android.app.FragmentController.execPendingActions(FragmentController.java:325)
    android.app.Activity.performResume(Activity.java:6334)
    android.app.ActivityThread.performResumeActivity(ActivityThread.java:3092)
    android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134)
    android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2481)
    android.app.ActivityThread.-wrap11(ActivityThread.java)
    android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
    android.os.Handler.dispatchMessage(Handler.java:102)
    android.os.Looper.loop(Looper.java:148)
    android.app.ActivityThread.main(ActivityThread.java:5417)
    java.lang.reflect.Method.invoke(Native Method)
	Frame: function:'View.onLoaded', file:'/data/data/org.nativescript.CarouselViewDemo/files/app/tns_modules/ui/core/view.js', line: 83, column: 35
	Frame: function:'Page.onLoaded', file:'/data/data/org.nativescript.CarouselViewDemo/files/app/tns_modules/ui/page/page-common.js', line: 53, column: 35
	Frame: function:'View._addViewCore', file:'/data/data/org.nativescript.CarouselViewDemo/files/app/tns_modules/ui/core/view-common.js', line: 1173, column: 18
	Frame: function:'View._addViewCore', file:'/data/data/org.nativescript.CarouselViewDemo/files/app/tns_modules/ui/core/view.js', line: 128, column: 39
	Frame: function:'View._addView', file:'/data/data/org.nativescript.CarouselViewDemo/files/app/tns_modules/ui/core/view-common.js', line: 1163, column: 14
	Frame: function:'onFragmentShown', file:'/data/data/org.nativescript.CarouselViewDemo/files/app/tns_modules/ui/frame/frame.js', line: 40, column: 11
	Frame: function:'FragmentCallbacksImplementation.onCreateView', file:'/data/data/org.nativescript.CarouselViewDemo/files/app/tns_modules/ui/frame/frame.js', line: 612, column: 13
	Frame: function:'FragmentClass.onCreateView', file:'/data/data/org.nativescript.CarouselViewDemo/files/app/tns_modules/ui/frame/fragment.js', line: 23, column: 38


	at com.tns.Runtime.callJSMethodNative(Native Method)
	at com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1022)
	at com.tns.Runtime.callJSMethodImpl(Runtime.java:907)
	at com.tns.Runtime.callJSMethod(Runtime.java:895)
	at com.tns.Runtime.callJSMethod(Runtime.java:879)
	at com.tns.Runtime.callJSMethod(Runtime.java:871)
	at com.tns.FragmentClass.onCreateView(android.app.Fragment.java)
	at android.app.Fragment.performCreateView(Fragment.java:2220)
	at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:973)
	at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148)
	at android.app.BackStackRecord.run(BackStackRecord.java:793)
	at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1535)
	at android.app.FragmentController.execPendingActions(FragmentController.java:325)
	at android.app.Activity.performResume(Activity.java:6334)
	at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3092)
	... 10 more
Caused by: java.lang.NoSuchFieldError: no "I" field "DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION" in class "Landroid/view/View;" or its superclasses
	... 25 more

Any ideas?

Copied from original issue: NativeScript/NativeScript#3216

@petekanev
Copy link
Contributor

petekanev commented Dec 1, 2016

Hey @alexrainman, this looks oddly familiar to an issue that we believe we have addressed in the unstable (master) branch. The problem is described here -> #626

Could you please add android@next and let us know if the problem is resolved for you?

@petekanev petekanev self-assigned this Dec 1, 2016
@petekanev petekanev added the bug label Dec 1, 2016
@alexrainman
Copy link

@NickIliev installing android@next solve the problem 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants