Android 高仿微信界面

http://blog.csdn.net/dawanganban/article/details/20408505

上一篇《是男人就下100层【第一层】——高仿微信界面(7)》中我们实现了下弹式菜单,这一篇我们来看看如何实现微信中的摇一摇功能。

首先我们来布局我们的摇一摇界面

布局文件如下:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical"  
  6.     android:background="#111"  
  7.     >  
  8.       
  9.     <RelativeLayout  
  10.         android:layout_width="fill_parent"  
  11.         android:layout_height="fill_parent"  
  12.         android:layout_centerInParent="true" >  
  13.               
  14.         <ImageView  
  15.             android:id="@+id/shakeBg"  
  16.             android:layout_width="wrap_content"  
  17.             android:layout_height="wrap_content"  
  18.             android:layout_centerInParent="true"          
  19.             android:src="@drawable/shakehideimg_man2" />  
  20.           
  21.         <LinearLayout  
  22.             android:layout_width="fill_parent"  
  23.             android:layout_height="wrap_content"  
  24.             android:layout_centerInParent="true"  
  25.             android:orientation="vertical" >  
  26.               
  27.             <RelativeLayout  
  28.                 android:id="@+id/shakeImgUp"     
  29.                 android:layout_width="fill_parent"  
  30.                 android:layout_height="190dp"                 
  31.                 android:background="#111">                 
  32.                 <ImageView                     
  33.                     android:layout_width="wrap_content"  
  34.                     android:layout_height="wrap_content"  
  35.                     android:layout_alignParentBottom="true"  
  36.                     android:layout_centerHorizontal="true"                                
  37.                     android:src="@drawable/shake_logo_up"  
  38.                      />                  
  39.             </RelativeLayout>  
  40.             <RelativeLayout  
  41.                 android:id="@+id/shakeImgDown"  
  42.                 android:layout_width="fill_parent"  
  43.                 android:layout_height="190dp"                 
  44.                 android:background="#111">                 
  45.                 <ImageView                     
  46.                     android:layout_width="wrap_content"  
  47.                     android:layout_height="wrap_content"  
  48.                     android:layout_centerHorizontal="true"                                
  49.                     android:src="@drawable/shake_logo_down"  
  50.                      />                  
  51.             </RelativeLayout>   
  52.         </LinearLayout>  
  53.     </RelativeLayout>  
  54.       
  55.     <RelativeLayout   
  56.         android:id="@+id/shake_title_bar"   
  57.         android:layout_width="fill_parent"  
  58.         android:layout_height="45dp"  
  59.         android:background="@drawable/title_bar"  
  60.         android:gravity="center_vertical"  >  
  61.             <Button  
  62.                 android:layout_width="70dp"  
  63.                 android:layout_height="wrap_content"  
  64.                 android:layout_centerVertical="true"  
  65.                 android:text="返回"  
  66.                 android:textSize="14sp"  
  67.                 android:textColor="#fff"  
  68.                 android:onClick="shake_activity_back"  
  69.                 android:background="@drawable/title_btn_back"/>    
  70.             <TextView  
  71.                 android:layout_width="wrap_content"   
  72.                 android:layout_height="wrap_content"   
  73.                 android:text="摇一摇"  
  74.                 android:layout_centerInParent="true"  
  75.                 android:textSize="20sp"       
  76.                 android:textColor="#ffffff" />   
  77.             <ImageButton   
  78.                 android:layout_width="67dp"   
  79.                 android:layout_height="wrap_content"  
  80.                 android:layout_alignParentRight="true"   
  81.                 android:layout_centerVertical="true"  
  82.                 android:layout_marginRight="5dp"  
  83.                 android:src="@drawable/mm_title_btn_menu"  
  84.                 android:background="@drawable/title_btn_right"  
  85.                 android:onClick="linshi"   
  86.                 />        
  87.     </RelativeLayout>  
  88.       
  89.   
  90.     <SlidingDrawer  
  91.         android:id="@+id/slidingDrawer1"  
  92.         android:layout_width="match_parent"  
  93.         android:layout_height="match_parent"  
  94.         android:content="@+id/content"  
  95.         android:handle="@+id/handle" >  
  96.         <Button  
  97.             android:id="@+id/handle"  
  98.             android:layout_width="wrap_content"  
  99.             android:layout_height="wrap_content"       
  100.                     
  101.             android:background="@drawable/shake_report_dragger_up" />  
  102.         <LinearLayout  
  103.             android:id="@+id/content"  
  104.             android:layout_width="match_parent"  
  105.             android:layout_height="match_parent"  
  106.             android:background="#f9f9f9" >              
  107.             <ImageView  
  108.                 android:layout_width="match_parent"  
  109.                 android:layout_height="wrap_content"  
  110.                 android:scaleType="fitXY"  
  111.                 android:src="@drawable/shake_line_up" />  
  112.         </LinearLayout>  
  113.     </SlidingDrawer>  
  114.   
  115. </RelativeLayout>  

