android 如何拖动控件的实现
今天,簡(jiǎn)單講講android如何拖動(dòng)控件。
之前,需要做一個(gè)功能,實(shí)現(xiàn)控件按照手勢(shì)進(jìn)行拖動(dòng),拖動(dòng)到移動(dòng)位置時(shí)可以進(jìn)行一些操作。當(dāng)時(shí)不知道怎么做,于是在網(wǎng)上查找了資料,終于是解決了這個(gè)問(wèn)題。這里記錄一下。
一.使用view.layout(left, top, right, bottom)實(shí)現(xiàn)拖動(dòng)。
1.按下圖搞懂幾個(gè)坐標(biāo)
視圖寬度 view.getWidth();
視圖高度 view.getHeight()?
橘色線:view.getLeft()
藍(lán)色線:view.getRight()
紅色線:view.getTop()
粉色線:view.getBottom()
上下左右的偏移都是相對(duì)于(0.0)來(lái)說(shuō)的
2. MotionEvent類中 getRowX()和 getX()?
1、event.getRowX():觸摸點(diǎn)相對(duì)于屏幕原點(diǎn)的x坐標(biāo)
2、event.getX():?? ?觸摸點(diǎn)相對(duì)于其所在組件原點(diǎn)的x坐標(biāo)?
下面是具體的代碼
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;@Overrideprotected 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);}@Overrideprotected void onResume() {super.onResume();}@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (v.getId()) {// 如果手指放在imageView上拖動(dòng)case R.id.iv_dv_view:// event.getRawX(); //獲取手指第一次接觸屏幕在x方向的坐標(biāo)switch (event.getAction()) {case MotionEvent.ACTION_DOWN:// 獲取手指第一次接觸屏幕sx = (int) event.getRawX();sy = (int) event.getRawY();iv_dv_view.setImageResource(R.drawable.t);break;case MotionEvent.ACTION_MOVE:// 手指在屏幕上移動(dòng)對(duì)應(yīng)的事件int x = (int) event.getRawX();int y = (int) event.getRawY();// 獲取手指移動(dòng)的距離int dx = x - sx;int dy = y - sy;// 得到imageView最開(kāi)始的各頂點(diǎn)的坐標(biāo)int l = iv_dv_view.getLeft();int r = iv_dv_view.getRight();int t = iv_dv_view.getTop();int b = iv_dv_view.getBottom();// 更改imageView在窗體的位置iv_dv_view.layout(l + dx, t + dy, r + dx, b + dy);// 獲取移動(dòng)后的位置sx = (int) event.getRawX();sy = (int) event.getRawY();break;case MotionEvent.ACTION_UP:// 手指離開(kāi)屏幕對(duì)應(yīng)事件// 記錄最后圖片在窗體的位置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;// 不會(huì)中斷觸摸事件的返回} }
簡(jiǎn)單講講,這個(gè)很簡(jiǎn)單,就是設(shè)置控件的setOnTouchListener,記錄在控件按下的位置,然后計(jì)算滑動(dòng)的距離,最后使用iv_dv_view.layout(l + dx, t + dy, r + dx, b + dy);改imageView在窗體的位置。不過(guò)我在項(xiàng)目?jī)?nèi)這樣使用時(shí),卻發(fā)現(xiàn)自己定義的控件滑動(dòng)的時(shí)候不停的閃爍,所以這個(gè)代碼可能只使用于簡(jiǎn)單的控件,對(duì)于復(fù)雜的控件可能不行。
二.使用LayoutParams實(shí)現(xiàn)控件的拖動(dòng)。
1.定義變量
private boolean isLongPress = false; private int startX, startY; //控件長(zhǎng)按的位置 private RelativeLayout curPressView; private LinearLayout.LayoutParams params; //控件的LayoutParams,便于抬起時(shí)恢復(fù)控件位置 private LinearLayout.LayoutParams m_LinearParams; //控件移動(dòng)時(shí)設(shè)置位置LayoutParams private LinearLayout mLlDeleteCamera; private ImageView mImgDeleteCamera; private int[] location = new int[2]; private int deleteHeight = 0; private boolean isTouchDelete = false;
2.記錄長(zhǎng)按時(shí)的位置
@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); }
滑動(dòng)控件,這個(gè)在public boolean onTouch(View v, MotionEvent event)函數(shù)里
if (isLongPress) {if (curPressView == null) {isLongPress = true; return gestureDetector.onTouchEvent(event); }switch (event.getAction()) {case MotionEvent.ACTION_MOVE:// 手指在屏幕上移動(dòng)對(duì)應(yīng)的事件 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:// 手指離開(kāi)屏幕對(duì)應(yīng)事件 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;
簡(jiǎn)單講講,因?yàn)槲业男枨笫情L(zhǎng)按控件,才可以拖動(dòng)控件,所以首先獲取長(zhǎng)按時(shí)點(diǎn)擊的位置,還有控件的LinearLayout.LayoutParams,然后計(jì)算滑動(dòng)的距離,設(shè)置LinearLayout.LayoutParams的Margin,這樣控件基本就可以拖動(dòng)。這里使用curPressView.getLocationOnScreen(location);是為了獲取控件的坐標(biāo),當(dāng)控件移動(dòng)到某個(gè)位置時(shí),進(jìn)行一些邏輯操作。
這個(gè)是我自己在代碼里實(shí)現(xiàn)了功能,控件拖動(dòng)是正常的,而且沒(méi)有閃爍的現(xiàn)象。大家有興趣的可以自己查找資料實(shí)現(xiàn)一下功能。
android 如何拖動(dòng)控件的實(shí)現(xiàn)就講完了。
就這么簡(jiǎn)單。
總結(jié)
以上是生活随笔為你收集整理的android 如何拖动控件的实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: android SharedPrefer
- 下一篇: android 如何监听应用前后台切换