How to implement the drag control in android


Today, I will briefly talk about how android drags controls.


Before, a function was needed to realize the dragging of controls according to gestures, and some operations could be performed when dragging to the moving position. I didn't know what to do at the time, so I looked up information on the Internet and finally solved the problem. Record it here.



1. Use view.layout(left, top, right, bottom) to implement dragging.


1. Follow the figure below to understand a few coordinates

View width view.getWidth();

View height view.getHeight() 

Orange line: view.getLeft()

Blue line: view.getRight()

Red line: view.getTop()

Pink line: view.getBottom()

The offsets of up, down, left and right are relative to ( 0.0 )


2. getRowX() and getX() in MotionEvent class 

1. event.getRowX(): The x coordinate of the touch point relative to the screen origin

2. event.getX(): The x coordinate of the touch point relative to the origin of the component where it is located 

Below is the specific code

package com.xugongming38.dragview;

import android.content.Context;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;


public class MainActivity extends AppCompatActivity implements View.OnTouchListener{
    private ImageView iv_dv_view;
    private int sx;
    private int sy;
    private SharedPreferences sp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);
        setContentView(R.layout.activity_main);
        if (getSupportActionBar() != null){
            getSupportActionBar().hide();
        }
        sp = this.getSharedPreferences("config", Context.MODE_PRIVATE);
        iv_dv_view = (ImageView) this.findViewById(R.id.iv_dv_view);
        sp = this.getSharedPreferences("config", Context.MODE_PRIVATE);
        iv_dv_view.setOnTouchListener(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (v.getId()) {
            // If the finger is dragged on the imageView
            case R.id.iv_dv_view:
                // event.getRawX(); //Get the coordinates of the first time the finger touches the screen in the x direction
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:// Get the first time the finger touches the screen
                        sx = (int) event.getRawX();
                        sy = (int) event.getRawY ();
                        iv_dv_view.setImageResource(R.drawable.t);
                        break;
                    case MotionEvent.ACTION_MOVE:// event corresponding to finger movement on the screen
                        int x = (int) event.getRawX();
                        int y = (int) event.getRawY();
                        // Get the distance the finger moved
                        int dx = x - sx;
                        int dy = y - sy;
                        // Get the coordinates of the first vertices of the imageView
                        int l = iv_dv_view.getLeft();
                        int r = iv_dv_view.getRight();
                        int t = iv_dv_view.getTop();
                        int b = iv_dv_view.getBottom();
                        // Change the position of imageView on the form
                        iv_dv_view.layout(l + dx, t + dy, r + dx, b + dy);
                        // Get the moved position
                        sx = (int) event.getRawX();
                        sy = (int) event.getRawY ();
                        break;
                    case MotionEvent.ACTION_UP:// The event corresponding to the finger leaving the screen
                        // Record the position of the last image in the form
                        int lasty = iv_dv_view.getTop();
                        int lastx = iv_dv_view.getLeft();
                        iv_dv_view.setImageResource(R.drawable.next);
                        SharedPreferences.Editor editor = sp.edit();
                        editor.putInt("lasty", lasty);
                        editor.putInt("lastx", lastx);
                        editor.commit();
                        break;
                }
                break;
        }
        return true;// will not interrupt the return of touch events
    }
}


To put it simply, this is very simple. It is to set the setOnTouchListener of the control, record the position where the control is pressed, then calculate the sliding distance, and finally use iv_dv_view.layout(l + dx, t + dy, r + dx, b + dy) ; Change the position of imageView in the form. However, when I use it like this in the project, I find that the controls I define keep flickering when sliding, so this code may only be used for simple controls, and may not work for complex controls.


2. Use LayoutParams to implement dragging of controls.

1. Define variables

private boolean isLongPress = false ;
 private int startX , startY ; //The position of the control long press
 private RelativeLayout curPressView ;
 private LinearLayout.LayoutParams params ; //The LayoutParams of the control, easy to restore the control position when it is lifted
 private LinearLayout.LayoutParams m_LinearParams ; // Set the position when the control moves LayoutParams
 private LinearLayout mLlDeleteCamera ;
 private ImageView mImgDeleteCamera ;
 private int [] location = new int [ 2];
private int deleteHeight = 0;
private boolean isTouchDelete = false;


2. Record the position of the long press

  @Override
