自由移動組件SimpleMovingView
- 功能簡介
- Gif演示
- 實作步驟
- java代碼
android安卓開發集合-自定義View-頁面布局-實用功能:點擊查看
功能簡介
自由移動的組件,自由切換是否僅允許在螢屏內移動,可監聽是否為點擊事件
相關文章講解:
View.layout如何重繪控制元件位置?點擊跳轉
用layout方法重繪控制元件新位置后,為什么頁面有新的組件添加后,會重繪頁面,控制元件回到原來的位置 點擊跳轉
Gif演示

實作步驟
1.創建SimpleMovingView.java并繼承一個view
2.我們可以通過onTouchEvent的方法來獲取手勢相關資訊
3.MotionEvent.ACTION_DOWN按壓的時候記錄一下手指相對于SimpleMovingView的位置event.getX() event.getY()
4.MotionEvent.ACTION_MOVE移動的時候進行計算,當前手勢移動的event.getX() event.getY()減去按壓時候記錄的位置,則為SimpleMovingView移動的距離,
5.用layout(left,top,right,bottom)去重繪控制元件位置即可,
6.用layout方法去重繪控制元件位置會有個問題,當根視圖重繪時,會遍歷重繪其所有子視圖,那么SimpleMovingView就會回到移動前的位置了,如何解決這個問題可以看這篇文章. 點擊跳轉 ,想了解layout為什么重繪位置看這篇 點擊跳轉
7.MotionEvent.ACTION_UP手勢抬起的時候,檢測是否為點擊事件,可以實作setOnMovingViewClickListener介面用來監聽點擊事件,
8.如何視為點擊事件?判斷控制元件相對于螢屏的位置是否移動,this.getX() this.getY()可以獲取組件相對于螢屏中的位置,手勢按下的時候記錄一下,抬起的時候記錄一下,再進行判斷是否一致,一致則視為點擊事件,
java代碼
/**
* 簡介:簡單可移動View
* 作者:游豐澤
* 主要功能: 自由移動組件,并可反饋點擊事件
* mIsLimitedInScreen 設定是否限制僅在螢屏內移動
* setOnMovingViewClickListener 實作介面,回傳點擊事件
*/
public class SimpleMovingView extends LinearLayout {
private Context mContext;
//是否限制僅在螢屏內移動
private boolean mIsLimitedInScreen =true;
//螢屏的長寬
private int mScreenHeight,mScreenWidth;
//記錄手指按下時,手指相對于組件的X,Y位置.
private float mDownOnViewX =0,mDownOnViewY =0;
//記錄手指按下時,組件相對于螢屏的X,Y絕對位置.
private float mDownOnScreenX =0,mDownOnScreenY =0;
//記錄手指移動時與按下時的X,Y距離
private float mMoveOnViewXDistance =0,mMoveOnViewYDistance =0;
//記錄新位置left top right bottom;
private int mNewLeft=0,mNewTop=0,mNewRight=0,mNewBottom=0;
//點擊回呼
private OnClickListener mOnClickListener;
public SimpleMovingView(Context context) {
super(context);
initial(context);
}
public SimpleMovingView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initial(context);
}
public SimpleMovingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initial(context);
}
private void initial(Context context){
mContext=context;
DisplayMetrics dm= new DisplayMetrics();
WindowManager wm=(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics( dm );
mScreenHeight =dm.heightPixels;
mScreenWidth =dm.widthPixels;
}
//return true,截獲觸摸焦點,并處理不同的手勢事件
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
mDownOnViewX = event.getX();
mDownOnViewY = event.getY();
mDownOnScreenX= this.getX();
mDownOnScreenY= this.getY();
break;
case MotionEvent.ACTION_MOVE:
mMoveOnViewXDistance =event.getX()- mDownOnViewX;
mMoveOnViewYDistance =event.getY()- mDownOnViewY;
mNewLeft=(int)(getLeft()+ mMoveOnViewXDistance);
mNewTop=(int)(getTop()+ mMoveOnViewYDistance);
mNewRight=(int)(getRight()+ mMoveOnViewXDistance);
mNewBottom=(int)(getBottom()+ mMoveOnViewYDistance);
if(mIsLimitedInScreen){ //如果開啟了限制僅允許在螢屏內移動
checkIfOverBoundary();
}
refreshNewPosition();
break;
case MotionEvent.ACTION_UP:
if(null != mOnClickListener){ //如果添加了監聽
if(mDownOnScreenX==this.getX() && mDownOnScreenY==this.getY()) { //且組件沒有移動
mOnClickListener.isClick(true);
}
}
break;
default:
break;
}
return true;
}
//重繪位置UI
private void refreshNewPosition(){
layout(mNewLeft,mNewTop,mNewRight,mNewBottom); //重繪位置UI
}
//檢測是否超出邊界
private void checkIfOverBoundary(){
if(mNewLeft<0){ //左邊朝邊界
mNewLeft=0;
mNewRight=mNewLeft+getWidth();
}
if(mNewTop<0){ //上邊朝邊界
mNewTop=0;
mNewBottom=mNewTop+getHeight();
}
if(mNewRight>mScreenWidth){ //右邊朝邊界
mNewRight=mScreenWidth;
mNewLeft=mNewRight-getWidth();
}
if(mNewBottom>mScreenHeight){ //下邊朝邊界
mNewBottom=mScreenHeight;
mNewTop=mNewBottom-getHeight();
}
}
//向外提供監聽介面
public void setOnMovingViewClickListener(OnClickListener onClickListener){
this.mOnClickListener=onClickListener;
}
//介面回呼-點擊
public interface OnClickListener{
void isClick(boolean isClick);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/279288.html
標籤:其他
