一、MP3播放器

查看Android API文档可以看到MediaPlayer状态转换图:

练习:

package com.shellway.mp3player;import java.io.File;import java.io.IOException;import android.support.v7.app.ActionBarActivity;import android.telephony.PhoneStateListener;import android.telephony.TelephonyManager;import android.content.Context;import android.media.MediaPlayer;import android.media.MediaPlayer.OnPreparedListener;import android.os.Bundle;import android.os.Environment;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;public class MainActivity extends ActionBarActivity {    //媒体播放器    private MediaPlayer mp;    private EditText songName;    //之前是否暂停过    private boolean pause;    private File file;    private TelephonyManager tm;    //暂停保存点    private int position = 0;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        songName = (EditText) findViewById(R.id.song_name);                tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);        tm.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_CALL_STATE);    }        private class MyPhoneStateListener extends PhoneStateListener{        @Override        public void onCallStateChanged(int state, String incomingNumber) {            // TODO Auto-generated method stub            super.onCallStateChanged(state, incomingNumber);            switch (state) {            case TelephonyManager.CALL_STATE_IDLE://闲置状态                if (position > 0 && mp != null) {                    //跳转到指定的保存点位置                    mp.seekTo(position);                    mp.start();                }                break;            case TelephonyManager.CALL_STATE_OFFHOOK://接听状态                if(mp != null){                    if(mp.isPlaying()){                        position = mp.getCurrentPosition();                        mp.pause();                    }                }                break;            case TelephonyManager.CALL_STATE_RINGING://响铃状态                                 if (mp.isPlaying()) {                     position = mp.getCurrentPosition();                     mp.pause();                    }                break;                            default:                break;            }        }    }//这里是利用Activity生命周期的方法监听来电时暂停播放//  @Override//  protected void onResume() {//      // TODO Auto-generated method stub//      super.onResume();//      if(position > 0){//          //跳转到指定的位置//          mp.seekTo(position);//          mp.start();//      }//  }//  //  @Override//  protected void onPause() {//      // TODO Auto-generated method stub//      super.onPause();//      position = mp.getCurrentPosition();//      mp.pause();//  }        public void play(View view){        String name = songName.getText().toString();                file = new File(Environment.getExternalStorageDirectory(),name+".mp3");                    if (!file.exists()) {                Toast.makeText(this, "文件不存在", Toast.LENGTH_SHORT).show();                mp=null;            }else{                if (mp!=null) {                    if (mp.isPlaying()) {                        Toast.makeText(this, "歌曲已经在播放中", Toast.LENGTH_SHORT).show();                    }else{                        play();                    }                }else{                    play();                }         }    }        public void play(){        try {            mp = new MediaPlayer();            //置为初始状态            mp.reset();            //指定要播放的文件            mp.setDataSource(file.getAbsolutePath());            //准备(缓冲)            mp.prepare();            //设置缓冲完成监听            mp.setOnPreparedListener(new MyOnPreparedListener());        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }        private class MyOnPreparedListener implements OnPreparedListener{        @Override        public void onPrepared(MediaPlayer mp) {            // TODO Auto-generated method stub            //播放            mp.start();        }    }        public void pause(View view){        if (mp.isPlaying()) {            //暂停播放            mp.pause();            Button bt = (Button) view;            bt.setText("继续");            pause = true;        }else{            if (pause) {                mp.start();                Button bt = (Button) view;                bt.setText("停止");            }        }    }        public void stop(View view){        if (mp!=null) {            //停止播放            mp.stop();        }    }        public void reset(View view){        if (mp!=null) {            mp.start();        }    }        @Override    protected void onDestroy() {        // TODO Auto-generated method stub        super.onDestroy();        if (mp != null) {            mp.release();            mp = null;        }    }}
MainActivity.java
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    >    <TextView        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="请输入歌曲名" />    <EditText         android:id="@+id/song_name"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="Complicated"        />  <LinearLayout         android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:orientation="horizontal"        >    <Button         android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="1"        android:onClick="play"        android:text="播放"        />    <Button         android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="1"        android:onClick="pause"        android:text="暂停"        />    <Button         android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="1"        android:onClick="stop"        android:text="停止"        />    <Button         android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="1"        android:onClick="reset"        android:text="重播"        />  </LinearLayout></LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.shellway.mp3player"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="21" />    <!-- 监听来电状态需要读取电话状态权限 -->    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>
AndroidManifest.xml

运行结果截图:

二:MP4播放器

MP4的播放同MP3的差不多,主要是在显示视频的控件上的区别

package com.shellway.mp4player;import java.io.File;import java.io.IOException;import android.support.v7.app.ActionBarActivity;import android.media.MediaPlayer;import android.media.MediaPlayer.OnCompletionListener;import android.media.MediaPlayer.OnPreparedListener;import android.os.Bundle;import android.os.Environment;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.widget.EditText;import android.widget.Toast;public class MainActivity extends ActionBarActivity {    private MediaPlayer mp;    private EditText et_name;    private File file;    private boolean pause ;    private SurfaceView surfaceview;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        et_name = (EditText) findViewById(R.id.et_name);        surfaceview = (SurfaceView) findViewById(R.id.surfaceview);        SurfaceHolder holder = surfaceview.getHolder();        //给SurfaceView设置屏幕分辨率        holder.setFixedSize(176, 144);        //给SurfaceView设置保持高亮        holder.setKeepScreenOn(true);        //不让surfaceview维持自己的缓冲,让它得到的数据直接输出        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);    }        public void play(View view){        String name = et_name.getText().toString();        file = new File(Environment.getExternalStorageDirectory(),name+".mp4");        Log.i("i", file.getAbsolutePath());        if (!file.exists()) {            Toast.makeText(this, "播放文件不存在", Toast.LENGTH_SHORT).show();        }else{            //开始播放            play();        }    }        public void play(){        try {            mp = new MediaPlayer();            mp.reset();            mp.setDataSource(file.getAbsolutePath());            //设置显示画面            mp.setDisplay(surfaceview.getHolder());             mp.prepare();            mp.setOnPreparedListener(new MyOnPreparedListener());                    } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }        private class MyOnPreparedListener implements OnPreparedListener{        @Override        public void onPrepared(MediaPlayer mp) {            // TODO Auto-generated method stub            mp.start();        }            }        public void pause(View view){        if (mp != null) {            if (mp.isPlaying()) {                mp.pause();                pause = true;            }else{                mp.start();                pause = false;            }        }    }        public void stop(View view){        if (mp != null) {            mp.stop();        }    }        public void reset(View view){        if (mp != null) {            mp.reset();            play();        }    }        @Override    protected void onDestroy() {        // TODO Auto-generated method stub        super.onDestroy();        if (mp != null) {            mp.release();            mp = null;        }    }}
MainActivity.java
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <TextView        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="请输入要播放的视频名称:" />    <EditText         android:id="@+id/et_name"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="test"        />        <LinearLayout         android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:orientation="horizontal"        >        <ImageView             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginRight="10dp"            android:onClick="play"            android:src="@drawable/play"            />        <ImageView             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginRight="10dp"            android:onClick="pause"            android:src="@drawable/pause"            />        <ImageView             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginRight="10dp"            android:onClick="stop"            android:src="@drawable/stop"            />        <ImageView             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginRight="10dp"            android:onClick="reset"            android:src="@drawable/reset"            />            </LinearLayout>        <SurfaceView            android:id="@+id/surfaceview"            android:layout_width="fill_parent"            android:layout_height="240dp"        ></SurfaceView></LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.shellway.mp4player"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="21" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>
AndroidManifest.xml

运行结果截图:

三、手机拍照

照相机的一些属性:
预览帧数:preview-frame-rate=30
图片质量:jpeg-thumbnail-quality=90
图片尺寸:preview-size-values=1280x720,800x480,768x432,720x480,640x480,480x320,176x144
SurfaceView只有当activity显示到了前台,该控件才会被创建。
只有当surfaceView被创建了,才把相机所捕获到的数据输出给它。
如果activity回到回台。surfaceview又会被销毁
注意:在拍照的时候相机是被占用的。拍照之后需要重新预览。

练习:

package com.shellway.takephoto;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import android.support.v7.app.ActionBarActivity;import android.hardware.Camera;import android.hardware.Camera.Parameters;import android.hardware.Camera.PictureCallback;import android.os.Bundle;import android.os.Environment;import android.util.Log;import android.view.SurfaceHolder;import android.view.SurfaceHolder.Callback;import android.view.SurfaceView;import android.view.View;import android.view.Window;import android.view.WindowManager;public class MainActivity extends ActionBarActivity {    private SurfaceView surfaceview;    private Camera camera;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //请求窗体特征:设置不显示标题,注意要在setContentView之前设置        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_main);        //设置全屏幕显示        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                             WindowManager.LayoutParams.FLAG_FULLSCREEN);        surfaceview = (SurfaceView) findViewById(R.id.surfaceview);        SurfaceHolder holder = surfaceview.getHolder();        //设置屏幕分辨率        holder.setFixedSize(176, 144);        //设置屏幕保持高亮        holder.setKeepScreenOn(true);        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);        holder.addCallback(new MySurfaceCallback());    }        private class MySurfaceCallback implements Callback{        @Override        public void surfaceCreated(SurfaceHolder holder) {            // TODO Auto-generated method stub            try {                //打开相机                camera = Camera.open();                Parameters params = camera.getParameters();                //设置照片的尺寸                params.setPictureSize(800, 480);                //设置预览帧数,为了兼容2.3以前版本还是加上好                params.setPreviewFrameRate(5);                //设置照片质量                params.setJpegQuality(80);                camera.setParameters(params);                //设置预览显示                camera.setPreviewDisplay(surfaceview.getHolder());                //设置开始预览                camera.startPreview();            } catch (Exception e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }        @Override        public void surfaceChanged(SurfaceHolder holder, int format, int width,                int height) {            // TODO Auto-generated method stub        }        @Override        public void surfaceDestroyed(SurfaceHolder holder) {            // TODO Auto-generated method stub            //释放相机资源            if (camera != null) {                camera.release();                camera = null;            }        }            }        public void takephoto(View view){        //参数:shutter 开门被按下, raw 相机所捕获的原始数据, jpeg 相机处理的数据        camera.takePicture(null, null, new MyPictureCallback());    }        private class MyPictureCallback implements PictureCallback{        @Override        public void onPictureTaken(byte[] data, Camera camera) {            // TODO Auto-generated method stub            try {                File file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg");                FileOutputStream fos = new FileOutputStream(file);                fos.write(data);                //记得拍照存完数据到存储卡后还要给相机设置继续预览                camera.startPreview();            } catch (Exception e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }        public void autofocus(View view){        //这里是由相机硬件为我们自动对焦    }        @Override    protected void onDestroy() {        // TODO Auto-generated method stub        super.onDestroy();        if (camera != null) {            camera.release();            camera = null;        }    }}
MainActivity.java
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.shellway.takephoto.MainActivity" >    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/hello_world" />        <SurfaceView         android:id="@+id/surfaceview"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        />    <LinearLayout        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:layout_alignParentRight="true"        >        <Button             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginRight="10dp"            android:onClick="autofocus"            android:text="对焦"            ></Button>        <Button             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginRight="10dp"            android:text="拍照"            android:onClick="takephoto"            ></Button>            </LinearLayout></RelativeLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.shellway.takephoto"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="21" />    <!-- 获取相机的拍照权限 -->    <uses-permission android:name="android.permission.CAMERA"/>    <!-- 获取外存储设备的写权限 -->    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <!-- 设置横屏显示属性 screenOrientation-->        <activity            android:name=".MainActivity"            android:label="@string/app_name" android:screenOrientation="landscape">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>
AndroidManifest.xml

运行结果截图:下图是在真实手机上运行的截图

四、视频刻录

查看Android API文档可以看到MediaRecoder状态转换图,用它来实现视频的刻录:

package com.shellway.videorecoder;import java.io.File;import java.io.IOException;import android.support.v7.app.ActionBarActivity;import android.media.MediaRecorder;import android.os.Bundle;import android.os.Environment;import android.view.Menu;import android.view.MenuItem;import android.view.Surface;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.widget.Button;public class MainActivity extends ActionBarActivity {    //声明一个媒体刻录机    private MediaRecorder mr;    //因为是动态视图,可以用SurfaceView来展示    private SurfaceView surfaceview;    private Button bt_start;    private Button bt_stop;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                surfaceview = (SurfaceView) findViewById(R.id.surfaceview);        SurfaceHolder holder = surfaceview.getHolder();        //设置屏幕分辨率        holder.setFixedSize(176, 144);        //设置屏幕保持高亮        holder.setKeepScreenOn(true);        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);        bt_start = (Button) findViewById(R.id.bt_start);        bt_stop = (Button) findViewById(R.id.bt_stop);    }        public void start(View view){        try {            //创建一个媒体刻录机            mr = new MediaRecorder();            //在给刻录机设置属性前首先要重置一下            mr.reset();            //设置音频、视频来源            mr.setAudioSource(MediaRecorder.AudioSource.MIC);            mr.setVideoSource(MediaRecorder.VideoSource.CAMERA);            //设置音频、视频输出格式            mr.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);            //设置音频、视频的编码            mr.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);            mr.setVideoEncoder(MediaRecorder.VideoEncoder.H264);            //创建一个输出音频、视频的文件            File file = new File(Environment.getExternalStorageDirectory(),                                        System.currentTimeMillis()+".3gp");            mr.setOutputFile(file.getAbsolutePath());            //设置预览            mr.setPreviewDisplay(surfaceview.getHolder().getSurface());            //准备刻录            mr.prepare();            //开始刻录            mr.start();            //开始刻录后,按钮可见的转变            bt_start.setEnabled(false);            bt_stop.setEnabled(true);        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }        public void stop(View view){        //停止刻录        mr.stop();        //停止刻录后,按钮可见的转变        bt_start.setEnabled(true);        bt_stop.setEnabled(false);        //释放资源        mr.release();        mr = null;    }}
MainActivity.java
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.shellway.videorecoder.MainActivity" >    <SurfaceView         android:id="@+id/surfaceview"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        />    <LinearLayout        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:layout_alignParentRight="true"        >        <Button             android:id="@+id/bt_start"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginRight="10dp"            android:onClick="start"            android:text="开始"            ></Button>        <Button             android:id="@+id/bt_stop"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginRight="10dp"            android:onClick="stop"            android:enabled="false"            android:text="停止"            ></Button>            </LinearLayout></RelativeLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.shellway.videorecoder"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="21" />    <!-- 使用相机的权限 -->    <uses-permission android:name="android.permission.CAMERA"/>    <!-- 媒体刻录机的权限 -->    <uses-permission android:name="android.permission.RECORD_AUDIO"/>    <!-- 外存储写的权限 -->    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>        <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <!-- 设置一开始就横屏显示 -->        <activity            android:name=".MainActivity"            android:label="@string/app_name" android:screenOrientation="landscape">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>
AndroidManifest.xml

运行结果截图:

五:手势识别
首先,使用系统给出的应用Gestures Builder画出手势库,然后把手势库导出到桌面,最后在工程res目录下
新建一个raw文件(这个文件表示原文件,编译的时候不会对它做任何修改),我这里画的一个打勾和“Z”字母,
打勾表示拨打电话号码为5556的电话,“Z”字母表示退出本应用程序。

练习:

package com.shellway.gestures;import java.util.ArrayList;import android.support.v7.app.ActionBarActivity;import android.R.anim;import android.content.Intent;import android.gesture.Gesture;import android.gesture.GestureLibraries;import android.gesture.GestureLibrary;import android.gesture.GestureOverlayView;import android.gesture.GestureOverlayView.OnGesturePerformedListener;import android.gesture.Prediction;import android.net.Uri;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.widget.Toast;public class MainActivity extends ActionBarActivity {    private GestureOverlayView gov;    private GestureLibrary library;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                gov = (GestureOverlayView) findViewById(R.id.gov_id);        //加载监听        gov.addOnGesturePerformedListener(new MyOnGesturePerformedListener());        //加载手势库        library = GestureLibraries.fromRawResource(this, R.raw.gestures);        library.load();    }        private class MyOnGesturePerformedListener implements OnGesturePerformedListener{        @Override        public void onGesturePerformed(GestureOverlayView overlay,                Gesture gesture) {            // 识别手势            ArrayList<Prediction> predictions = library.recognize(gesture);            if (predictions.isEmpty()) {                Toast.makeText(getApplicationContext(),"手势不存在", Toast.LENGTH_SHORT).show();            }else{                //拿到手势库里面的第一个,即最匹配的手势                Prediction prediction = predictions.get(0);                //给匹配度打分,分是从0-10                double score  = prediction.score;                if (score>=6) {                    //手势的名字                    String name = prediction.name;                    if (name.equals("call")) {                        Intent intent  = new Intent();                        intent.setAction(Intent.ACTION_CALL);                        intent.setData(Uri.parse("tel:"+5556));                        startActivity(intent);                    }else if(name.equals("exit")){                        //利用杀死进程的方法退出程序                        android.os.Process.killProcess(android.os.Process.myPid());                    }                }else{                    Toast.makeText(getApplicationContext(),"匹配度太低", Toast.LENGTH_SHORT).show();                }            }        }    }}
MainActivity.java
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"       >    <android.gesture.GestureOverlayView                   android:id="@+id/gov_id"                  android:layout_width="fill_parent"                  android:layout_height="0dp"                  android:layout_weight="1"        ></android.gesture.GestureOverlayView>        <LinearLayout           android:layout_width="fill_parent"          android:layout_height="wrap_content"          android:orientation="horizontal"        >          <Button               android:layout_width="0dp"              android:layout_height="wrap_content"              android:layout_weight="1"              android:text="确定"              />          <Button               android:layout_width="0dp"              android:layout_height="wrap_content"              android:layout_weight="1"              android:text="取消"              />    </LinearLayout></LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.shellway.gestures"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="21" />    <!-- 拨打电话权限 -->    <uses-permission android:name="android.permission.CALL_PHONE"/>    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>
AndroidManifest.xml

运行结果截图:

可以支持多笔手势:需要做如下改动

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"       >    <!-- 要支持多笔手势就要加上gestureStrokeType这个属性,因为默认是单笔手势 -->    <android.gesture.GestureOverlayView                   android:id="@+id/gov_id"                  android:layout_width="fill_parent"                  android:layout_height="0dp"                  android:layout_weight="1"                  android:gestureStrokeType="multiple"        ></android.gesture.GestureOverlayView>        <LinearLayout           android:layout_width="fill_parent"          android:layout_height="wrap_content"          android:orientation="horizontal"        >          <Button               android:layout_width="0dp"              android:layout_height="wrap_content"              android:layout_weight="1"              android:onClick="ok"              android:text="确定"              />          <Button               android:layout_width="0dp"              android:layout_height="wrap_content"              android:layout_weight="1"              android:onClick="cancel"              android:text="取消"              />    </LinearLayout></LinearLayout>
activity_main.xml
package com.shellway.gestures;import java.util.ArrayList;import android.support.v7.app.ActionBarActivity;import android.R.anim;import android.content.Intent;import android.gesture.Gesture;import android.gesture.GestureLibraries;import android.gesture.GestureLibrary;import android.gesture.GestureOverlayView;import android.gesture.GestureOverlayView.OnGestureListener;import android.gesture.GestureOverlayView.OnGesturePerformedListener;import android.gesture.Prediction;import android.net.Uri;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.MotionEvent;import android.view.View;import android.widget.Toast;public class MainActivity extends ActionBarActivity {    private GestureOverlayView gov;    private GestureLibrary library;    private Gesture gesture;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                gov = (GestureOverlayView) findViewById(R.id.gov_id);        //加载监听    //  gov.addOnGesturePerformedListener(new MyOnGesturePerformedListener());        //这个是支持多笔手势的监听        gov.addOnGestureListener(new MyOnGestureListener());        //加载手势库        library = GestureLibraries.fromRawResource(this, R.raw.gestures);        library.load();    }        private class MyOnGestureListener implements OnGestureListener{        @Override        public void onGestureStarted(GestureOverlayView overlay,                MotionEvent event) {            // TODO Auto-generated method stub            Log.i("i", " onGestureStarted ");        }        @Override        public void onGesture(GestureOverlayView overlay, MotionEvent event) {            // TODO Auto-generated method stub            Log.i("i", " onGesture ");        }        @Override        public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) {            // TODO Auto-generated method stub            Log.i("i", " onGestureEnded ");            //拿到当前的手势            gesture = overlay.getGesture();        }        @Override        public void onGestureCancelled(GestureOverlayView overlay,                MotionEvent event) {            // TODO Auto-generated method stub            Log.i("i", " onGestureCancelled ");        }            }        private class MyOnGesturePerformedListener implements OnGesturePerformedListener{        @Override        public void onGesturePerformed(GestureOverlayView overlay,                Gesture gesture) {            //overlay:表示当前的手势,gesture表示最后的手势            recognize(gesture);        }    }        public void ok(View view){        recognize(gesture);        gov.clear(true);    }        public void cancel(View view){        gov.clear(true);    }        // 识别手势    private void recognize(Gesture gesture) {        ArrayList<Prediction> predictions = library.recognize(gesture);        if (predictions.isEmpty()) {            Toast.makeText(getApplicationContext(),"手势不存在", Toast.LENGTH_SHORT).show();        }else{            //拿到手势库里面的第一个,即最匹配的手势            Prediction prediction = predictions.get(0);            //给匹配度打分,分是从0-10            double score  = prediction.score;            if (score>=6) {                //手势的名字                String name = prediction.name;                if (name.equals("call")) {                    Intent intent  = new Intent();                    intent.setAction(Intent.ACTION_CALL);                    intent.setData(Uri.parse("tel:"+5556));                    startActivity(intent);                }else if(name.equals("exit")){                    //利用杀死进程的方法退出程序                    android.os.Process.killProcess(android.os.Process.myPid());                }            }else{                Toast.makeText(getApplicationContext(),"匹配度太低", Toast.LENGTH_SHORT).show();            }        }    }}
MainActivity.java

多笔手势监听方法的测试:

八、通知:Notification
之前我们学了提示用户的两种方式:Toast 、AlertDialog
现在我们来看看通知Noitification,它主要由以下六部分组成:
图标、ticker提示信息、时间、标题、内容、事件

练习:

package com.shellway.notification;import android.support.v7.app.ActionBarActivity;import android.R.anim;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.RemoteViews;public class MainActivity extends ActionBarActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }        public void notification(View view){        //得到通知管理器        NotificationManager notificationManager =                      (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);        //构建通知        Notification notification = new Notification(android.R.drawable.stat_notify_chat,                                               "这是一个提示信息", System.currentTimeMillis());        //通知的点击事件        Intent intent = new Intent(this,MainActivity.class);        //第二个参数为请求码,可随意指定。第四个参数为标志码,我们这里填0就可以了        PendingIntent pendingIntent = PendingIntent.getActivity(this, 100, intent, 0);        notification.setLatestEventInfo(this, "通知标题", "通知内容", pendingIntent);        //点击后消失        notification.flags = Notification.FLAG_AUTO_CANCEL;        //发送通知        notificationManager.notify(100, notification);    }        public void customnotification(View view){        //得到通知管理器        NotificationManager notificationManager =                     (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);        //构建通知        Notification notification = new Notification();        notification.icon = android.R.drawable.stat_notify_call_mute;//图标        notification.tickerText  = "新的信息来啦";//通知提示信息        //自定义通知内容布局        RemoteViews remoteviews = new RemoteViews(getPackageName(), R.layout.contentview);        notification.contentView = remoteviews;        //定义通知内容        Intent intent = new Intent(this,MainActivity.class);        PendingIntent paIntent = PendingIntent.getActivity(this, 100, intent, 0);        notification.contentIntent = paIntent;        //点击后消失        notification.flags = Notification.FLAG_AUTO_CANCEL;        //发送通知        notificationManager.notify(100, notification);            }}
MainActivity.java
package com.shellway.notification;import android.app.Activity;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;public class OtherActivity extends ActionBarActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        // TODO Auto-generated method stub        super.onCreate(savedInstanceState);        setContentView(R.layout.contentview);    }}
OtherActivity.java
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    >    <Button         android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:onClick="notification"        android:text="普通通知"        />        <Button         android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:onClick="customnotification"        android:text="自定义通知"        /></LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="horizontal" >        <ImageView         android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:src="@drawable/ic_launcher"        />    <LinearLayout        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:orientation="vertical"        >        <TextView             android:layout_width="fill_parent"            android:layout_height="wrap_content"            android:text="新收到10条短信"            />        <ProgressBar            android:layout_width="fill_parent"            android:layout_height="wrap_content"            style="@android:style/Widget.ProgressBar.Horizontal"            ></ProgressBar>    </LinearLayout>      </LinearLayout>
contentview.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.shellway.notification"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="21" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <activity android:name=".OtherActivity"></activity>    </application></manifest>
AndroidManifest.xml

运行结果截图:

九、动画(Animation)

我们可以查官方文档中API Guies可以看到

根据它,我们可以进行以上提到的两种动画的开发工作
练习1:tween动画,首先在res目录下新建文件夹anim,然后在其下面建立动画xml文件

package com.example.tweenanimation;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.animation.Animation;import android.view.animation.AnimationUtils;import android.widget.ImageView;public class MainActivity extends ActionBarActivity {    private ImageView iv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        iv = (ImageView) findViewById(R.id.iv);    }     public void start(View view){         //加载动画   //      Animation anim = AnimationUtils.loadAnimation(this, R.anim.alpha);//图片透明度   //      Animation anim = AnimationUtils.loadAnimation(this, R.anim.scale);//图片缩放   //      Animation anim = AnimationUtils.loadAnimation(this, R.anim.translate);//图片移动   //      Animation anim = AnimationUtils.loadAnimation(this, R.anim.rotate);//图片旋转         Animation anim = AnimationUtils.loadAnimation(this, R.anim.set);//以上综合         //执行动画         iv.startAnimation(anim);     }}
MainActivity.java
<?xml version="1.0" encoding="utf-8"?><!-- FillAfter,动画的最后一帧是否保持在View上面,FillEnabled是否启用Fill保持  --><alpha xmlns:android="http://schemas.android.com/apk/res/android"    android:fromAlpha="1"    android:toAlpha="0"    android:duration="2000"    android:fillAfter="true"    >    </alpha>
alpha.xml
<?xml version="1.0" encoding="utf-8"?><!-- pivotX 若填5表示旋转5个像素, 若填5%表示相对自身旋转5%,若填5%p表示相对父元素旋转--><rotate xmlns:android="http://schemas.android.com/apk/res/android"    android:fromDegrees="0"    android:toDegrees="90"    android:pivotX="50%"    android:pivotY="50%"    android:duration="2000"    >    </rotate>
rotate.xml
<?xml version="1.0" encoding="utf-8"?><!-- FillAfter,动画的最后一帧是否保持在View上面,FillEnabled是否启用Fill保持 --><scale xmlns:android="http://schemas.android.com/apk/res/android"    android:fromXScale="1"    android:toXScale="2"    android:fromYScale="1"    android:toYScale="0.5"    android:duration="2000"    android:fillAfter="true"    ></scale>
scale.xml
<?xml version="1.0" encoding="utf-8"?><translate xmlns:android="http://schemas.android.com/apk/res/android"    android:fromXDelta="0"    android:toXDelta="100"    android:fromYDelta="0"    android:toYDelta="100"    android:fillAfter="true"    android:duration="2000"    >    </translate>
translate.xml
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android">    <alpha     android:fromAlpha="1"    android:toAlpha="0"    android:duration="2000"    android:fillAfter="true"    />    <scale     android:fromXScale="1"    android:toXScale="2"    android:fromYScale="1"    android:toYScale="0.5"    android:duration="2000"    android:fillAfter="true"    />    <translate     android:fromXDelta="0"    android:toXDelta="100"    android:fromYDelta="0"    android:toYDelta="100"    android:fillAfter="true"    android:duration="2000"    />    <rotate    android:fromDegrees="0"    android:toDegrees="90"    android:pivotX="50%"    android:pivotY="50%"    android:duration="2000"    /></set>
set.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"     >         <ImageView         android:id="@+id/iv"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:src="@drawable/ic_launcher"        />    <Button         android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:onClick="start"        android:text="开始"        /></LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.tweenanimation"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="21" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>
AndroidManifest.xml

练习2:frame动画,首先在res目录下新建drawable文件夹,然后在其下加入要用到的图片资源和资源xml文件

package comshellway.frameanimation;import android.support.v7.app.ActionBarActivity;import android.graphics.drawable.AnimationDrawable;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.ImageView;public class MainActivity extends ActionBarActivity {    private AnimationDrawable ad;    private ImageView iv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                iv = (ImageView) findViewById(R.id.iv);    }        //开始动画    public void start(View view){        //一般frame动画用来作背景用,在这里是得到背景动画        ad = (AnimationDrawable) iv.getBackground();        ad.start();    }        //停止动画    public void stop(View view){        ad.stop();    }}
MainActivity.java
<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true" >     <item        android:drawable="@drawable/a1"        android:duration="200" />     <item        android:drawable="@drawable/a2"        android:duration="200" />     <item        android:drawable="@drawable/a3"        android:duration="200" />     <item        android:drawable="@drawable/a4"        android:duration="200" />     <item        android:drawable="@drawable/a5"        android:duration="200" />     <item        android:drawable="@drawable/a6"        android:duration="200" />     <item        android:drawable="@drawable/a7"        android:duration="200" />     <item        android:drawable="@drawable/a8"        android:duration="200" />     <item        android:drawable="@drawable/a9"        android:duration="200" />     <item        android:drawable="@drawable/a10"        android:duration="200" />     <item        android:drawable="@drawable/a11"        android:duration="200" />     <item        android:drawable="@drawable/a12"        android:duration="200" />     <item        android:drawable="@drawable/a13"        android:duration="200" />     <item        android:drawable="@drawable/a14"        android:duration="200" />     <item        android:drawable="@drawable/a15"        android:duration="200" /></animation-list>
res/drawable下的frame.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    >  <ImageView       android:id="@+id/iv"      android:layout_width="fill_parent"      android:layout_height="wrap_content"      android:background="@drawable/frame"      />    <Button         android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:onClick="start"        android:text="开始"        />    <Button         android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:onClick="stop"        android:text="停止"        /></LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="comshellway.frameanimation"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="21" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>
AndroidManifest.xml

运行结果截图:

十、传感器

练习:

package com.shellway.sensor;import android.support.v7.app.ActionBarActivity;import android.content.Context;import android.hardware.Sensor;import android.hardware.SensorEvent;import android.hardware.SensorEventListener;import android.hardware.SensorManager;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.animation.Animation;import android.view.animation.RotateAnimation;import android.widget.ImageView;public class MainActivity extends ActionBarActivity {    private MySensorEventListener listener;    private SensorManager sensorManager;    private Sensor sensor;    private ImageView iv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                iv = (ImageView) findViewById(R.id.iv);        //获得传感器管理器        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);        //获得方向传感器        sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);        listener = new MySensorEventListener();    }        @Override    protected void onResume() {        // TODO Auto-generated method stub        super.onResume();        //注册sensor监听        sensorManager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_GAME);    }        private class MySensorEventListener implements SensorEventListener{        private float predegree = 0;        @Override        public void onSensorChanged(SensorEvent event) {            // TODO Auto-generated method stub            float x = event.values[SensorManager.DATA_X];            //创建一个旋转的动画,0.5f表示自身的正中间,Animation.RELATIVE_TO_SELF表示相对自身旋转            RotateAnimation rotate = new RotateAnimation(-predegree, x,                                       Animation.RELATIVE_TO_SELF, 0.5f,                                      Animation.RELATIVE_TO_SELF, 0.5f);            rotate.setDuration(50);            iv.startAnimation(rotate);            predegree = x;        }          //精确度的改变,这里暂时不用管        public void onAccuracyChanged(Sensor sensor, int accuracy) {            // TODO Auto-generated method stub                    }    }        @Override    protected void onPause() {        // TODO Auto-generated method stub        super.onPause();        //当应用在前台不活动的时候取消监听        sensorManager.unregisterListener(listener);    }}
MainActivity.java
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.shellway.sensor.MainActivity" >    <ImageView         android:id="@+id/iv"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:src="@drawable/zn"        /></RelativeLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.shellway.sensor"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="21" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>
AndroidManifest.xml

运行结果截图:

十一:图片的移动和缩放

分析:

练习:

package com.shellway.dragscale;import android.support.v7.app.ActionBarActivity;import android.graphics.Matrix;import android.graphics.PointF;import android.os.Bundle;import android.util.FloatMath;import android.view.Menu;import android.view.MenuItem;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;import android.widget.ImageView;public class MainActivity extends ActionBarActivity {    private ImageView iv;    private MyOnTouchListener listener;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        listener = new MyOnTouchListener();                iv = (ImageView) findViewById(R.id.iv);        iv.setOnTouchListener(listener);    }        private class MyOnTouchListener implements OnTouchListener{        private PointF startPiont = new PointF();//起始点        private Matrix mcurrentMatrix = new Matrix();//图片当前的matrix值        private Matrix mMatrix = new Matrix();//来一个临时的matrix                private int type = 0;        private final static int DRAG = 1;        private final static int SCALE = 2;        private PointF mstartP;//中心点        private float mdistance;//两点间的距离        @Override        public boolean onTouch(View v, MotionEvent event) {                        int action = event.getAction()&MotionEvent.ACTION_MASK;            switch (action) {            case MotionEvent.ACTION_DOWN://当手指按下                float x = event.getX();                float y = event.getY();                startPiont.set(x, y);//                mcurrentMatrix.set(iv.getImageMatrix());//图片还没有被拖动时候的位置                type = DRAG;                break;            case MotionEvent.ACTION_POINTER_1_DOWN://屏幕上已经有一根手指,再按下一根手指                mcurrentMatrix.set(iv.getImageMatrix());//图片还没有被缩放时候的大小                mstartP = getMidPoint(event);//得到移动前两个手指间的中心位置                mdistance = getMidDistance(event);//得到移动前两个手指间的距离                type = SCALE;                break;            case MotionEvent.ACTION_MOVE://当手指移动                if (type == DRAG) {                    mMatrix.set(mcurrentMatrix);                    float dx = event.getX() - startPiont.x;                    float dy = event.getY() - startPiont.y;                    mMatrix.postTranslate(dx, dy);                }else if(type == SCALE){                    mMatrix.set(mcurrentMatrix);                    float distance = getMidDistance(event);//得到移动后两个手指间的距离                    float sx = distance/mdistance;                    mMatrix.postScale(sx, sx, mstartP.x, mstartP.y);                }                break;            case MotionEvent.ACTION_UP://当手指弹起            case MotionEvent.ACTION_POINTER_1_UP://屏幕上弹起一根手指,还有一根手指                type = 0;                break;            default:                break;            }            //给界面设置变动后的数据            iv.setImageMatrix(mMatrix);            return true;        }                //计算中心点位置        public PointF getMidPoint(MotionEvent event){            float x = (event.getX(1) + event.getX(0))/2;            float y = (event.getY(1) + event.getY(0))/2;            return new PointF(x,y);        }                //计算两点间的距离        public float getMidDistance(MotionEvent event){            float dx = event.getX(1) - event.getX(0);            float dy = event.getY(1) - event.getY(0);            return FloatMath.sqrt((dx*dx) + (dy*dy));        }    }}
MainActivity.java
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.shellway.dragscale.MainActivity" >    <!--scaleType表示缩放类型, matrix表示图片的位置和大小 -->    <ImageView         android:id="@+id/iv"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:scaleType="matrix"        android:src="@drawable/family"        /></RelativeLayout>
activity_mian.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.shellway.dragscale"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="21" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>
AndroidManifest.xml

运行结果截图:

更多相关文章

  1. Android中显示消息通知栏
  2. 属性动画笔记
  3. Android(安卓)动画之RotateAnimation应用详解
  4. android动画及用法
  5. android 动画使用
  6. (转载)Android一些不常见的API及一些其他注意事项
  7. Android加载动画库
  8. Android(安卓)动画学习笔记
  9. Android(安卓)动画学习

随机推荐

  1. Android: android自适应屏幕方向和大小
  2. xml ----editview
  3. Android(安卓)assets 目录介绍和应用
  4. Android应用程序内存优化
  5. Android(安卓)Framework中的PolicyManage
  6. Android编译过程详解(三)
  7. 查看Android进程内存资源信息
  8. php +MySQL +KSWEB Android(安卓)应用
  9. 【Android】Android(安卓)中string-array
  10. Android(安卓)RetainFragment状态保存的