View体系第二篇:View滑动
View滑动的基本思想:当点击事件传到View时,系统记下触摸点的坐标,手指移动时系统记下触摸后的坐标并计算出偏移量,然后根据偏移量修正View坐标.
实现View滑动共有6种方法:layout()方法,offsetTopAndBottom(),LayoutParams,动画,scrollTo与scrollBy,以及Scroller.
一.layout()
import ...;
public class CustomView extends View {
private int lastX;
private int lastY;
public CustomView(Context context) {
super(context);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@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;
//修改View的left,top,right,bottom属性重新放置View
layout(getLeft() + offsetX, getTop() + offsetY, getRight() + offsetX, getBottom() + offsetY);
break;
}
return true;
}
}
然后在布局文件中引用就好了:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical"
> <com.example.scroll_test.CustomView
android:layout_width="80dp"
android:layout_height="80dp"
android:background="@color/colorAccent"
/> </LinearLayout>
二.offsetLeftandRight
这种方法与Layout()方法相似,只需将ACTION_MOVE修改成以下代码:
case MotionEvent.ACTION_MOVE:
int offsetX = x - lastX;
int offsetY = y - lastY;
offsetLeftAndRight(offsetX);
offsetTopAndBottom(offsetY);
break;
}
三.LayoutParams(改变布局参数)
通过LayoutParams改变View的布局参数,从而达到修改View位置的效果.
将ACTION_MOVE修改成以下代码:
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;
}
由于父控件是LinearLayout,所以用到了LineatLayout.LayoutParams.如果是RelativeLayout,则要使用RelativeLayot.LayoutParams.还可以用ViewGroup.MarginLayoutParams来实现:
ViewGroup.MarginLayoutParams layoutParams= (LinearLayout.LayoutParams) getLayoutParams();
layoutParams.leftMargin=getLeft() + offsetX;
layoutParams.topMargin=getTop() + offsetY;
setLayoutParams(layoutParams);
四.属性动画
ObjectAnimator.ofFloat(mCustomView,"translationX",0,300).setDuration().start();
五.scrollTo与scrollBy
scrollTo(x,y)表示移动到一个具体的点,scrollBy(dx,dy)表示移动的增量为dx,dy.
scrollTo,scrollBy移动的是View的内容,如果在ViewGround中使用,则是移动其所有的子View..我们将ACTION_MOVE替换成如下代码:
((View)getParent()).scrollBy(-offsetX,-offsetY);
设置为负值,则CustomView会跟随手滑动.原因是因为此时移动的是手机屏幕,布局是不移动的.布局中的控件也是不懂的,手指向右滑动后,想要View也向右滑动,则要把手机屏幕向着左边滑动,则布局相对向右滑动,实现跟手的效果.
六.Scroller
这个方法的实现效果比较类似动画,不过与动画相比其只可以用来实现滑动效果.
首先要初始化这个scroller:
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
scroller=new Scroller(context);
}
接下来重写computeScroll()方法,该方法会在View绘制时的draw()中调用
@Override
public void computeScroll() {
super.computeScroll();
if(scroller.computeScrollOffset()){
((View)getParent()).scrollTo(scroller.getCurrX(),scroller.getCurrY());
//通过不断调用invalidate(),不断返回调用computeScroll,更新View位置
// 直到scroller.computeScrolloffset返回fasle(即dutation结束)
invalidate();
}
}
同时在CustomView中写一个方法:
public void smoothScrollTo(int destX,int dextY){
int scrollX=getScrollX();
int deltaX=destX-scrollX;
//startScroll (int startX, int startY, int dx, int dy, int duration)
scroller.startScroll(scrollX,0,deltaX,0,2000);
invalidate();
}
通过在代码中调用自定义控件的smoothScrollTo方法,可以实现View的滑动效果.
View体系第二篇:View滑动的更多相关文章
- Android学习笔记(第二篇)View中的五大布局
PS:人不要低估自己的实力,但是也不能高估自己的能力.凡事谦为本... 学习内容: 1.用户界面View中的五大布局... i.首先介绍一下view的概念 view是什么呢?我们已经知道一个Act ...
- View体系第一篇:基础
View体系的学习内容为学习刘望舒先生博客总结的内容,大家可到他的博客看到更详细的内容. 一.view之间的继承关系 Viewground用来包裹其他view.在平常的使用中,我们不会直接用到View ...
- 《Android进阶之光》--View体系与自定义View
No1: View的滑动 1)layout()方法的 public class CustomView extends View{ private int lastX; private int last ...
- Android View体系(一)视图坐标系
前言 Android View体系是界面编程的核心,他的重要性不亚于Android四大组件,在这个系列中我会陆续讲到View坐标系.View的滑动.View的事件分发等文章来逐步介绍Android V ...
- Android View体系(四)从源码解析Scroller
在Android View体系(二)实现View滑动的六种方法这篇文章中我们讲到了用Scroller来实现View的滑动,所以这篇文章我们就不介绍Scroller是如何使用的了,本篇就从源码来分析下S ...
- android自定义View之仿通讯录侧边栏滑动,实现A-Z字母检索
我们的手机通讯录一般都有这样的效果,如下图: OK,这种效果大家都见得多了,基本上所有的android手机通讯录都有这样的效果.那我们今天就来看看这个效果该怎么实现. 一.概述 1.页面功能分析 整体 ...
- Android View体系(三)属性动画
上一篇文章讲了View滑动的六种方法,其中一种是使用动画,这篇文章我们来讲一讲动画的其中一种:属性动画. 1.android视图动画和属性动画 视图动画我们都了解,它提供了AlphaAnimation ...
- Android View体系(八)从源代码解析View的layout和draw流程
相关文章 Android View体系(一)视图坐标系 Android View体系(二)实现View滑动的六种方法 Android View体系(三)属性动画 Android View体系(四)从源 ...
- Android View体系(十)自定义组合控件
相关文章 Android View体系(一)视图坐标系 Android View体系(二)实现View滑动的六种方法 Android View体系(三)属性动画 Android View体系(四)从源 ...
随机推荐
- 我面试过没有上万人也有十几个,简历要这么写才有hr要你
今天终于有时间好好给大家写写关于如何写简历,给自己加分了. 这篇文章拖了很久了应该说,本来想在上周写的,但是事情实在是太多,又不想草草了事,所以搁置到现在.今天早上正好空出来了,就马上给大家码出来了. ...
- eslint prettier editrorconfig - 写出干净的前端代码
FConfidence 关注 2018.12.30 02:38* 字数 2912 阅读 195评论 0喜欢 0 VSCode 插件安装 Prettier - Code Formatter ESLint ...
- Mac 下使用svn
作为一个一直使用windows系统的人,还真不知道mac上的svn如何使用,偶然机会下现在需要. 查过后发现 mac 是自带svn的,在我装好xcode后,再安装 Command Line Tools ...
- Zabbix系列之五——监控TCP端口
监控端口的几个主要Keys: net.tcp.listen[port] Checks if this port is in LISTEN state. 0 - it is not, 1 - it is ...
- Android--UI之Button
前言 最近一直在讲androidUI控件的使用方式,这篇博客讲解一下基本上属于用处最广泛的控件之一的Button控件.如果有过其他平台开发经验的程序员,对按钮是不会陌生的.本篇博客首先讲解一下Andr ...
- 【干货】Jquery.Datables与Bootstrap3的组合使用
官方地址 datatables官方网址:www.datatables.net 下载bootstrap3与datables文件包 引用文件 css:bootstrap.css.dataTables.bo ...
- Docker 快速入门之 Dockerfile
在 Docker 中我们可以从名为 Dockerfile 的文件中读取指令并且自动构建镜像.在本文中,将介绍 Dockerfile 的基本语法以及基本知识. Dockerfile 是什么 Docker ...
- sshfs基于ssh挂载远程目录
为了像本地一样访问远程主机上的目录,通常我们会在远程主机上使用nfs来导出目录,并在本地主机上mount这个nfs文件系统.如果是windows系统,则使用cifs或samba的方式来访问. 但可能我 ...
- [转]Xcode编译生成ipa文件(因为两种证书所以打两个ipa)
本文转自:https://blog.csdn.net/aisemi/article/details/78305795 1.生成Archive文档a) 需将左上角红色方框里的设备类型选为ios devi ...
- 线程 线程池 Task
首先声明 这是读了 愉悦的绅士 文章 <菜鸟之旅——学习线程(线程和线程池)> <Task与线程> 的一些个人总结,还是那句话,如有不对,欢迎指正 文章以代码加注释的方法展示. ...