这个布局里面用到了很多相对布局,最外面是一个相对布局(我们先称为R1),R1内是两个相对布局(分别称为R2、R3)和一个抽屉组件,R3是上部标题栏,R2中有一个ImageView和一个线性布局,这两个组件都位于R2的中心,所以上面的线性布局会将下面的ImageView遮住,为什么要遮住,玩过微信摇一摇的朋友应该明白。

SlidingDrawer隐藏屏外的内容,并允许用户通过handle以显示隐藏内容。它可以垂直或水平滑动,它有俩个View组成,其一是可以拖动的handle,其二是隐藏内容的View.它里面的控件必须设置布局,在布局文件中必须指定handle和content.

接下来我们看看如何检查手机摇晃,摇一摇让手机震动

  1. package com.example.weixin.listener;  
  2.   
  3. import android.content.Context;  
  4. import android.hardware.Sensor;  
  5. import android.hardware.SensorEvent;  
  6. import android.hardware.SensorEventListener;  
  7. import android.hardware.SensorManager;  
  8. import android.util.Log;  
  9.   
  10. /** 
  11.  * 一个检测手机摇晃的监听器 
  12.  */  
  13. public class ShakeListener implements SensorEventListener {  
  14.     // 速度阈值,当摇晃速度达到这值后产生作用  
  15.     private static final int SPEED_SHRESHOLD = 3000;  
  16.     // 两次检测的时间间隔  
  17.     private static final int UPTATE_INTERVAL_TIME = 70;  
  18.     // 传感器管理器  
  19.     private SensorManager sensorManager;  
  20.     // 传感器  
  21.     private Sensor sensor;  
  22.     // 重力感应监听器  
  23.     private OnShakeListener onShakeListener;  
  24.     // 上下文  
  25.     private Context mContext;  
  26.     // 手机上一个位置时重力感应坐标  
  27.     private float lastX;  
  28.     private float lastY;  
  29.     private float lastZ;  
  30.     // 上次检测时间  
  31.     private long lastUpdateTime;  
  32.   
  33.     // 构造器  
  34.     public ShakeListener(Context c) {  
  35.         // 获得监听对象  
  36.         mContext = c;  
  37.         start();  
  38.     }  
  39.   
  40.     // 开始  
  41.     public void start() {  
  42.         // 获得传感器管理器  
  43.         sensorManager = (SensorManager) mContext  
  44.                 .getSystemService(Context.SENSOR_SERVICE);  
  45.         if (sensorManager != null) {  
  46.             // 获得重力传感器  
  47.             sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);  
  48.         }  
  49.         // 注册  
  50.         if (sensor != null) {  
  51.             sensorManager.registerListener(this, sensor,  
  52.                     SensorManager.SENSOR_DELAY_GAME);  
  53.         }  
  54.   
  55.     }  
  56.   
  57.     // 停止检测  
  58.     public void stop() {  
  59.         sensorManager.unregisterListener(this);  
  60.     }  
  61.   
  62.     // 设置重力感应监听器  
  63.     public void setOnShakeListener(OnShakeListener listener) {  
  64.         onShakeListener = listener;  
  65.     }  
  66.   
  67.     // 重力感应器感应获得变化数据  
  68.     public void onSensorChanged(SensorEvent event) {  
  69.         // 现在检测时间  
  70.         long currentUpdateTime = System.currentTimeMillis();  
  71.         // 两次检测的时间间隔  
  72.         long timeInterval = currentUpdateTime - lastUpdateTime;  
  73.         // 判断是否达到了检测时间间隔  
  74.         if (timeInterval < UPTATE_INTERVAL_TIME)  
  75.             return;  
  76.         // 现在的时间变成last时间  
  77.         lastUpdateTime = currentUpdateTime;  
  78.   
  79.         // 获得x,y,z坐标  
  80.         float x = event.values[0];  
  81.         float y = event.values[1];  
  82.         float z = event.values[2];  
  83.   
  84.         // 获得x,y,z的变化值  
  85.         float deltaX = x - lastX;  
  86.         float deltaY = y - lastY;  
  87.         float deltaZ = z - lastZ;  
  88.   
  89.         // 将现在的坐标变成last坐标  
  90.         lastX = x;  
  91.         lastY = y;  
  92.         lastZ = z;  
  93.   
  94.         double speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ  
  95.                 * deltaZ)  
  96.                 / timeInterval * 10000;  
  97.         //Log.v("thelog", "===========log===================");  
  98.         // 达到速度阀值,发出提示  
  99.         if (speed >= SPEED_SHRESHOLD) {  
  100.             onShakeListener.onShake();  
  101.         }  
  102.     }  
  103.   
  104.     public void onAccuracyChanged(Sensor sensor, int accuracy) {  
  105.   
  106.     }  
  107.   
  108.     // 摇晃监听接口  
  109.     public interface OnShakeListener {  
  110.         public void onShake();  
  111.     }  
  112.   
  113. }  

