Android之滑屏动画和自定义控件
滑屏动画
在Android系统中,通过手势识别切换界面时,通常会在界面切换时加入动画,以提高用户的体验效果,这种动画一般都采用平移动画,下一个界面进入时,上一个界面移除屏幕。

图中标识的均为左上角坐标,进入屏幕的界面坐标是(100%p,0),从屏幕切出界面的坐标是(-100%p,0)。需要注意的是,p指的是屏幕,100%p表示整个屏幕。切入和切出界面都是以整个屏幕为单位计算的。
界面切换的平移动画有四个,分别是下一个界面的进入和切出效果,以及上一个界面进入和切出的效果。接下来分别是这四个动画文件:
一、下一个界面进入、切出动画
在res目录下新建一个anim的文件夹,然后分别建立translate_in.xml(下一个界面进入手机屏幕)、translate_out.xml(下一个界面移出手机屏幕)、translate_previous_in.xml
(上一个界面进入屏幕)、translate_previous_out.xml(上一个界面移出屏幕)
1.translate_in.xml
<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500" //表示动画执行时长为500毫秒
android:fromXDelta="100%p" //x的坐标由100%p移动到0.证明是下一个界面进
android:toXDelta="0"> //入手机屏幕
</translate>
2.translate_out.xml
<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromXDelta="0"
android:toXDelta="-100%p">
</translate>
3.translate_previous_in.xml
<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromXDelta="-100%p"
android:toXDelta="0">
</translate>
4.translate_previous_out.xml
<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromXDelta="0"
android:toXDelta="100%p">
</translate>
二、手势滑动
用户通过手指落在手机屏幕上按住屏幕快速滑动屏幕即可切换屏幕。需要注意的是:在滑动的过程中需要过滤一些无效的动作。例如在y轴方向的滑动,以及小范围的滑动等。

