描述的是设备的配置信息
获取像素密度、横竖屏、键盘信息、字体缩放等级等等信息
private void getConfig() {
StringBuilder sb = new StringBuilder();
Configuration conf = context.getResources().getConfiguration();
if (conf.orientation == Configuration.ORIENTATION_LANDSCAPE) {
// 横屏
sb.append("横屏\n");
} else if (conf.orientation == Configuration.ORIENTATION_PORTRAIT) {
// 竖屏
sb.append("竖屏\n");
}
// 字体缩放级别
sb.append("frontScale:" + conf.fontScale + "\n");
sb.append("像素密度:" + conf.densityDpi + "\n");
sb.append("键盘:"
+ (conf.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO ? "划出"
: "隐藏"));
tvHello.setText(sb.toString());
}
获取视图操作常用配置信息
如判定双击时间间隔判定,长按时间间隔判定,滑动距离判定,滑动距离、速度
private void getViewConfig() {
StringBuilder sb = new StringBuilder();
ViewConfiguration vConf = ViewConfiguration.get(context);
sb.append("双击间隔时间:" + vConf.getDoubleTapTimeout() + "\n");
sb.append("长按时间:" + vConf.getLongPressTimeout() + "\n");
sb.append("Fling速度最小值:" + vConf.getScaledMinimumFlingVelocity() + "\n");
sb.append("Fling速度最大值:" + vConf.getScaledMaximumFlingVelocity() + "\n");
sb.append("Fling滑动距离:" + vConf.getScaledOverflingDistance() + "\n");
sb.append("判定滑动的距离:" + vConf.getScaledTouchSlop() + "\n");
tvHello.setText(sb.toString());
}
class GestureImpl implements GestureDetector.OnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
// 触碰到屏幕
return false;
}
@Override
public void onShowPress(MotionEvent e) {
// 按下未松开
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
// 轻击屏幕
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
// 滑动 无论滑动速率快慢都会触发
return false;
}
@Override
public void onLongPress(MotionEvent e) {
// 长按
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
/* * 滑动 和onScroll相比此方法对滑动的速率有一定的要求 * 速率大小从ViewConfiguration的getScaledMinimumFlingVelocity(), * getScaledMaximumFlingVelocity()获取 */
return false;
}
}
2.生成GestureDecetor对象
private GestureDetector mGDetector;
public MyView(Context context) {
super(context);
mGDetector = new GestureDetector(getContext(), new GestureImpl());
}
3.事件转发
例如View的onTouch事件
@Override
public boolean onTouchEvent(MotionEvent event) {
return mGDetector.onTouchEvent(event);
}
private void startVelocityTracker(MotionEvent event) {
if (vTracker == null) {
vTracker = VelocityTracker.obtain();
}
vTracker.addMovement(event);
}
2.追踪事件
private int getScrollTrakcer() {
//1000ms内的变化
vTracker.computeCurrentVelocity(1000);
//X轴的变化
int velocity = (int) vTracker.getXVelocity();
return Math.abs(velocity);
}
3.回收资源
private void stopVelocityTracker() {
if (vTracker != null) {
vTracker.recycle();
vTracker = null;
}
}
scroll改变的是View填充的内容,view所处的位置和背景是不变的。
阴影部分表示内容
Scroll的坐标系刚好和笛卡尔坐标系相反,以左上角为坐标原点(0,0)
也就相当于Android-Scroll坐标系的(-100,-100) 等价于 笛卡尔坐标系的(100,100)
scrollBy 其实调用的是scrollTo的方法
public void scrollBy(int x, int y) {
scrollTo(mScrollX + x, mScrollY + y);
}
只是scrollBy会保留上次的移动位置
Android的侧滑菜单,在DrawerLayout出现之前,侧滑菜单都是由第三方开源代码实现的,其中著名的当属 MenuDrawer ,MenuDrawer重写onTouchEvent方法来实现侧滑效果,代码量很大,实现逻辑也需要很大的耐心才能看懂。为了解拖动手势分析过于复杂,Google提出了ViewDragHelper,其作用和GrestureDecetor类似,简化操作。
我们来一步一步的创建一个ViewDragHelper。
ViewDragHelper一般用在一个自定义ViewGroup的内部。
private final ViewDragHelper mDragHelper;
void init(){
mDragHelper = ViewDragHelper.create(this, 1f, new DragHelperCallback());
}
其中
第一个参数为this,表示该类生成的对象,他是ViewDragHelper的拖动处理对象,必须为ViewGroup,因为拖动的是子View他必定存在于一个ViewGrounp中。
第二个参数表示敏感度,数值越高越敏感;
第三个参数是拖动回调,需要自己实现
重要方法:
1.水平拖动
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
if (mDragHorizontal || mDragCapture || mDragEdge) {
final int leftBound = getPaddingLeft();
final int rightBound = getWidth() - mDragView1.getWidth();
final int newLeft = Math.min(Math.max(left, leftBound),
rightBound);
return newLeft;
}
return super.clampViewPositionHorizontal(child, left, dx);
}
第二个参数left表示拖动的具体位置返回,一般我们不需要处理它,但是这里需要让view滑动的范围处于x轴的(leftPadding,getWidth()-view.width)之间,就需要做一些判断
2.垂直拖动
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
if (mDragVertical) {
final int topBound = getPaddingTop();
final int bottomBound = getHeight() - mDragView1.getHeight();
// Math.max(top, topBound) 上边界的最小值,让子view不能在上方滑出视图
// Math.min 下边界 让子view不能从下方滑出视图
final int newTop = Math.min(Math.max(top, topBound),
bottomBound);
return newTop;
}
return super.clampViewPositionVertical(child, top, dy);
}
@Override
public void onEdgeDragStarted(int edgeFlags, int pointerId) {
// 不用接触拖动view直接接触边缘即可拖动
if (mDragEdge) {
mDragHelper.captureChildView(mDragView1, pointerId);
}
}
public void setDragEdge(boolean dragEdge) {
// 设置左边缘
mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
mDragEdge = dragEdge;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// 拖动结束
final int action = MotionEventCompat.getActionMasked(ev);
if (action == MotionEvent.ACTION_CANCEL
|| action == MotionEvent.ACTION_UP) {
mDragHelper.cancel();
return false;
}
return mDragHelper.shouldInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// 拖动开始
mDragHelper.processTouchEvent(ev);
return true;
}
参考:http://blog.csdn.net/lfdfhl/article/details/51324275