Android项目:

1.准备资源图片。图片放到hdip里和mdip里对想过的影响:对于320*480的模拟器,默认去mdip里去找图片资源,拿过来的图片可以直接用,清晰度不变。要是所要找的图片在hdip里,这里的图片默认是高分辨率效果的,而屏幕是中等分辨率的屏幕,那么拿到hdip里的图片后,会对图片进行压缩(大约60%)。显示出来的图片就会变得模糊了。

2.使用自定义的ViewGroup(MyScrollView)实现ViewPager的效果,创建继承ViewGroup的类,实现onLayout方法,这个方法的作用:当继承一个ViewGroup的时候,系统会要求告知ViewGroup中子View的排列方式(指定子View的位置);实现VIewGroup的三个构造方法;

3.自定义的ViewGroup先写到这,再看看主Activity怎么写。首先定义图片资源的引用(id),然后使用for循环将这些图片放到自定义的ViewGroup里面。

for (int i = 0; i < ids.length; i++) {

ImageView image = new ImageView(this);

//image.setBackgroundResource(ids[i]);

image.setImageResource(ids[i]);

msv.addView(image);

}

图片有了之后,再创建自定义的MyScrollView对象msv。并将image对象放到msv中。

这时候就可以setContentView(msv)。

4.在MyScrollView的构造方法中,调用初始化方法init()。实现onLayout方法,使子View从左到右依次排列,并且每一个View都占整个屏幕的大小。效果如下图:

这就需要在onLayout方法中给每一个子View指定一个位置。

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

for (int i = 0; i < getChildCount(); i++) {

View view = getChildAt(i);

view.layout(i*getWidth(), 0, (1+i)*getWidth(), getHeight());

}

}

要想看到右面未显示的View的内容,就要把它滑到屏幕中,这就需要实现Touch事件。要使用GestureDetector实现手势解析,我们创建一个GestureDetector对象detector,并实现它的onGestureListener()监听方法,这时会让我们重写很多方法,这些方法都是在某个特定事件发生的时候执行。

然后我们重写onTouchEvent方法,这时候就可以使用detector解析touch事件而不是switch(event.getAction())方式了。

detector.onTouchEvent(event);

然后实现onGestureListener里的onScroll方法,在这里使用scrollBy方法,穿进去偏移量。

做了以上事情,就可以初步完成滑动的效果了。

现在希望,在滑动后手指抬起时当前图片可以自动回到占满屏幕的位置。

这就需要我们在onTouchEvent方法中对MotionEvent.ACTION_UP进行处理。判断哪张图片应该放到屏幕上去。这个处理可以创建一个方法来实现,moveToDest()。

/**

* 移动到适当的位置上

*/

private void moveToDest() {

int destId = (getScrollX()+getWidth()/2)/getWidth();

if(destId>getChildCount()-1){

destId=getChildCount()-1;

}

moveToDest(destId);

}

/**

* 将指定下标的图片移动至屏幕

* @param destId    distance:图片需要移动的距离

*/

public void moveToDest(int destId) {

int distance = destId*getWidth()-getScrollX();

scrollBy(distance, 0);

}

这样就可以实现ViewPager效果。但是这样还是比较生硬,这时候可以加一个在BaiHeTest中实现的动画效果。

创建MyScroller对象,使用scroller代替scrollBy:

myScroller.startScroll(getScrollX(), getScrollY(), distance, 0,Math.abs(distance));

invalidate();

然后还得重写computeScroll()方法,设置mScroller滚动的位置时,并不会导致View的滚动,通常是用mScroller记录/计算View滚动的位置,再重写View的computeScroll(), 完成实际的滚动。

public void computeScroll() {

if(myScroller.computeScrollOffset()){

int x = myScroller.getCurrX();

scrollTo(x, 0);

invalidate();

}

}

computeScrollOffset()这个方法,如果动画还在执行就返回true,如果动画不执行了,就返回false。不断的移动和刷新。