public void onLongPress(MotionEvent event) {
            super.onLongPress(event);
isLongPress = true;
startX = (int) event.getRawX();
startY = (int) event.getRawY();
if (m_LinearParams == null) {
                m_LinearParams = new LinearLayout.LayoutParams(
                        LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams                                            
                                    .MATCH_PARENT, 1);
            }

            curPressView = (RelativeLayout) monitorView.findView(MonitorView.MONITOR_RL_ID, channelCurSelected);
params = (LinearLayout.LayoutParams) curPressView.getLayoutParams();
if (checkCurrentItemStatusByCloseSingVideo(channelCurSelected)) {
                mLlDeleteCamera.setVisibility(View.VISIBLE);
if (!fullScreen) {
                    monitorContent.getLocationOnScreen(            

                            location);
deleteHeight = location[1] - PublicFunction.dip2px(MyApplication.app, 50f);
} else {
                    deleteHeight = 0;
}                                                    
            }

//            Log.e("test_LongPres", "onLongPress " + monitorContent.getHeight() + "  " + location[1] + "  " + deleteHeight);
}
        


Sliding control, this is in the public boolean onTouch(View v, MotionEvent event) function

                    if (isLongPress) {
                        if (curPressView == null) {
                            isLongPress = true;
                            return gestureDetector.onTouchEvent(event);
                        }

                        switch (event.getAction()) {
                            case MotionEvent.ACTION_MOVE:// 手指在屏幕上移动对应的事件
                                int dx = (int) event.getRawX() - startX;
                                int dy = (int) event.getRawY() - startY;

                                m_LinearParams.leftMargin = params.leftMargin + dx;
                                m_LinearParams.rightMargin = params.rightMargin - dx;
                                m_LinearParams.topMargin = params.topMargin + dy;
                                m_LinearParams.bottomMargin = params.bottomMargin - dy;
                                curPressView.setLayoutParams(m_LinearParams);
                                curPressView.getLocationOnScreen(location);


                                if (checkCurrentItemStatusByCloseSingVideo(channelCurSelected)) {
                                    if (location[1] < deleteHeight) {
                                        if (isTouchDelete == false) {
                                            mLlDeleteCamera.setBackgroundColor(Color.RED);
                                            mImgDeleteCamera.setImageResource(R.drawable.delete_camera_2);
                                            isTouchDelete = true;
                                        }
                                    } else {
                                        if (isTouchDelete) {
                                            mLlDeleteCamera.setBackgroundResource(R.color.colorPrimaryNormal);
                                            mImgDeleteCamera.setImageResource(R.drawable.delete_camera_1);
                                            isTouchDelete = false;
                                        }
                                    }
//                                    Log.e("test_LongPres", "ACTION_MOVE:  " + m_LinearParams.leftMargin + "  " + m_LinearParams.topMargin + "  " + m_LinearParams.rightMargin + "  " + m_LinearParams.bottomMargin
//                                            + location[0] + "  " + location[1]);

                                }

                                break;
                            case MotionEvent.ACTION_UP:// 手指离开屏幕对应事件
                                curPressView.setLayoutParams(params);
                                isLongPress = false;
                                curPressView = null;
                                params = null;

                                mLlDeleteCamera.setVisibility(View.GONE);
                                mLlDeleteCamera.setBackgroundResource(R.color.colorPrimaryNormal);
                                mImgDeleteCamera.setImageResource(R.drawable.delete_camera_1);

//                                Log.e("test_LongPres", "ACTION_UP  " + isTouchDelete);

                                isTouchDelete = false;
                                break;
                            default:
                                break;

                        }
                        return true;



简单讲讲,因为我的需求是长按控件,才可以拖动控件,所以首先获取长按时点击的位置,还有控件的LinearLayout.LayoutParams,然后计算滑动的距离,设置LinearLayout.LayoutParams的Margin,这样控件基本就可以拖动。这里使用curPressView.getLocationOnScreen(location);是为了获取控件的坐标,当控件移动到某个位置时,进行一些逻辑操作。


这个是我自己在代码里实现了功能,控件拖动是正常的,而且没有闪烁的现象。大家有兴趣的可以自己查找资料实现一下功能。


android 如何拖动控件的实现就讲完了。


就这么简单。



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324849770&siteId=291194637