SensorManager是一个系统提供来管理传感器的服务。

SensorManager通过getDefaultSensor(int type)方法来获取指定类型的传感器。

  1. // 获得重力传感器  
  2. sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);  

SensorManager提供了一个注册传感器的方法:registerListener

  1. sensorManager.registerListener(this, sensor,  
  2.                     SensorManager.SENSOR_DELAY_GAME);  

SensorEventListener接口定义了两个方法需要实现

onSensorChanged()方法,当传感器的值发生改变时触发该方法。

onAccuracyChanged()方法,当传感器的精度发生改变时触发该方法。

  1. // 重力感应器感应获得变化数据  
  2. public void onSensorChanged(SensorEvent event) {  
  3.     // 现在检测时间  
  4.     long currentUpdateTime = System.currentTimeMillis();  
  5.     // 两次检测的时间间隔  
  6.     long timeInterval = currentUpdateTime - lastUpdateTime;  
  7.     // 判断是否达到了检测时间间隔  
  8.     if (timeInterval < UPTATE_INTERVAL_TIME)  
  9.         return;  
  10.     // 现在的时间变成last时间  
  11.     lastUpdateTime = currentUpdateTime;  
  12.   
  13.     // 获得x,y,z坐标  
  14.     float x = event.values[0];  
  15.     float y = event.values[1];  
  16.     float z = event.values[2];  
  17.   
  18.     // 获得x,y,z的变化值  
  19.     float deltaX = x - lastX;  
  20.     float deltaY = y - lastY;  
  21.     float deltaZ = z - lastZ;  
  22.   
  23.     // 将现在的坐标变成last坐标  
  24.     lastX = x;  
  25.     lastY = y;  
  26.     lastZ = z;  
  27.   
  28.     double speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ  
  29.             * deltaZ)  
  30.             / timeInterval * 10000;  
  31.     //Log.v("thelog", "===========log===================");  
  32.     // 达到速度阀值,发出提示  
  33.     if (speed >= SPEED_SHRESHOLD) {  
  34.         onShakeListener.onShake();  
  35.     }  
  36. }  

坐标对应的关系看下图可知

这里计算速度的公式是高中学过的知识v=s/t=(a^2+b^2+c^2)/t

  1. double speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ  
  2.                 * deltaZ)  
  3.                 / timeInterval * 10000;  


