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 如何拖动控件的实现就讲完了。
就这么简单。