天天看點

android 自定義可拖動框

這陣子在做一個東西 ,  要求定位一個動态攝像頭中一個東西的位置(這個位置必須由人 手動圈住),查的好多都是調用系統 intent 相機切圖,發現不可行,是以有了這篇部落格。

此代碼實作了,方形框拉伸,拖動。

剛看到這個要求時,覺得很簡單,結果....           android 裡面還是坑太多了,這次就是掉了android 中擷取控件位置的一個坑,setleft、setright、settop、setbottom  不穩定,是以弄得很亂啊。

廢話不多說上代碼,main.java中隻有一個跳轉 ,有用的隻有一個java、一個xml、一個style    檔案清單如下:

android 自定義可拖動框

1、CameraRemoveView.java

public class CameraRemoveView extends AppCompatActivity implements GestureDetector.OnGestureListener{

    private int Left = 300;
    private int Top =300 ;
    private int Bottom = 600;
    private int Right = 600;
    private int r=70;
    private int winTop ; //狀态欄高度

    private GestureDetector gestureDetector;

    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera_remove_layout);

        /**
         * 擷取狀态欄高度——方法1
         * */
        int statusBarHeight1 = -1;
        //擷取status_bar_height資源的ID
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            //根據資源ID擷取響應的尺寸值
            statusBarHeight1 = getResources().getDimensionPixelSize(resourceId);
        }
        winTop = statusBarHeight1;

        textView=(TextView) findViewById(view);

        //設定初始位置
        textView.setX(Left);
        textView.setY(Top);
        textView.setHeight( Bottom - Top );
        textView.setWidth( Right - Left );
        gestureDetector=new GestureDetector(this);   //監聽鄭哥螢幕觸摸
    }


    /**
     * 計算觸摸點是否在給定正放心内部  R為邊長1/2
     * @param x 中心點x坐标
     * @param y 中心點y坐标
     * @param event_x 觸摸點x坐标
     * @param event_y 觸摸點y坐标
     * @return
     */
    private boolean isInSquare(int x,int y,int event_x,int event_y){
        return  Math.abs( event_x -x ) < r && Math.abs( event_y - y ) < r;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return  gestureDetector.onTouchEvent(event);
    }

    @Override
    public boolean onDown(MotionEvent e) {
        //按下時記錄控件位置
        Left = (int) textView.getX();
        Right = textView.getWidth()+Left;
        Top = (int) textView.getY();
        Bottom = textView.getHeight()+Top;
        return false;
    }

    @Override
    public void onShowPress(MotionEvent e) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

        if (isInSquare( Left, Top , (int)e1.getRawX() , (int)e1.getRawY() )){   //擷取左上角
            textView.setX(e2.getRawX());
            textView.setY(e2.getRawY() - winTop);
            textView.setHeight((int) (Bottom - e2.getRawY() + winTop));
            textView.setWidth((int) (Right - e2.getRawX()));
        }else if ( isInSquare( Right, Bottom , (int)e1.getRawX() , (int)e1.getRawY() )){   //擷取右下角
            textView.setHeight((int) e2.getRawY() - Top - winTop);
            textView.setWidth((int) e2.getRawX() - Left);
        }else if( isInSquare( Right, Top , (int)e1.getRawX() , (int)e1.getRawY() )){    //擷取右上角
            textView.setY(e2.getRawY() - winTop);
            textView.setWidth((int) e2.getRawX() - Left);
            textView.setHeight((int) (Bottom - e2.getRawY() + winTop));
        }else if( isInSquare( Left, Bottom , (int)e1.getRawX() , (int)e1.getRawY() )){     //擷取左下角
            textView.setX(e2.getRawX());
            textView.setHeight((int) ( e2.getRawY() - winTop - Top ));
            textView.setWidth((int) (Right - e2.getRawX()));
        }else if( Math.abs(e1.getRawX() - Left) < r ){    //左
            textView.setX((int) e2.getRawX());
            textView.setWidth((int) (Right - e2.getRawX()));
        }else if ( Math.abs(e1.getRawY() - winTop - Top) < r ){  //上
            textView.setY((int) e2.getRawY() - winTop );
            textView.setHeight((int) (Bottom - e2.getRawY() + winTop));
        }else if ( Math.abs(e1.getRawX() - Right ) < r ){    //右
            textView.setWidth((int) e2.getRawX() - Left);
        }else if (Math.abs(e1.getRawY() - winTop - Bottom ) < r ){    //下
            textView.setHeight((int) e2.getY() - winTop - Top );
        }else if ((e1.getRawX() - r > Left ) && (e1.getRawY() - r  > Top + winTop )    //中間
                && (e1.getRawX() + r < Right ) && (e1.getRawY() + r < Bottom + winTop )){
            textView.setX(Left - e1.getRawX() + e2.getRawX() );
            textView.setY( Top - e1.getRawY() + e2.getRawY() );
        }else {
            Log.i("haha","觸摸了框以外部分" );
        }

        return false;
    }

    @Override
    public void onLongPress(MotionEvent e) {

    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

        return false;
    }
}      

2、xml檔案

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </LinearLayout>
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:id="@+id/view"
                android:background="@drawable/view_style"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>

        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <Space
                android:layout_weight="0.5"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
            <Button
                android:id="@+id/view_ok"
                android:text="記錄位置"
                android:layout_weight="1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
            <Space
                android:layout_weight="0.5"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
            <Button
                android:id="@+id/view_cancel"
                android:text="取消"
                android:layout_weight="1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
            <Space
                android:layout_weight="0.5"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </LinearLayout>


</FrameLayout>
      

3、style.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="false">
        <shape >
            <stroke android:color="#ff0000" android:width="1dp"/>
            <solid android:color="#00000000"/>
        </shape>
    </item>

</selector>
      

最後來一張效果圖吧

android 自定義可拖動框