揭秘Android界面水平滑动与竖直滑动实现
来源:互联网 发布:db2数据库和oracle 编辑:程序博客网 时间:2024/05/21 18:45
自从iphone诞生以来,利用触屏手势进行界面滑动就成了智能机程序的标配界面效果了,如果你的程序还只能用Button进行操作,那实在太out了。 现在,我来向大家介绍Android界面滑动的基本实现方法,并解释其中的一些原理。
下面先说下我将介绍的知识点:
1.Activity、Window、View之间的关系;
2.利用ViewFlipper、GestureDetector(手势识别)、OnGestureListener,OnTouchListener实现界面水平滑动;
3.多 View时的控件绑定;
4.利用ScrollVeiw实现界面的竖直滑动。
先来说说 Activity、Window、View之间的关系。一些书上在介绍Activity时都说它就是我们看到的界面,这种说法是错的。从Android源代码可以知道,Activity创建时建立了一个PhoneWindow对象,它是我们实现视图的承载模型,它接收View对象后才能显示我们在界面上看到的内容。你可以把setContentView()方法换成
- getWindow().setContentView(LayoutInflater.from(this).inflate(R.layout.main, null));
下面我将介绍界面滑动的代码实现。我不想仅靠贴代码和代码旁的几行注释来和大家分享这些经验,因为这种做法不但无法让人明白程序编写的顺序,也不能说明为何要这些变量和函数,它们的作用,以及需要注意的问题和自己的体会。希望大家喜欢我的分享形式。
这个程序的源代码下载地址在Linux公社的1号FTP服务器里,下载地址:
FTP地址:ftp://www.linuxidc.com
用户名:www.linuxidc.com
密码:www.muu.cc
在 2011年LinuxIDC.com\8月\揭秘Android界面水平滑动与竖直滑动实现源代码
下载方法见这里 http://www.linuxidc.net/thread-1187-1-1.html
现在开始介绍界面水平滑动的实现。
第一步,我们需要得到自己的“窗花纸”。这需要就一个LayoutInflater对象,它能将我们编写的xml格式的layout文件变为界面显示需要的View对象。我们调用LayoutInflater的from()方法,向它传入一个Context对象。
- // 重点,将Context对象传入LayoutInflater.from()里,得到LayoutInflater对象
- LayoutInflater factory = LayoutInflater.from(MainActivity.this);
Inflater的意思是充气,我们应该把它理解为“渲染”。
我在layout文件里放了3个布局文件,分别是firstview.xml、secondview.xml和thirdscrollview.xml,里面只放一个TextView和一个Button就可以了。然后,我们就可以把这3个xml布局文件变为View对象的窗花纸了。我们调用刚才生成的factory对象的inflate()方法来完成,向里面传入布局资源文件的R资源引用,第二个参数设为null。
- // 用inflate(渲染)方法将布局文件变为View对象
- View first = factory.inflate(R.layout.firstview, null);
- View second = factory.inflate(R.layout.secondview, null);
- View third = factory.inflate(R.layout.thirdscrollview, null);
第二步,我们需要一个List之类的对象来帮我存放这些窗花纸,使我们能按顺序调用上一个或下一个View,这就是ViewFlipper对象。先声明一个ViewFlipper类的引用。
- // 定义一个ViewFlipper对象的引用
- private ViewFlipper myViewFlipper;
其次,我们将layout下main.xml里的<TextView>标签换为<ViewFlipper>标签。有人问为何要只留一个<ViewFlipper>,因为不清空的话这些main里的内容会出现在其他View里,相当于你的窗户玻璃上有图案,那么贴上窗花纸后你看到就是窗花纸和玻璃上的图案的结合体。当然具体表现与这些内容和<ViewFlipper>的前后关系有关,你可以自己试试!
- <ViewFlipper
- Android:id="@+id/myViewFlipper"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- ></ViewFlipper>
- // 绑定inflate控件,否则无法使用它
- myViewFlipper = (ViewFlipper) findViewById(R.id.myViewFlipper);
好了,现在管理者有了,我们用myViewFlipper的addView()方法来往里面添加View实例。
- // 用addView方法将生成的View对象加入到ViewFlipper对象中
- myViewFlipper.addView(first);
- myViewFlipper.addView(second);
- myViewFlipper.addView(third);
现在,只要调用myViewFlipper的showPrevious()和showNext()方法就能显示前一个或后一个界面了。问题是,什么时候调用这两个方法?我们要实现的是触屏手势滑动,自然是在有滑动手势的时候,那么现在开始介绍第三步。
第三步,实例化GestureDetector对象,实现OnGestureListener接口,实现onFling()方法。
我们前面说了,要识别触屏手势,因此我们需要实例化一个GestureDetector(手势识别)对象。而这个对象的构造函数需要一个OnGestureListener作为参数,所以我们让MainActivity实现OnGestureListener接口,实现它的虚方法,然后在相关方法里调用showPrevious()和showNext()方法。
首先,定义GestureDetector引用。
- // 定义一个GestureDetector(手势识别类)对象的引用
- private GestureDetector myGestureDetector;
然后,让MainActivity实现OnGestureListener接口,用Eclipse的自动补全功能完成它的虚方法。
- public class MainActivity extends Activity implements OnGestureListener{}
下一步,实例化GestureDetector对象。
- // MainActivity继承了OnGestureListener接口
- myGestureDetector = new GestureDetector(this);
- // 设置识别长按手势,这样才能实现拖动
- myViewFlipper.setLongClickable(true);
到此,基本配置完了,我们现在来做最重要的工作——将showPrevious()和showNext()方法放入OnGestureListener接口合适的方法里。
OnGestureListener接口里有很多方法,这里就不在赘述了,有兴趣的朋友去网上一查就能知道。我们需要处理的滑动是由onFling(MotionEvent e1,MotionEvent e2, float velocityX,float velocityY)方法完成的,它有四个参数,前两个是动作事件,后两个是滑动时的X轴Y轴的速度分量,这里用不到。
所谓水平滑动,就是按下时的横坐标与放开时的横坐标不同。因此我们从代表滑动开始与结束的e1和e2里取出滑动开始与结束时的横坐标比较判定,就能知道是左划还是右划,再调用showPrevious()和showNext()方法就可以了。
- // 实现OnFling方法,就可以利用滑动的起始坐标识别出左右滑动的手势,并处理
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
- float velocityY) {
- // 参数e1是按下事件,e2是放开事件,剩下两个是滑动的速度分量,这里用不到
- // 按下时的横坐标大于放开时的横坐标,从右向左滑动
- if (e1.getX() > e2.getX()) {
- myViewFlipper.showNext();
- }
- // 按下时的横坐标小于放开时的横坐标,从左向右滑动
- else if (e1.getX() < e2.getX()) {
- myViewFlipper.showPrevious();
- }
- return false;
- }
好了,现在主要代码已经完成,运行一下看看吧!
。。。 。。。 。。。(漫长的虚拟机启动,先去泡杯茶)
。。。 。。。(安装apk文件)
。。。(测试程序)
。。。what!不能滑动?别急,要的就是这个效果,如果现在能滑动了那就聊斋了。
第四步,实现OnTouchListener接口和onTouch()方法。
现在我来解释下为何不能滑动,因为当发生触屏事件时,Android系统没有直接调用myGestureDetector和OnGestureListener里的方法,也不可能把MotionEvent类型的参数传递给onFling()函数。因此,按照前面的思路我们下面还需让myGestureDetector中的方法被调用,并获得参数。
为此,我们需要实现OnTouchListener接口和onTouch()方法,因为当一个View上发生触摸事件,android系统会调用的这个方法,并传递给它MotionEvent对象作为参数。
- public class MainActivity extends Activity implements OnGestureListener, OnTouchListener {}
- // MainActivity继承了OnTouchListener接口
- myViewFlipper.setOnTouchListener(this);
现在是伟大工程的最后一步啦,欢呼吧。我们实现onTouch()方法,在里面调用myGestureDetector对象的onTouchEvent()方法,并把MotionEvent类型参数event传递进去,这样我们的手势识别方法就能处理现在的触屏手势啦。
- /*
- * 实现OnTouchListener接口中的onTouch()方法,当View上发生触屏时间时调用,传如一个View和一个运动事件event,我们将
- * 这个event传给OnGestureListener接口的onTouchEvent()方法处理,这样我们的OnFling()就能工作了
- */
- public boolean onTouch(View v, MotionEvent event) {
- return myGestureDetector.onTouchEvent(event);
- }
好了,现在你可以再次运行程序看看效果了,我不会再抖包袱了。
啰啰嗦嗦写了那么多,想必大家对整个功能的实现过程,需要的类、接口与方法,以及它们的功能都有一个了解了吧。
我们还有两个较简单的功能要实现,请继续往下看。
一个Activity对应多个View时的空间注册
当我们只有一个View对应一个Activity时,View里的控件注册自然在这个Activity里完成,现在多个View对应一个Activity,又该如何注册呢?我们别忘了Activity是管家的角色,这些工作自然还是给这个它完成。我在代码里已经给每个View里的Button控件完成了注册,按下Button后可以显示一个Toast,因为太简单这里就不浪费笔墨了,有兴趣的朋友可以下载源代码来研究。
最后是屏幕竖直滑动的实现。
比起水平滑动它实在太简单了,因为android直接提供了一种View来处理,我们直接在layout文件里使用<ScrollView></ScrollView>标签就可以了。需要注意的是,ScrollView下只能包含一个子元素,因此如果你的ScrollView下有多个View控件,请像我一样用个属于ViewGroup的Layout将它们包起来,再将这个Layout放入ScrollView标签中。
- <ScrollView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- >
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <TextView
- android:text="这是第三个View,也是一个ScrollView"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- <Button
- android:id="@+id/thiedButton"
- android:text="第三个View上的提示"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
- </ScrollView>
Ok,所有要介绍的知识点都介绍完了,希望这些知识对大家有用。真正的编程中的界面滑动效果可能比这个复杂,希望大家坚信android是强大的,拿出锲而不舍的精神克服这些困难。
来源:http://www.linuxidc.com/Linux/2011-08/41934p3.htm- 揭秘Android界面水平滑动与竖直滑动实现
- 揭秘Android界面水平滑动与竖直滑动实现
- 揭秘Android界面水平滑动与竖直滑动实现
- 揭秘android界面水平滑动与竖直滑动实现 “第二届 Google 暑期大学生博客分享大赛 - 2011 Android 成长篇 ”
- android 简单实现viewpager竖直滑动
- android实现左右滑动界面
- Android: 水平滑动线性布局的实现
- Android ListView 水平滑动
- DrawerLayout 中listView 滑动不好控制(竖直滑动和水平方向滑动判断)
- android gallery 竖直(上下)滑动
- 让LinearLayout实现水平滑动,左右滑动
- js实现水平滑动和垂直滑动
- 【Android】viewpager+fragment实现界面滑动,顶部导航也滑动
- VerticalSeekBar 竖直滑动条
- 外部解决滑动冲突水平方向和竖直方向滑动冲突实例
- android实现多界面左右滑动切换
- Android实现界面左右滑动切换
- Android 实现手势滑动界面(ViewPager)
- MongoDB与内存
- python 实例
- 提高asp.net 的性能
- Android EditText 显示/隐藏 密码字符串
- BIT寒假练习-2013__1007:Number Converter
- 揭秘Android界面水平滑动与竖直滑动实现
- Idea常用快捷键
- Oracle10g的ORA-3136错误(INBOUND_CONNECT_TIMEOUT参数)
- 对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?
- srand((unsigned)time(NULL))和rand()
- HDU 3177 Crixalis's Equipment
- 【Java反射机制】_反射应用——取得类的结构笔记
- jobdu 6 日期差值
- 文档在线预览(一)-序