1. 程式人生 > >實現view跟著手指滑動的效果(實現方式三)

實現view跟著手指滑動的效果(實現方式三)

第三種方式就是通過改變LayoutParams的方式實現該效果(這種方法是整個父佈局跟著一起動)

我們都知道LayoutParams儲存了一個view的佈局引數。因此可以在程式中,通過改變LayoutParams來動態的修改一個佈局的位置引數,從而達到改變view的位置的效果,我們可以很方便的在程式中使用getLayoutParams()來獲取一個view的LayoutParams。當然,計算偏移量的方法與Layout方法中計算offset也是一樣的。當獲取到偏移量之後,就可以通過setLayoutParams來改變其LayoutParams,程式碼如下所示:

LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
layoutParams.leftMargin = getLeft() + offsetX; layoutParams.topMargin = getTop() + offsetY; setLayoutParams(layoutParams);
完整程式碼如下
public class DragView extends TextView {

    private int lastX;
    private int lasty;
    public DragView(Context context) {
        super(context);
initView();
}

    public 
DragView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } private void initView() { setBackgroundColor(Color.BLUE); } @Override public boolean onTouchEvent(MotionEvent event) { int x = (int) event.getX(); int y = (int) event.getY();
switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //記錄觸控點的座標 lastX = x; lasty = y; break; case MotionEvent.ACTION_MOVE: //計算偏移量 int offsetX = x - lastX; int offsetY = y - lasty; LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams(); layoutParams.leftMargin = getLeft() + offsetX; layoutParams.topMargin = getTop() + offsetY; setLayoutParams(layoutParams); break; case MotionEvent.ACTION_UP: break; } return true; } }
不過這裡需要注意的是,通過getLayoutParams()獲取LayoutParams時,需要根據view所在父佈局的型別來設定不同的型別,比如這裡將view放在LinearLayout中就可以使用LinearLayout.LayoutParams.類似的,如果將view放在RelativeLayout中,就需要使用 RelativeLayout.LayoutParams當然這一切的前提是你必須要有一個父佈局,不然系統無法獲取LayoutParams.

在通過改變LayoutParams來改變一個view的位置時,通常改變的是這個view的Margin屬性,所以出了使用佈局的LayoutParams之外,還可以使用ViewGroup.MarginLayoutParams來實現這一個功能,程式碼如下所示

ViewGroup.MarginLayoutParams layoutParams1 = (ViewGroup.MarginLayoutParams) getLayoutParams();
layoutParams1.leftMargin = getLeft() + offsetX;
layoutParams1.topMargin = getTop() + offsetY;
setLayoutParams(layoutParams1);
可以發現使用ViewGroup.MarginLayoutParams更加的方便,不需要考慮父佈局的型別,當然它們的本質是一樣的。