Androidは任意のViewコードをドラッグ

18293 ワード

前のプロジェクトの中で、このような需要を書いたことを覚えていますが、プロジェクトとの結合がきついので、ネット上でいくつかの文章を探して見ました.ついでに他の作者が書いたコードも写しました.もし需要シーンが簡単で、現在の携帯電話の画面の中でviewをドラッグするためだけなら、この文章のコードを直接使うことができますか.ここには、2つのクラスがあります.1つはカスタムImageViewで、ImageViewの任意のドラッグ効果に使用されています.もう1つはfabButtonで、fabButtonを任意に引っ張ることができます.
コードは比較的に簡単で、次回は簡単な需要があって、直接コードを写すことができて、さもなくばまだ半日探さなければなりません.まずImageViewを見てみましょう
@SuppressLint("AppCompatCustomView")
public class DragImageView extends ImageView {

    private int width;
    private int height;
    private int screenWidth;
    private int screenHeight;
    private Context context;

    //    
    private boolean isDrag = false;
    private float downX;
    private float downY;


    public DragImageView(Context context) {
        super(context);
        this.context = context;
    }

    public DragImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }

    public boolean isDrag() {
        return isDrag;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getMeasuredWidth();
        height = getMeasuredHeight();
        screenWidth = SystemUtils.getWindowWidth();
        screenHeight = SystemUtils.getWindowHeight() - SystemUtils.getStatusBarHeight();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        if (this.isEnabled()) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    isDrag = false;
                    downX = event.getX();
                    downY = event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    final float xDistance = event.getX() - downX;
                    final float yDistance = event.getY() - downY;
                    int l, r, t, b;
                    //             10,      
                    if (Math.abs(xDistance) > 10 || Math.abs(yDistance) > 10) {
                        isDrag = true;
                        l = (int) (getLeft() + xDistance);
                        r = l + width;
                        t = (int) (getTop() + yDistance);
                        b = t + height;
                        //       ,           ,                 ,
                        //        ,       ,                
                        if (l < 0) {
                            l = 0;
                            r = l + width;
                        } else if (r > screenWidth) {
                            r = screenWidth;
                            l = r - width;
                        }
                        if (t < 0) {
                            t = 0;
                            b = t + height;
                        } else if (b > screenHeight) {
                            b = screenHeight;
                            t = b - height;
                        }

                        this.layout(l, t, r, b);
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    setPressed(false);
                    break;
                case MotionEvent.ACTION_CANCEL:
                    setPressed(false);
                    break;
            }
            return true;
        }
        return false;
    }

}
 
次にFabButtonを見てみましょう.実はコードはあまり違いません.
public class DragFloatingActionButton extends FloatingActionButton {

    private int width;
    private int height;
    private int screenWidth;
    private int screenHeight;
    private Context context;

    //    
    private boolean isDrag = false;
    private float downX;
    private float downY;


    public DragFloatingActionButton(Context context) {
        super(context);
        this.context = context;
    }

    public DragFloatingActionButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }

    public boolean isDrag() {
        return isDrag;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getMeasuredWidth();
        height = getMeasuredHeight();
        screenWidth = SystemUtils.getWindowWidth();
        screenHeight = SystemUtils.getWindowHeight() - SystemUtils.getStatusBarHeight();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        if (this.isEnabled()) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    isDrag = false;
                    downX = event.getX();
                    downY = event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    final float xDistance = event.getX() - downX;
                    final float yDistance = event.getY() - downY;
                    int l, r, t, b;
                    //             10,      
                    if (Math.abs(xDistance) > 10 || Math.abs(yDistance) > 10) {
                        isDrag = true;
                        l = (int) (getLeft() + xDistance);
                        r = l + width;
                        t = (int) (getTop() + yDistance);
                        b = t + height;
                        //       ,           ,                 ,
                        //        ,       ,                
                        if (l < 0) {
                            l = 0;
                            r = l + width;
                        } else if (r > screenWidth) {
                            r = screenWidth;
                            l = r - width;
                        }
                        if (t < 0) {
                            t = 0;
                            b = t + height;
                        } else if (b > screenHeight) {
                            b = screenHeight;
                            t = b - height;
                        }

                        this.layout(l, t, r, b);
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    setPressed(false);
                    break;
                case MotionEvent.ACTION_CANCEL:
                    setPressed(false);
                    break;
            }
            return true;
        }
        return false;
    }

}
コアロジックはonTouchEventでの判断です.研究が必要なものは自分で分析することができる.
 
viewがクリックイベントを処理する必要がある場合は.
では、コード上の使い方に注意して、以下のポーズを参考にします.
dragView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e("TEST", "onClick() dragView 111");
                if (dragView.isDrag()) {
                    return;
                }
                Log.e("TEST", "onClick() dragView 222");
                Toast.makeText(MainActivity.this, "  ", Toast.LENGTH_SHORT).show();
            }
        });
 
この文章を書くのは記録のためで、このようなよく書かないコード(シーンが簡単である必要がある)のように、場所を置いて管理して、次回コピーして貼り付けるのに便利です.