源自梦想 自定义ViewGroup的整理_2的更多相关文章

  1. 源自梦想 自定义ViewGroup的整理_1

    今天说说自定义控件,稍微偏底层一点的东西.今天的主要任务是自己完全写代码,写一个ViewGroup,实现一个类似ViewPager这样的一个功能. 大家自定义View肯定写过,不过估计写的也不多.等大 ...

  2. Kotlin 第一弹:自定义 ViewGroup 实现流式标签控件

    古人学问无遗力, 少壮工夫老始成.纸上得来终觉浅, 绝知此事要躬行. – 陆游 <冬夜读书示子聿> 上周 Google I/O 大会的召开,宣布了 Kotlin 语言正式成为了官方开发语言 ...

  3. Android 自定义ViewGroup,实现侧方位滑动菜单

    侧方位滑动菜单 1.现在adnroid流行的应用当中很多都是用的侧方位滑动菜单如图:

  4. 简单的例子了解自定义ViewGroup(一)

    在Android中,控件可以分为ViewGroup控件与View控件.自定义View控件,我之前的文章已经说过.这次我们主要说一下自定义ViewGroup控件.ViewGroup是作为父控件可以包含多 ...

  5. Android动画效果之自定义ViewGroup添加布局动画

    前言: 前面几篇文章介绍了补间动画.逐帧动画.属性动画,大部分都是针对View来实现的动画,那么该如何为了一个ViewGroup添加动画呢?今天结合自定义ViewGroup来学习一下布局动画.本文将通 ...

  6. Android自定义控件之自定义ViewGroup实现标签云

    前言: 前面几篇讲了自定义控件绘制原理Android自定义控件之基本原理(一),自定义属性Android自定义控件之自定义属性(二),自定义组合控件Android自定义控件之自定义组合控件(三),常言 ...

  7. Android自定义ViewGroup

    视图分类就两类,View和ViewGroup.ViewGroup是View的子类,ViewGroup可以包含所有的View(包括ViewGroup),View只能自我描绘,不能包含其他View. 然而 ...

  8. [Android Pro] Android开发实践:自定义ViewGroup的onLayout()分析

    reference to : http://www.linuxidc.com/Linux/2014-12/110165.htm 前一篇文章主要讲了自定义View为什么要重载onMeasure()方法( ...

  9. android 手把手教您自定义ViewGroup(一)

    1.概述 在写代码之前,我必须得问几个问题: 1.ViewGroup的职责是啥? ViewGroup相当于一个放置View的容器,并且我们在写布局xml的时候,会告诉容器(凡是以layout为开头的属 ...

随机推荐

  1. getConnection 区别

    1. 这是一个接口 package javax.sql; DataSource.class /** * <p>Attempts to establish a connection with ...

  2. 使用WSAIoctl获取socket扩展函数(如AcceptEx)的指针

    未获取函数指针就调用函数(如直接连接mswsock.lib并直接调用AcceptEx)的消耗是很大的,因为AcceptEx 实际上是存在于Winsock2结构体系之外的.每次应用程序常试在服务提供层上 ...

  3. 关于mysql存储过程的definer的问题

    由于对mysql了解不够透彻,导致对definer问题查了好久才解决问题 记录自己的一些理解! 问题描述: 在数据库写,为一个表写了一个触发器,此触发器调用一个存储过程:由公司写的一个c程序自动往该表 ...

  4. [OAuth2 & OpenID] 1.OAuth2授权

    1 OAuth2解决什么问题的? 举个栗子先.小明在QQ空间积攒了多年的照片,想挑选一些照片来打印出来.然后小明在找到一家提供在线打印并且包邮的网站(我们叫它PP吧(Print Photo缩写

  5. 通过javascript完成分页查询功能

    主要思路: 实现分页查询的关键是设置一个页面的最大数据行数和开始行号,代码如下: 最大行数我们设置为常量,不必纠结于他,所以关键就是如何把起始行号设置为变量,让他随着我们点击[上一页]或[下一页]而改 ...

  6. Angular JS 使用的注意事项

    标签中ng-app,什么情况需要指定名称,什么时候又不需要呢? 1.ng-app="" <div ng-app="" ng-controller='myC ...

  7. Java字面常量与常量池

    Java中的字面常量(区别于final创建的有名常量)通常会保存在常量池中,常量池可以理解为像堆一样的内存区域.但是常量池有一个特性就是,如果常量池中已存在该常量将不会再次为该常量开辟内存 还是看个程 ...

  8. Hello OSGI --- Apache Felix

    Apache Felix Felix是一个OSGi版本4规范的Apache实现. OSGi是一个基于Java的服务平台规范,其目标是被需要长时间运行.动态更新.对运行环境破坏最小化的系统所使用.有许多 ...

  9. ClassRequestHandler or VendorRequestHandler wIndex must be less than NumIFs

    P1_ro:20000EEA ClassRequestHandler ; CODE XREF: USB__HandleSetup+38j P1_ro:20000EEA LDRB R0, [R4,#4] ...

  10. On-board diagnostics -- Standards documents

    http://en.wikipedia.org/wiki/On-board_diagnostics#Standards_documents SAE standards documents on OBD ...