因为很多的界面可能都会应用到滑动的效果,为了避免代码的重复量,我们需要把代码提取出来,使代码更好的运用。下面的这个类是一个抽象类需要使用它的类继承它,并强制重写其中的一些方法。
public abstract class BaseSetUpActivity extends Activity{
private GestureDetector mDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//初始化手势识别器
mDetector = new GestureDetector(this,new GestureDetector.SimpleOnGestureListener(){
/*
* 快速滑动的事件
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2,
float velocityX, float velocityY) {
//判断滑动的姿势对不对
if (Math.abs(e2.getRawY() - e1.getRawY())>100) {
ToastUtils.showToast(getApplicationContext(), "你滑动的姿势不对哦!");
return true;
}
//判断滑动的速度
if (Math.abs(velocityX)<100) {
ToastUtils.showToast(getApplicationContext(), "你滑动的速度太慢啦!");
return true;
}
if (e2.getRawX() - e1.getRawX() > 100) {
showPreviousPage(); //调用跳转到上个页面的方法
return true;
}
if (e1.getRawX() - e2.getRawX() >100) {
showNextPage(); //调用跳转到下一个页面的方法
return true;
}
// TODO Auto-generated method stub
return super.onFling(e1, e2, velocityX, velocityY);
}
});
}
public abstract void showNextPage();
public abstract void showPreviousPage();
/*
* 点击下一步跳转页面
*/
public void nextPage(View view){
showNextPage() ;
}
/*
* 点击上一步跳转到上个页面
*/
public void PreviousPage(View view){
showPreviousPage();
}
/*
* 触摸后的事件回调
* (non-Javadoc)
* @see android.app.Activity#onTouchEvent(android.view.MotionEvent)
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
mDetector.onTouchEvent(event);//委托手势识别器,处理触摸事件
return super.onTouchEvent(event);
}
}
自定义控件
在Android实际的开发中,我们为了更好的让用户使用我们的软件,我们常常需要自定义一些控件来满足我们开发过程中的需要,下面我来举个例子:

这是一个自定义的控件,由两个TextView、一个View和一个ToggleButton组成。这个控件不是Android开发自带的,而是需要用户自己通过代码和布局文件实现这样的一个效果。
1.首先需要我们建立一个布局文件ui_setting_item_view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="5dp"
android:layout_marginTop="10dp"
android:textColor="@color/black"
android:textSize="25sp"
android:text="标题" />
<TextView
android:id="@+id/tv_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_title"
android:layout_marginTop="5dp"
android:layout_marginLeft="5dp"
android:textColor="#88000000"
android:textSize="20sp"
android:text="描述" />
<CheckBox
android:button="@drawable/btn_selector"
android:id="@+id/cb_status"
android:clickable="false"
android:focusable="false"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:layout_marginRight="5dp"
android:layout_marginTop="7dp"
android:layout_centerVertical="true"
android:gravity="center"/>
<View
android:layout_below="@+id/tv_desc"
android:layout_width="fill_parent"
android:layout_height="0.2dip"
android:layout_marginTop="5dip"
android:background="#bb000000"/>
</RelativeLayout>
上述布局文件中,Button按钮使用了一个背景选择器,当按钮处于选中状态时,为按钮指定一个背景图片btn_checked_on.png(开启状态),当按钮未被选中时,为按钮指定一个背景图片btn_checked_off.png(关闭状态)
在res/drawable/btn_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_checked="true"
android:drawable="@drawable/btn_checked_on">
</item>
<item android:state_checked="false"
android:drawable="@drawable/btn_checked_off">
</item>
</selector>
2.自定义控件属性
由于自定义控件中没有设置标题、状态开启时的描述和状态关闭时的描述,因此需要在在res/values/attrs.xml
文件中定义对应的两个属性:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="SettingView">
<attr name="title" format="string" />
<attr name="descs" format="string" />
</declare-styleable>
</resources>
<declare-styleable>........</declare-styleable>代表自定义属性, <attr />代表的内容就是具体的属性,name表示属性的名称,format表示属性的数据类型。
3.实现自定义控件
自定义控件的布局以及所需的属性都已经定义完成,接下来通过代码实现自定义控件,在定义控件时,需要继承RelativeLayout,并创建自定义控件类的构造方法。
SettingItemView.java
// 特殊的相对布局,创建对象的时候就把里面的内容初始化出来
class SettingItemView extends RelativeLayout{
private CheckBox cb_status;
private TextView tv_desc;
private TextView tv_title;
private String[] descs;
public SettingItemView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context); //调用初始化控件的方法
}
public SettingItemView(Context context, AttributeSet attrs) {
super(context, attrs);
String title=attrs.getAttributeValue
("http://schemas.android.com/apk/res/com.itcast.mobilesafe58.activity","title");
String desc = attrs.getAttributeValue
("http://schemas.android.com/apk/res/com.itcast.mobilesafe58.activity", "descs");
init(context); //调用初始化控件的方法
setTitle(title);
descs = desc.split("#"); //以#分割
setDesc(descs, false);
}
public SettingItemView(Context context) {
super(context);
init(context); //调用初始化控件的方法
}
/*
* 初始化控件的方法
*/
private void init(Context context){
//把资源文件转化成view对象,显示在自己身上
View.inflate(context, R.layout.ui_setting_item_view, this);
cb_status = (CheckBox) findViewById(R.id.cb_status);
tv_desc = (TextView) findViewById(R.id.tv_desc);
tv_title = (TextView)findViewById(R.id.tv_title);
this.setBackgroundResource(R.drawable.btn_green_normal);
}
/*
* 设置自定义控件的标题
*/
public void setTitle(String text){
tv_title.setText(text);
}
/*
* 设置自定义控件的内容
*/
public void setDesc(String[] descs,boolean checked){
this.descs = descs;
if (checked) {
if (descs != null) {
tv_desc.setText(descs[0]);
}
}else {
if (descs != null) {
tv_desc.setText(descs[1]);
}
}
}
/*
* 判断组合控件是否被选中
*/
public boolean isChecked(){
return cb_status.isChecked();
}
/*
* 设置组合控件的选中方式
*/
public void setChecked(boolean checked){
cb_status.setChecked(checked);
if (checked) {
tv_desc.setTextColor(Color.GREEN);
if (descs != null) {
tv_desc.setText(descs[0]);
}
}else {
tv_desc.setTextColor(Color.RED);
if (descs != null) {
tv_desc.setText(descs[1]);
}
}
}
}
当UI布局文件中需要引入自己自定义的控件时,首先需要为自定义控件声明命名空间。在Android系统中,声明控件的命名空间格式为: xmlns:itheima(自己随意命名)="http://schemas.android.com/apk/res/包名"
当引用自定义控件时,需要使用控件的全路径。
例如:文件中的加粗部分就是怎么引入自定义的控件
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:itheima="http://schemas.android.com/apk/res/com.itcast.mobilesafe58.activity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical"
tools:context=".SetUp2Activity" >
<TextView
style="@style/TitleStyle"
android:text="2.手机卡绑定" />
<TextView
style="@style/ContentStyle"
android:text="通过绑定SIM卡:"/>
<TextView
style="@style/ContentStyle"
android:text="下次重启手机,发现SIM卡变"/>
<TextView
style="@style/ContentStyle"
android:text="化就会发送报警短信"/>
<com.itcast.mobilesafe58.view.SettingItemView
android:id="@+id/siv_bind"
android:layout_width="match_parent"
android:layout_height="wrap_content"
itheima:descs="SIM卡已绑定#SIM卡没有绑定"
itheima:title="点击绑定SIM卡"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/presence_invisible"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/presence_online"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/presence_invisible"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/presence_invisible"/>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="@drawable/ic_launcher" />
<Button
style="@style/NextPage"/>
<Button
style="@style/PreviousPage" />
</RelativeLayout>
</LinearLayout>
Android之滑屏动画和自定义控件的更多相关文章
- Android中滑屏实现----手把手教你如何实现触摸滑屏以及Scroller类详解
前言: 虽然本文标题的有点标题党的感觉,但无论如何,通过这篇文章的学习以及你自己的实践认知,写个简单的滑屏小 Demo还是just so so的. 友情提示: 在继续往下面读之前,希望您对以下知识点 ...
- Android中滑屏初探 ---- scrollTo 以及 scrollBy方法使用说明
今天给大家介绍下Android中滑屏功能的一个基本实现过程以及原理初探,最后给大家重点讲解View视图中scrollTo 与 scrollBy这两个函数的区别 . 首先 ,我们必须明白在Android ...
- Android中滑屏实现----触摸滑屏以及Scroller类详解 .
转:http://blog.csdn.net/qinjuning/article/details/7419207 知识点一: 关于scrollTo()和scrollBy()以及偏移坐标的设置/取值问 ...
- android之滑屏的实现
★理论知识 ●View在屏幕上显示出来要先经过measure(计算)和layout(布局). ◆当控件的父元素正要放置该控件时调用,父元素会问子控件“你想要用多大的地方?”,然后传入两个参数widt ...
- Scroller的应用--滑屏实现
1.Scroller源代码分析 以下是对Scroller源代码的分析,并附有源代码.例如以下: package android.widget; import android.content.Conte ...
- 利用轮播原理结合hammer.js实现简洁的滑屏功能
最近有个任务,做一个非常小的h5的应用,只有2屏,需要做横向的全屏滑动切换和一些简单的动画效果,之前做这种东西用的是fullpage.js和jquery,性能不是很好,于是就想自己动手弄一个简单的东西 ...
- (转)【移动开发】Android中三种超实用的滑屏方式汇总(ViewPager、ViewFlipper、ViewFlow)
转自: http://smallwoniu.blog.51cto.com/3911954/1308959 现如今主流的Android应用中,都少不了左右滑动滚屏这项功能,(貌似现在好多人使用智能机都习 ...
- Android中三种超实用的滑屏方式汇总(转载)
Android中三种超实用的滑屏方式汇总 现如今主流的Android应用中,都少不了左右滑动滚屏这项功能,(貌似现在好多人使用智能机都习惯性的有事没事的左右滑屏,也不知道在干什么...嘿嘿),由于 ...
- 【Android 界面效果29】研究一下Android滑屏的功能的原理,及scrollTo和scrollBy两个方法
Android中的滑屏功能的原理是很值得我们去研究的,在知道这两个原理之前,有必要先说说View的两个重要方法,它们就是scrollTo 和scrollBy. Android View视图是没有边界的 ...
随机推荐
- Hyperledger fabric Client Node.js Hello World示例程序
简介 Hyperledger fabric Client (HFC)提供了基于Node.js的应用接口来访问Hyperledger区块. 本文介绍了一个使用HFC访问IBM Bluemixr区块服务的 ...
- Javascript编程风格
Douglas Crockford是Javascript权威,Json格式就是他的发明. 去年11月他有一个演讲(Youtube),谈到了好的Javascript编程风格是什么.我非常推荐这个演讲,它 ...
- 地图定位IOS8之后的定位
从ios8开始,苹果进一步加强了对用户隐私的保护. 当app想要访问用户的隐私信息时 系统不再自动弹出一个对话框让用户授权 解决方法: (1)调用ios8.0的API 主动请求用户授权 - (voi ...
- Android布局尺寸思考
一.初步思考 虽然安卓的这个显示适配的方案有点怪,最初也不容易马上理解,不过这个方案确实有其自己的道理,整个思路是清晰的,方案的也是完整的,没有硬伤 安卓采用的[屏幕密度放缩机制].与web前端对应的 ...
- EasyUI datagrid 行编辑
一.HTML: <div class="info"> <div class="info_tt"> <span class=&quo ...
- Unicode中文和特殊字符的编码范围
编程中有时候需要用到匹配中文的正则,一般用 [ \u4e00-\u9fa5]+ 即可搞定.不过这正则对一般的火星文鸟语就不太适用了,甚至全角的标点符号都不包含在内.例如游戏里面的玩家名,普通青年一般都 ...
- OS初识
参考: 操作系统的故事(1-4):
- C# redis使用之ServiceStack
需要注意的是:ServiceStack.Redis 中GetClient()方法,只能拿到Master redis中获取连接,而拿不到slave 的readonly连接.这样 slave起到了冗余备份 ...
- [测试] Firemonkey Android 照相自订分辨率测试
在 Delphi 10 Seattle 提供了照相及相册自订分辨率的功能,请见官方网站教学: http://docwiki.embarcadero.com/RADStudio/Seattle/en/T ...
- android版高仿淘宝客户端源码V2.3
android版高仿淘宝客户端源码V2.3,这个版本我已经更新到2.3了,源码也上传到源码天堂那里了,大家可以看一下吧,该应用实现了我们常用的购物功能了,也就是在手机上进行网购的流程的,如查看产品(浏 ...