在Activity中创建摇动监听实例并设置监听

  1. mShakeListener = new ShakeListener(this);  
  2.        mShakeListener.setOnShakeListener(new OnShakeListener() {  
  3.         public void onShake() {  
  4.             //Toast.makeText(getApplicationContext(), "抱歉,暂时没有找到在同一时刻摇一摇的人。\n再试一次吧!", Toast.LENGTH_SHORT).show();  
  5.             startAnim();  //开始 摇一摇手掌动画  
  6.             mShakeListener.stop();  
  7.             startVibrato(); //开始 震动  
  8.             new Handler().postDelayed(new Runnable(){  
  9.                 @Override  
  10.                 public void run(){  
  11.                     //Toast.makeText(getApplicationContext(), "抱歉,暂时没有找到\n在同一时刻摇一摇的人。\n再试一次吧!", 500).setGravity(Gravity.CENTER,0,0).show();  
  12.                     Toast mtoast;  
  13.                     mtoast = Toast.makeText(getApplicationContext(),  
  14.                              "抱歉,暂时没有找到\n在同一时刻摇一摇的人。\n再试一次吧!", 10);  
  15.                            //mtoast.setGravity(Gravity.CENTER, 0, 0);  
  16.                            mtoast.show();  
  17.                            mVibrator.cancel();  
  18.                            mShakeListener.start();  
  19.                 }  
  20.             }, 2000);  
  21.         }  
  22.     });  

在设置监听之前,在Activity的onCreate方法中需呀获得系统提供的振动服务对象

  1. Vibrator mVibrator = (Vibrator)getApplication().getSystemService(VIBRATOR_SERVICE);  

有关Vibrator的使用请看我的另一篇博文:http://blog.csdn.net/dawanganban/article/details/17531697

  1. public void startVibrato(){     //定义震动  
  2.         mVibrator.vibrate( new long[]{500,200,500,200}, -1); //第一个{}里面是节奏数组, 第二个参数是重复次数,-1为不重复,非-1俄日从pattern的指定下标开始重复  
  3.     }  

摇一摇的时候还有一个图片移动的动画,设置动画代码如下:

  1. public void startAnim () {   //定义摇一摇动画动画  
  2.     AnimationSet animup = new AnimationSet(true);  
  3.     TranslateAnimation mytranslateanimup0 = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,-0.5f);  
  4.     mytranslateanimup0.setDuration(1000);  
  5.     TranslateAnimation mytranslateanimup1 = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,+0.5f);  
  6.     mytranslateanimup1.setDuration(1000);  
  7.     mytranslateanimup1.setStartOffset(1000);  
  8.     animup.addAnimation(mytranslateanimup0);  
  9.     animup.addAnimation(mytranslateanimup1);  
  10.     mImgUp.startAnimation(animup);  
  11.       
  12.     AnimationSet animdn = new AnimationSet(true);  
  13.     TranslateAnimation mytranslateanimdn0 = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,+0.5f);  
  14.     mytranslateanimdn0.setDuration(1000);  
  15.     TranslateAnimation mytranslateanimdn1 = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,-0.5f);  
  16.     mytranslateanimdn1.setDuration(1000);  
  17.     mytranslateanimdn1.setStartOffset(1000);  
  18.     animdn.addAnimation(mytranslateanimdn0);  
  19.     animdn.addAnimation(mytranslateanimdn1);  
  20.     mImgDn.startAnimation(animdn);    
  21. }  

运行效果如下:

源代码下载:http://download.csdn.net/detail/lxq_xsyu/6990129

时间: 2024-11-01 18:18:41

Android 高仿微信界面的相关文章

Android高仿微信聊天界面代码分享_Android

微信聊天现在非常火,是因其界面漂亮吗,哈哈,也许吧.微信每条消息都带有一个气泡,非常迷人,看起来感觉实现起来非常难,其实并不难.下面小编给大家分享实现代码. 先给大家展示下实现效果图: OK,下面我们来看一下整个小项目的主体结构: 下面是Activity的代码: package com.way.demo; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import jav

Android开发之高仿微信界面(1)

转载自:http://blog.csdn.net/dawanganban/article/details/19925449   是男人就下100层[第一层]--高仿微信界面(1) 分类: Android高仿系列2014-02-25 23:07 4118人阅读 评论(14) 收藏 举报 微信界面高仿闪屏主题 从今天开始将进行一个特别有趣且有意义的专栏<是男人就下100层>,计划对市面上比较火的应用进行高度仿照,并将开发过程贴出来,和大家交流和分享.由于时间关系可能进度会比较缓慢,但是任何事情如果

