@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 计算所有child view 要占用的空间
desireWidth = 0;
desireHeight = 0;
int count = getChildCount();
for (int i = 0; i < count; ++i) {
View v = getChildAt(i);
if (v.getVisibility() != View.GONE) {
measureChild(v, widthMeasureSpec,
heightMeasureSpec);
desireWidth += v.getMeasuredWidth();
desireHeight = Math
.max(desireHeight, v.getMeasuredHeight());
}
}
// count with padding
desireWidth += getPaddingLeft() + getPaddingRight();
desireHeight += getPaddingTop() + getPaddingBottom();
// see if the size is big enough
desireWidth = Math.max(desireWidth, getSuggestedMinimumWidth());
desireHeight = Math.max(desireHeight, getSuggestedMinimumHeight());
setMeasuredDimension(resolveSize(desireWidth, widthMeasureSpec),
resolveSize(desireHeight, heightMeasureSpec));
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int parentLeft = getPaddingLeft();
final int parentRight = r - l - getPaddingRight();
final int parentTop = getPaddingTop();
final int parentBottom = b - t - getPaddingBottom();
if (BuildConfig.DEBUG)
Log.d("onlayout", "parentleft: " + parentLeft + " parenttop: "
+ parentTop + " parentright: " + parentRight
+ " parentbottom: " + parentBottom);
int left = parentLeft;
int top = parentTop;
int count = getChildCount();
for (int i = 0; i < count; ++i) {
View v = getChildAt(i);
if (v.getVisibility() != View.GONE) {
final int childWidth = v.getMeasuredWidth();
final int childHeight = v.getMeasuredHeight();
v.layout(left, top, left + childWidth, top + childHeight);
left += childWidth;
}
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <com.example.testslidelistview.SlideGroup android:id="@+id/sl" android:layout_width="match_parent" android:layout_height="500dp" android:layout_marginTop="50dp" android:background="#FFFF00" > <ImageView android:id="@+id/iv1" android:layout_width="150dp" android:layout_height="300dp" android:scaleType="fitXY" android:src="@drawable/lead_page_1" /> <ImageView android:layout_width="150dp" android:layout_height="300dp" android:scaleType="fitXY" android:src="@drawable/lead_page_2" /> <ImageView android:layout_width="150dp" android:layout_height="300dp" android:scaleType="fitXY" android:src="@drawable/lead_page_3" /> </com.example.testslidelistview.SlideGroup> </LinearLayout>
@Override
protected android.view.ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
}
@Override
public android.view.ViewGroup.LayoutParams generateLayoutParams(
AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
@Override
protected android.view.ViewGroup.LayoutParams generateLayoutParams(
android.view.ViewGroup.LayoutParams p) {
return new LayoutParams(p);
}
public static class LayoutParams extends MarginLayoutParams {
public int gravity = -1;
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
TypedArray ta = c.obtainStyledAttributes(attrs,
R.styleable.SlideGroup);
gravity = ta.getInt(R.styleable.SlideGroup_layout_gravity, -1);
ta.recycle();
}
public LayoutParams(int width, int height) {
this(width, height, -1);
}
public LayoutParams(int width, int height, int gravity) {
super(width, height);
this.gravity = gravity;
}
public LayoutParams(android.view.ViewGroup.LayoutParams source) {
super(source);
}
public LayoutParams(MarginLayoutParams source) {
super(source);
}
}
<?xml version="1.0" encoding="utf-8"?> <resources> <attr name="layout_gravity"> <!-- Push object to the top of its container, not changing its size. --> <flag name="top" value="0x30" /> <!-- Push object to the bottom of its container, not changing its size. --> <flag name="bottom" value="0x50" /> <!-- Push object to the left of its container, not changing its size. --> <flag name="left" value="0x03" /> <!-- Push object to the right of its container, not changing its size. --> <flag name="right" value="0x05" /> <!-- Place object in the vertical center of its container, not changing its size. --> <flag name="center_vertical" value="0x10" /> <!-- Place object in the horizontal center of its container, not changing its size. --> <flag name="center_horizontal" value="0x01" /> </attr> <declare-styleable name="SlideGroup"> <attr name="layout_gravity" /> </declare-styleable> </resources>
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 计算所有child view 要占用的空间
desireWidth = 0;
desireHeight = 0;
int count = getChildCount();
for (int i = 0; i < count; ++i) {
View v = getChildAt(i);
if (v.getVisibility() != View.GONE) {
LayoutParams lp = (LayoutParams) v.getLayoutParams();
//将measureChild改为measureChildWithMargin
measureChildWithMargins(v, widthMeasureSpec, 0,
heightMeasureSpec, 0);
//这里在计算宽度时加上margin
desireWidth += v.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
desireHeight = Math
.max(desireHeight, v.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
}
}
// count with padding
desireWidth += getPaddingLeft() + getPaddingRight();
desireHeight += getPaddingTop() + getPaddingBottom();
// see if the size is big enough
desireWidth = Math.max(desireWidth, getSuggestedMinimumWidth());
desireHeight = Math.max(desireHeight, getSuggestedMinimumHeight());
setMeasuredDimension(resolveSize(desireWidth, widthMeasureSpec),
resolveSize(desireHeight, heightMeasureSpec));
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int parentLeft = getPaddingLeft();
final int parentRight = r - l - getPaddingRight();
final int parentTop = getPaddingTop();
final int parentBottom = b - t - getPaddingBottom();
if (BuildConfig.DEBUG)
Log.d("onlayout", "parentleft: " + parentLeft + " parenttop: "
+ parentTop + " parentright: " + parentRight
+ " parentbottom: " + parentBottom);
int left = parentLeft;
int top = parentTop;
int count = getChildCount();
for (int i = 0; i < count; ++i) {
View v = getChildAt(i);
if (v.getVisibility() != View.GONE) {
LayoutParams lp = (LayoutParams) v.getLayoutParams();
final int childWidth = v.getMeasuredWidth();
final int childHeight = v.getMeasuredHeight();
final int gravity = lp.gravity;
final int horizontalGravity = gravity
& Gravity.HORIZONTAL_GRAVITY_MASK;
final int verticalGravity = gravity
& Gravity.VERTICAL_GRAVITY_MASK;
left += lp.leftMargin;
top = parentTop + lp.topMargin;
if (gravity != -1) {
switch (verticalGravity) {
case Gravity.TOP:
break;
case Gravity.CENTER_VERTICAL:
top = parentTop
+ (parentBottom - parentTop - childHeight)
/ 2 + lp.topMargin - lp.bottomMargin;
break;
case Gravity.BOTTOM:
top = parentBottom - childHeight - lp.bottomMargin;
break;
}
}
if (BuildConfig.DEBUG) {
Log.d("onlayout", "child[width: " + childWidth
+ ", height: " + childHeight + "]");
Log.d("onlayout", "child[left: " + left + ", top: "
+ top + ", right: " + (left + childWidth)
+ ", bottom: " + (top + childHeight));
}
v.layout(left, top, left + childWidth, top + childHeight);
left += childWidth + lp.rightMargin;
}
}
}
public static enum Orientation {
HORIZONTAL(0), VERTICAL(1);
private int value;
private Orientation(int i) {
value = i;
}
public int value() {
return value;
}
public static Orientation valueOf(int i) {
switch (i) {
case 0:
return HORIZONTAL;
case 1:
return VERTICAL;
default:
throw new RuntimeException("[0->HORIZONTAL, 1->VERTICAL]");
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 计算所有child view 要占用的空间
desireWidth = 0;
desireHeight = 0;
int count = getChildCount();
for (int i = 0; i < count; ++i) {
View v = getChildAt(i);
if (v.getVisibility() != View.GONE) {
LayoutParams lp = (LayoutParams) v.getLayoutParams();
measureChildWithMargins(v, widthMeasureSpec, 0,
heightMeasureSpec, 0);
//只是在这里增加了垂直或者水平方向的判断
if (orientation == Orientation.HORIZONTAL) {
desireWidth += v.getMeasuredWidth() + lp.leftMargin
+ lp.rightMargin;
desireHeight = Math.max(desireHeight, v.getMeasuredHeight()
+ lp.topMargin + lp.bottomMargin);
} else {
desireWidth = Math.max(desireWidth, v.getMeasuredWidth()
+ lp.leftMargin + lp.rightMargin);
desireHeight += v.getMeasuredHeight() + lp.topMargin
+ lp.bottomMargin;
}
}
}
// count with padding
desireWidth += getPaddingLeft() + getPaddingRight();
desireHeight += getPaddingTop() + getPaddingBottom();
// see if the size is big enough
desireWidth = Math.max(desireWidth, getSuggestedMinimumWidth());
desireHeight = Math.max(desireHeight, getSuggestedMinimumHeight());
setMeasuredDimension(resolveSize(desireWidth, widthMeasureSpec),
resolveSize(desireHeight, heightMeasureSpec));
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int parentLeft = getPaddingLeft();
final int parentRight = r - l - getPaddingRight();
final int parentTop = getPaddingTop();
final int parentBottom = b - t - getPaddingBottom();
if (BuildConfig.DEBUG)
Log.d("onlayout", "parentleft: " + parentLeft + " parenttop: "
+ parentTop + " parentright: " + parentRight
+ " parentbottom: " + parentBottom);
int left = parentLeft;
int top = parentTop;
int count = getChildCount();
for (int i = 0; i < count; ++i) {
View v = getChildAt(i);
if (v.getVisibility() != View.GONE) {
LayoutParams lp = (LayoutParams) v.getLayoutParams();
final int childWidth = v.getMeasuredWidth();
final int childHeight = v.getMeasuredHeight();
final int gravity = lp.gravity;
final int horizontalGravity = gravity
& Gravity.HORIZONTAL_GRAVITY_MASK;
final int verticalGravity = gravity
& Gravity.VERTICAL_GRAVITY_MASK;
if (orientation == Orientation.HORIZONTAL) {
// layout horizontally, and only consider vertical gravity
left += lp.leftMargin;
top = parentTop + lp.topMargin;
if (gravity != -1) {
switch (verticalGravity) {
case Gravity.TOP:
break;
case Gravity.CENTER_VERTICAL:
top = parentTop
+ (parentBottom - parentTop - childHeight)
/ 2 + lp.topMargin - lp.bottomMargin;
break;
case Gravity.BOTTOM:
top = parentBottom - childHeight - lp.bottomMargin;
break;
}
}
if (BuildConfig.DEBUG) {
Log.d("onlayout", "child[width: " + childWidth
+ ", height: " + childHeight + "]");
Log.d("onlayout", "child[left: " + left + ", top: "
+ top + ", right: " + (left + childWidth)
+ ", bottom: " + (top + childHeight));
}
v.layout(left, top, left + childWidth, top + childHeight);
left += childWidth + lp.rightMargin;
} else {
// layout vertical, and only consider horizontal gravity
left = parentLeft;
top += lp.topMargin;
switch (horizontalGravity) {
case Gravity.LEFT:
break;
case Gravity.CENTER_HORIZONTAL:
left = parentLeft
+ (parentRight - parentLeft - childWidth) / 2
+ lp.leftMargin - lp.rightMargin;
break;
case Gravity.RIGHT:
left = parentRight - childWidth - lp.rightMargin;
break;
}
v.layout(left, top, left + childWidth, top + childHeight);
top += childHeight + lp.bottomMargin;
}
}
}
}
<attr name="orientation"> <enum name="horizontal" value="0" /> <enum name="vertical" value="1" /> </attr>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <com.example.testslidelistview.SlideGroup xmlns:gs="http://schemas.android.com/apk/res-auto" android:id="@+id/sl" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="50dp" android:background="#FFFF00" > <ImageView android:id="@+id/iv1" android:layout_width="300dp" android:layout_height="200dp" android:layout_marginBottom="20dp" gs:layout_gravity="left" android:scaleType="fitXY" android:src="@drawable/lead_page_1" /> <ImageView android:layout_width="300dp" android:layout_height="200dp" android:layout_marginBottom="20dp" gs:layout_gravity="center_horizontal" android:scaleType="fitXY" android:src="@drawable/lead_page_2" /> <ImageView android:layout_width="300dp" android:layout_height="200dp" android:layout_marginBottom="20dp" gs:layout_gravity="right" android:scaleType="fitXY" android:src="@drawable/lead_page_3" /> </com.example.testslidelistview.SlideGroup> </LinearLayout>
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getAction();
if (BuildConfig.DEBUG)
Log.d("onTouchEvent", "action: " + action);
switch (action) {
case MotionEvent.ACTION_DOWN:
x = event.getX();
y = event.getY();
break;
case MotionEvent.ACTION_MOVE:
float mx = event.getX();
float my = event.getY();
//此处的moveBy是根据水平或是垂直排放的方向,
//来选择是水平移动还是垂直移动
moveBy((int) (x - mx), (int) (y - my));
x = mx;
y = my;
break;
}
return true;
}
//此处的moveBy是根据水平或是垂直排放的方向,
//来选择是水平移动还是垂直移动
public void moveBy(int deltaX, int deltaY) {
if (BuildConfig.DEBUG)
Log.d("moveBy", "deltaX: " + deltaX + " deltaY: " + deltaY);
if (orientation == Orientation.HORIZONTAL) {
if (Math.abs(deltaX) >= Math.abs(deltaY))
scrollBy(deltaX, 0);
} else {
if (Math.abs(deltaY) >= Math.abs(deltaX))
scrollBy(0, deltaY);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getAction();
if (BuildConfig.DEBUG)
Log.d("onTouchEvent", "action: " + action);
//将事件加入到VelocityTracker中,用于计算手指抬起时的初速度
if (velocityTracker == null) {
velocityTracker = VelocityTracker.obtain();
}
velocityTracker.addMovement(event);
switch (action) {
case MotionEvent.ACTION_DOWN:
x = event.getX();
y = event.getY();
if (!mScroller.isFinished())
mScroller.abortAnimation();
break;
case MotionEvent.ACTION_MOVE:
float mx = event.getX();
float my = event.getY();
moveBy((int) (x - mx), (int) (y - my));
x = mx;
y = my;
break;
case MotionEvent.ACTION_UP:
//maxFlingVelocity是通过ViewConfiguration来获取的初速度的上限
//这个值可能会因为屏幕的不同而不同
velocityTracker.computeCurrentVelocity(1000, maxFlingVelocity);
float velocityX = velocityTracker.getXVelocity();
float velocityY = velocityTracker.getYVelocity();
//用来处理实际的移动
completeMove(-velocityX, -velocityY);
if (velocityTracker != null) {
velocityTracker.recycle();
velocityTracker = null;
}
break;
return true;
}
private void completeMove(float velocityX, float velocityY) {
if (orientation == Orientation.HORIZONTAL) {
int mScrollX = getScrollX();
int maxX = desireWidth - getWidth();// - Math.abs(mScrollX);
if (Math.abs(velocityX) >= minFlingVelocity && maxX > 0) {
mScroller.fling(mScrollX, 0, (int) velocityX, 0, 0, maxX, 0, 0);
invalidate();
}
} else {
int mScrollY = getScrollY();
int maxY = desireHeight - getHeight();// - Math.abs(mScrollY);
if (Math.abs(velocityY) >= minFlingVelocity && maxY > 0) {
mScroller.fling(0, mScrollY, 0, (int) velocityY, 0, 0, 0, maxY);
invalidate();
}
}
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
if (orientation == Orientation.HORIZONTAL) {
scrollTo(mScroller.getCurrX(), 0);
postInvalidate();
} else {
scrollTo(0, mScroller.getCurrY());
postInvalidate();
}
}
}
private void completeMove(float velocityX, float velocityY) {
if (orientation == Orientation.HORIZONTAL) {
int mScrollX = getScrollX();
int maxX = desireWidth - getWidth();
if (mScrollX > maxX) {
// 超出了右边界,弹回
mScroller.startScroll(mScrollX, 0, maxX - mScrollX, 0);
invalidate();
} else if (mScrollX < 0) {
// 超出了左边界,弹回
mScroller.startScroll(mScrollX, 0, -mScrollX, 0);
invalidate();
} else if (Math.abs(velocityX) >= minFlingVelocity && maxX > 0) {
mScroller.fling(mScrollX, 0, (int) velocityX, 0, 0, maxX, 0, 0);
invalidate();
}
} else {
int mScrollY = getScrollY();
int maxY = desireHeight - getHeight();
if (mScrollY > maxY) {
// 超出了下边界,弹回
mScroller.startScroll(0, mScrollY, 0, maxY - mScrollY);
invalidate();
} else if (mScrollY < 0) {
// 超出了上边界,弹回
mScroller.startScroll(0, mScrollY, 0, -mScrollY);
invalidate();
} else if (Math.abs(velocityY) >= minFlingVelocity && maxY > 0) {
mScroller.fling(0, mScrollY, 0, (int) velocityY, 0, 0, 0, maxY);
invalidate();
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
if (velocityTracker == null) {
velocityTracker = VelocityTracker.obtain();
}
velocityTracker.addMovement(event);
switch (action) {
case MotionEvent.ACTION_DOWN:
// 获取索引为0的手指id
mPointerId = event.getPointerId(0);
x = event.getX();
y = event.getY();
if (!mScroller.isFinished())
mScroller.abortAnimation();
break;
case MotionEvent.ACTION_MOVE:
// 获取当前手指id所对应的索引,虽然在ACTION_DOWN的时候,我们默认选取索引为0
// 的手指,但当有第二个手指触摸,并且先前有效的手指up之后,我们会调整有效手指
// 屏幕上可能有多个手指,我们需要保证使用的是同一个手指的移动轨迹,
// 因此此处不能使用event.getActionIndex()来获得索引
final int pointerIndex = event.findPointerIndex(mPointerId);
float mx = event.getX(pointerIndex);
float my = event.getY(pointerIndex);
moveBy((int) (x - mx), (int) (y - my));
x = mx;
y = my;
break;
case MotionEvent.ACTION_UP:
velocityTracker.computeCurrentVelocity(1000, maxFlingVelocity);
float velocityX = velocityTracker.getXVelocity(mPointerId);
float velocityY = velocityTracker.getYVelocity(mPointerId);
completeMove(-velocityX, -velocityY);
if (velocityTracker != null) {
velocityTracker.recycle();
velocityTracker = null;
}
break;
case MotionEvent.ACTION_POINTER_UP:
// 获取离开屏幕的手指的索引
int pointerIndexLeave = event.getActionIndex();
int pointerIdLeave = event.getPointerId(pointerIndexLeave);
if (mPointerId == pointerIdLeave) {
// 离开屏幕的正是目前的有效手指,此处需要重新调整,并且需要重置VelocityTracker
int reIndex = pointerIndexLeave == 0 ? 1 : 0;
mPointerId = event.getPointerId(reIndex);
// 调整触摸位置,防止出现跳动
x = event.getX(reIndex);
y = event.getY(reIndex);
if (velocityTracker != null)
velocityTracker.clear();
}
break;
}
return true;
}
/**
* onInterceptTouchEvent()用来询问是否要拦截处理。 onTouchEvent()是用来进行处理。
*
* 例如:parentLayout----childLayout----childView 事件的分发流程:
* parentLayout::onInterceptTouchEvent()---false?--->
* childLayout::onInterceptTouchEvent()---false?--->
* childView::onTouchEvent()---false?--->
* childLayout::onTouchEvent()---false?---> parentLayout::onTouchEvent()
*
*
*
* 如果onInterceptTouchEvent()返回false,且分发的子View的onTouchEvent()中返回true,
* 那么onInterceptTouchEvent()将收到所有的后续事件。
*
* 如果onInterceptTouchEvent()返回true,原本的target将收到ACTION_CANCEL,该事件
* 将会发送给我们自己的onTouchEvent()。
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getActionMasked();
if (BuildConfig.DEBUG)
Log.d("onInterceptTouchEvent", "action: " + action);
if (action == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {
// 该事件可能不是我们的
return false;
}
boolean isIntercept = false;
switch (action) {
case MotionEvent.ACTION_DOWN:
// 如果动画还未结束,则将此事件交给onTouchEvet()处理,
// 否则,先分发给子View
isIntercept = !mScroller.isFinished();
// 如果此时不拦截ACTION_DOWN时间,应该记录下触摸地址及手指id,当我们决定拦截ACTION_MOVE的event时,
// 将会需要这些初始信息(因为我们的onTouchEvent将可能接收不到ACTION_DOWN事件)
mPointerId = ev.getPointerId(0);
// if (!isIntercept) {
downX = x = ev.getX();
downY = y = ev.getY();
// }
break;
case MotionEvent.ACTION_MOVE:
int pointerIndex = ev.findPointerIndex(mPointerId);
if (BuildConfig.DEBUG)
Log.d("onInterceptTouchEvent", "pointerIndex: " + pointerIndex
+ ", pointerId: " + mPointerId);
float mx = ev.getX(pointerIndex);
float my = ev.getY(pointerIndex);
if (BuildConfig.DEBUG)
Log.d("onInterceptTouchEvent", "action_move [touchSlop: "
+ mTouchSlop + ", deltaX: " + (x - mx) + ", deltaY: "
+ (y - my) + "]");
// 根据方向进行拦截,(其实这样,如果我们的方向是水平的,里面有一个ScrollView,那么我们是支持嵌套的)
if (orientation == Orientation.HORIZONTAL) {
if (Math.abs(x - mx) >= mTouchSlop) {
// we get a move event for ourself
isIntercept = true;
}
} else {
if (Math.abs(y - my) >= mTouchSlop) {
isIntercept = true;
}
}
//如果不拦截的话,我们不会更新位置,这样可以通过累积小的移动距离来判断是否达到可以认为是Move的阈值。
//这里当产生拦截的话,会更新位置(这样相当于损失了mTouchSlop的移动距离,如果不更新,可能会有一点点跳的感觉)
if (isIntercept) {
x = mx;
y = my;
}
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
// 这是触摸的最后一个事件,无论如何都不会拦截
if (velocityTracker != null) {
velocityTracker.recycle();
velocityTracker = null;
}
break;
case MotionEvent.ACTION_POINTER_UP:
solvePointerUp(ev);
break;
}
return isIntercept;
}
private void solvePointerUp(MotionEvent event) {
// 获取离开屏幕的手指的索引
int pointerIndexLeave = event.getActionIndex();
int pointerIdLeave = event.getPointerId(pointerIndexLeave);
if (mPointerId == pointerIdLeave) {
// 离开屏幕的正是目前的有效手指,此处需要重新调整,并且需要重置VelocityTracker
int reIndex = pointerIndexLeave == 0 ? 1 : 0;
mPointerId = event.getPointerId(reIndex);
// 调整触摸位置,防止出现跳动
x = event.getX(reIndex);
y = event.getY(reIndex);
if (velocityTracker != null)
velocityTracker.clear();
}
}
case MotionEvent.ACTION_UP:
//先判断是否是点击事件
final int pi = event.findPointerIndex(mPointerId);
if((isClickable() || isLongClickable())
&& ((event.getX(pi) - downX) < mTouchSlop || (event.getY(pi) - downY) < mTouchSlop)) {
//这里我们得到了一个点击事件
if(isFocusable() && isFocusableInTouchMode() && !isFocused())
requestFocus();
if(event.getEventTime() - event.getDownTime() >= ViewConfiguration.getLongPressTimeout() && isLongClickable()) {
//是一个长按事件
performLongClick();
} else {
performClick();
}
} else {
velocityTracker.computeCurrentVelocity(1000, maxFlingVelocity);
float velocityX = velocityTracker.getXVelocity(mPointerId);
float velocityY = velocityTracker.getYVelocity(mPointerId);
completeMove(-velocityX, -velocityY);
if (velocityTracker != null) {
velocityTracker.recycle();
velocityTracker = null;
}
}
break;
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有