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体系(四)从源 ...
随机推荐
- Django 数据聚合函数 annotate
统计各个分类下的文章数 2 周,3 日前 字数 3818 阅读 546 评论 21 在我们的博客侧边栏有分类列表,显示博客已有的全部文章分类.现在想在分类名后显示该分类下有多少篇文章,该怎么做呢?最优 ...
- [MongoDB]Mongo基本使用
[MongoDB]Mongo基本使用: 汇总: 1. [MongoDB]安装MongoDB2. [MongoDB]Mongo基本使用:3. [MongoDB]MongoDB的优缺点及与关系型数据库 ...
- jetty8 text/plain默认字符编码的坑
今天在测试一个content-type为text/plain的API时发现后端requestBody乱码了,而线上正常. 自己本地使用jetty8版本,插件自带版本,而线上使用jetty9. 最开始没 ...
- Storm WordCount
特别注意,在本地运行的时候应该去掉<scope>provided</scope>,否则会报java.lang.ClassNotFoundException: org.apach ...
- Android主线程的消息系统(Handler\Looper)
前言: 之前的文章写的都是关于Bitmap和内存的优化技术,这一篇文章给大家谈谈Handler. Handler是Android系统中比较重要的一个知识,在Android多线程面试经常会被问到,在实际 ...
- HashMap source code view(1)
前言 HashMap source code view 类注释 Hash table based implementation of the Map interface. This implement ...
- 【EF6学习笔记】(十)处理并发
本篇原文链接:Handling Concurrency Concurrency Conflicts 并发冲突 发生并发冲突很简单,一个用户点开一条数据进行编辑,另外一个用户同时也点开这条数据进行编辑, ...
- Java 容器源码分析之 Set
Set 表示由无重复对象组成的集合,也是集合框架中重要的一种集合类型,直接扩展自 Collection 接口.在一个 Set 中,不能有两个引用指向同一个对象,或两个指向 null 的引用.如果对象 ...
- 【Git】时光机命令—Git命令
cd c: 进入C盘 mkdir learngit 创建名为learngit的文件夹 cd learngit 进入learngit文件夹 pwd 显示当前目录路径 gi ...
- Python网络编程之Socket的简单实现
一.引入 关于Python的网络编程,最基础莫过于socket了. socket,又称“套接字”,网络上的两个程序如果想要实现双向的数据通信,需要建立连接,这个连接的一端就称为一个socket. py ...