Android高仿微信聊天界面代码分享

微信聊天现在非常火,是因其界面漂亮吗,哈哈,也许吧.微信每条消息都带有一个气泡,非常迷人,看起来感觉实现起来非常难,其实并不难.下面小编给大家分享实现代码. 先给大家展示下实现效果图: OK,下面我们来看一下整个小项目的主体结构: 下面是Activity的代码: package com.way.demo; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import jav

Android高仿微信表情输入与键盘输入详解_Android

       最近公司在项目上要使用到表情与键盘的切换输入,自己实现了一个,还是存在些缺陷,比如说键盘与表情切换时出现跳闪问题,这个相当困扰我,不过所幸在Github(其中一个不错的开源项目,其代码整体结构很不错)并且在论坛上找些解决方案,再加上我也是研究了好多个开源项目的代码,最后才苦逼地整合出比较不错的实现效果,可以说跟微信基本一样(嘿嘿,只能说目前还没发现大Bug,若发现大家一起日后慢慢完善,这里我也只是给出了实现方案,拓展其他表情我并没有实现哈,不过代码中我实现了一个可拓展的fragme

Android 高仿微信朋友圈动态支持双击手势放大并滑动查看图片效果

最近参与了开发一款旅行APP,其中包含实时聊天和动态评论功能,终于耗时几个月几个伙伴完成了,今天就小结一下至于实时聊天功能如果用户不多的情况可以scoket实现,如果用户万级就可以采用开源的smack + opnefile实现,也可以用mina开源+XMMP,至于怎么搭建和实现,估计目前github上一搜一大把,至于即时通讯怕误人子弟,暂且不做介绍,现就把实现的一个微信朋友圈的小功能介绍一下. 先上效果图: 一拿到主流的UI需求,大致分析下,需要我ListView嵌套Gridview,而grid

Android高仿微信图片选择功能的PhotoPicker

类似于微信修改头像的功能基本上每个app都会有,以前公司开发的项目就有修改头像的功能,但是用的Android系统自带的图片 选择器.用Android系统的图片选择器有个好处就是稳定,不会有什么问题.但也有它的缺点,比如不可定制,我们想要修改一下符合自己app的风格无法 做到. 既然大部分app都要用到图片选择器,为啥我不自己写一个呢?难不成每次都用系统自带的?那显得太没水平.所以,我就有了一个自己编写一个图片选择器的想法,以后只要有项目需要这个功能,直接拿来用就行了,这多爽! 其实github上

Android 高仿微信语音聊天页面高斯模糊(毛玻璃效果)_Android

目前的应用市场上,使用毛玻璃效果的APP随处可见,比如用过微信语音聊天的人可以发现,语音聊天页面就使用了高斯模糊效果. 先看下效果图:   仔细观察上图,我们可以发现,背景图以用户头像为模板,对其进行了高斯模糊,并把它作为整个页面的背景色. 关于Android如何快速实现高斯模糊(毛玻璃效果),网上一堆相关介绍,可参考下面文章一种快速毛玻璃虚化效果实现–Android. 下面直接给出模糊化工具类(已验证可行): import android.graphics.Bitmap; /** * 快速模糊

Android 高仿微信支付数字键盘功能_Android

现在很多app的支付.输入密码功能,都已经开始使用自定义数字键盘,不仅更加方便.其效果着实精致. 下面带着大家学习下,如何高仿微信的数字键盘,可以拿来直接用在自身的项目中. 先看下效果图: 1. 自定义布局 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

Android 高仿微信语音聊天页面高斯模糊(毛玻璃效果)

目前的应用市场上,使用毛玻璃效果的APP随处可见,比如用过微信语音聊天的人可以发现,语音聊天页面就使用了高斯模糊效果. 先看下效果图: 仔细观察上图,我们可以发现,背景图以用户头像为模板,对其进行了高斯模糊,并把它作为整个页面的背景色. 关于Android如何快速实现高斯模糊(毛玻璃效果),网上一堆相关介绍,可参考下面文章一种快速毛玻璃虚化效果实现–Android. 下面直接给出模糊化工具类(已验证可行): import android.graphics.Bitmap; /** * 快速模糊化工