zoukankan      html  css  js  c++  java
  • 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>
  • 相关阅读:
    [Salesforce] 下拉列表
    html 标签 中 的Lang 有什么用
    今天是我的纪念日到公司工作一年了
    [Salesforce] Batchable instance is too big
    [Salesforce] SCRIPT16386: No such interface supported visualforce page 解决办法
    40 Useful JavaScript Libraries
    [Salesforce] IE8 无法下载, can not connect to internet 解决方法
    Timing English Class Speech
    Javescribt Library Javescript 库 总结
    尽量不要
  • 原文地址:https://www.cnblogs.com/kangyaping/p/5522289.html
Copyright © 2011-2022 走看看