代码之家  ›  专栏  ›  技术社区  ›  Sanal S

Android ImageView收缩缩放和旋转在扩展服务的类上不起作用

  •  1
  • Sanal S  · 技术社区  · 5 年前

    我正在尝试实现一个应用程序,它使用 android.permission.SYSTEM_ALERT_WINDOW . 它显示一条直线( ImageView )在屏幕上,可以拖动(一个手指)、缩放(收缩缩放)和旋转(两个手指)。

    我能拖这条船 在屏幕上显示,并从中获得帮助 chatHead code . 但我无法在屏幕上应用缩放和旋转 图片框 在这项服务上,但缩放和旋转适用于正常活动时效果完美,扩展了 AppCompatActivity (使用第二个答案) this question

    HomeActivity.java

    HomeActivity Service(LineService) AppCompatActivity(LineActivity) viewTransformation() 从…起 LineActivity 在里面 LineService 因为它是一个 Service 线路服务 .

    import android.app.Activity;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Build;
    import android.os.Bundle;
    import android.provider.Settings;
    import android.view.View;
    import android.widget.Button;
    
    public class HomeActivity extends Activity {
    
        public final static int REQUEST_CODE = 5463&0xffffff00;
        Button buttonLineService;
        Button buttonLineActivity;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_home);
    
            buttonLineService = findViewById(R.id.buttonLineService);
            buttonLineActivity = findViewById(R.id.buttonLineActivity);
    
            checkDrawOverlayPermission();
    
            buttonLineService.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent i = new Intent(getApplicationContext(), LineService.class);
                    startService(i);
                    finish();
                }
            });
            buttonLineActivity.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent i = new Intent(getApplicationContext(), LineActivity.class);
                    startActivity(i);
                    finish();
                }
            });
        }
            public void checkDrawOverlayPermission() {
                /** check if we already  have permission to draw over other apps */
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(HomeActivity.this)) {
    //            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
    //                    (AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW.equals(op) &&
    //                            packageName.equals(mContext.getPackageName()))) {
                    /** if not construct intent to request permission */
                    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                            Uri.parse("package:" + getPackageName()));
                    /** request permission via start activity for result */
                    startActivityForResult(intent, REQUEST_CODE);
                }
            }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode,  Intent data) {
            /** check if received result code
             is equal our requested code for draw permission  */
            if (requestCode == REQUEST_CODE) {
           // ** if so check once again if we have permission */
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Settings.canDrawOverlays(this)) {
                    // continue here - permission was granted
                }
            }
        }
    }
    

    activity_home.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".HomeActivity">
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="100dp"
        android:orientation="vertical"
        android:layout_centerHorizontal="true">
    
        <Button
            android:id="@+id/buttonPermission"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Provide Overlay Permission"/>
    
        <Button
            android:id="@+id/buttonLineService"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Open Line Service"/>
    
        <Button
            android:id="@+id/buttonLineActivity"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Open Line Activity"/>
    
    </LinearLayout>
    
    </RelativeLayout>
    

    LineService.java

    import android.annotation.SuppressLint;
    import android.app.Service;
    import android.content.Intent;
    import android.graphics.PixelFormat;
    import android.os.Build;
    import android.os.IBinder;
    import android.view.Gravity;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.WindowManager;
    import android.widget.ImageView;
    
    public class LineService extends Service {
    
        private WindowManager windowManager;
        private ImageView line;
    
        @Override
        public IBinder onBind(Intent intent) {
            // Not used
            return null;
        }
    
        @SuppressLint("ClickableViewAccessibility")
        @Override
        public void onCreate() {
            super.onCreate();
    
            windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    
            line = new ImageView(this);
            line.setImageResource(R.drawable.line);
    
            final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_PHONE,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                    PixelFormat.TRANSLUCENT);
    
            params.gravity = Gravity.CENTER;
            params.x = 0;
            params.y = 100;
    
            windowManager.addView(line, params);
    
    
            line.setOnTouchListener(new View.OnTouchListener() {
                private int initialX;
                private int initialY;
                private float initialTouchX;
                private float initialTouchY;
    
                @Override
                public boolean onTouch(View v, MotionEvent event) {
    
                    if (event.getPointerCount() == 2) {
    
                    } else {
                        switch (event.getAction()) {
                            case MotionEvent.ACTION_DOWN:
                                initialX = params.x;
                                initialY = params.y;
                                initialTouchX = event.getRawX();
                                initialTouchY = event.getRawY();
                                return true;
                            case MotionEvent.ACTION_UP:
                                return true;
                            case MotionEvent.ACTION_MOVE:
                                params.x = initialX + (int) (event.getRawX() - initialTouchX);
                                params.y = initialY + (int) (event.getRawY() - initialTouchY);
                                windowManager.updateViewLayout(line, params);
                                return true;
                        }
                    }
                    return false;
                }
            });
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            if (line != null) windowManager.removeView(line);
        }
    }
    

    LineActivity.java

    import android.annotation.SuppressLint;
    import android.content.Intent;
    import android.graphics.PixelFormat;
    import android.graphics.PointF;
    import android.os.Build;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.Gravity;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.WindowManager;
    import android.widget.ImageView;
    
    public class LineActivity extends AppCompatActivity {
    
        private ImageView line;
    
        float[] lastEvent = null;
        float d = 0f;
        float newRot = 0f;
        private boolean isZoomAndRotate;
        private boolean isOutSide;
        private static final int NONE = 0;
        private static final int DRAG = 1;
        private static final int ZOOM = 2;
        private int mode = NONE;
        private PointF start = new PointF();
        private PointF mid = new PointF();
        float oldDist = 1f;
        private float xCoOrdinate, yCoOrdinate;
    
        @SuppressLint("ClickableViewAccessibility")
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test_line);
    
            final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_PHONE,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                    PixelFormat.TRANSLUCENT);
    
            params.gravity = Gravity.CENTER;
            params.x = 0;
            params.y = 100;
    
            line = findViewById(R.id.imageview_trash);
    
            line.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    ImageView view = (ImageView) v;
                    view.bringToFront();
                    viewTransformation(view, event);
                    return true;
                }
            });
        }
    
        private void viewTransformation(View view, MotionEvent event) {
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    xCoOrdinate = view.getX() - event.getRawX();
                    yCoOrdinate = view.getY() - event.getRawY();
    
                    start.set(event.getX(), event.getY());
                    isOutSide = false;
                    mode = DRAG;
                    lastEvent = null;
                    break;
                case MotionEvent.ACTION_POINTER_DOWN:
                    oldDist = spacing(event);
                    if (oldDist > 10f) {
                        midPoint(mid, event);
                        mode = ZOOM;
                    }
    
                    lastEvent = new float[4];
                    lastEvent[0] = event.getX(0);
                    lastEvent[1] = event.getX(1);
                    lastEvent[2] = event.getY(0);
                    lastEvent[3] = event.getY(1);
                    d = rotation(event);
                    break;
                case MotionEvent.ACTION_UP:
                    isZoomAndRotate = false;
                    if (mode == DRAG) {
                        float x = event.getX();
                        float y = event.getY();
                    }
                case MotionEvent.ACTION_OUTSIDE:
                    isOutSide = true;
                    mode = NONE;
                    lastEvent = null;
                case MotionEvent.ACTION_POINTER_UP:
                    mode = NONE;
                    lastEvent = null;
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (!isOutSide) {
                        if (mode == DRAG) {
                            isZoomAndRotate = false;
                            view.animate().x(event.getRawX() + xCoOrdinate).y(event.getRawY() + yCoOrdinate).setDuration(0).start();
                        }
                        if (mode == ZOOM && event.getPointerCount() == 2) {
                            float newDist1 = spacing(event);
                            if (newDist1 > 10f) {
                                float scale = newDist1 / oldDist * view.getScaleX();
                                view.setScaleX(scale);
                                view.setScaleY(scale);
                            }
                            if (lastEvent != null) {
                                newRot = rotation(event);
                                view.setRotation((float) (view.getRotation() + (newRot - d)));
                            }
                        }
                    }
                    break;
            }
        }
    
        private float rotation(MotionEvent event) {
            double delta_x = (event.getX(0) - event.getX(1));
            double delta_y = (event.getY(0) - event.getY(1));
            double radians = Math.atan2(delta_y, delta_x);
            return (float) Math.toDegrees(radians);
        }
    
        private float spacing(MotionEvent event) {
            float x = event.getX(0) - event.getX(1);
            float y = event.getY(0) - event.getY(1);
            return (int) Math.sqrt(x * x + y * y);
        }
    
        private void midPoint(PointF point, MotionEvent event) {
            float x = event.getX(0) + event.getX(1);
            float y = event.getY(0) + event.getY(1);
            point.set(x / 2, y / 2);
        }
    
        @Override
        public void onBackPressed() {
            super.onBackPressed();
            Intent i = new Intent(getApplicationContext(), HomeActivity.class);
            startActivity(i);
            finish();
        }
    }
    

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".LineActivity">
    
        <ImageView
            android:id="@+id/imageview_trash"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/line" />
    
    </LinearLayout>
    

    line.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <gradient
            android:startColor="#FFFF0000"
            android:endColor="#80FF00FF"
            android:angle="45"/>
        <padding android:left="200dp"
            android:top="200dp"
            android:right="200dp"
            android:bottom="200dp" />
        <corners android:radius="8dp" />
        <size android:width="200dp"
            android:height="5dp"/>
    </shape>
    
    0 回复  |  直到 5 年前