In the previous article "men are on the next layer [the first layer] -- high imitation interface (7)", we implemented the pop-up menu, this article describes how to implement the shake function.
First, let's deploy our shake interface.
The layout file is as follows:
<? Xml version = "1.0" encoding = "UTF-8"?> <RelativeLayout xmlns: android = "http://schemas.android.com/apk/res/android" android: layout_width = "fill_parent" android: layout_height = "fill_parent" android: orientation = "vertical" android: background = "#111"> <RelativeLayout android: layout_width = "fill_parent" android: layout_height = "fill_parent" android: layout_centerInParent = "true"> <ImageView android: id = "@ + id/shakeBg" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_centerInParent = "true" android: src = "@ drawable/shakehideimg_man2"/> <LinearLayout android: layout_width = "fill_parent" android: layout_height = "wrap_content" android: layout_centerInParent = "true" android: orientation = "vertical"> <RelativeLayout android: id = "@ + id/shakeImgUp" android: layout_width = "fill_parent" android: layout_height = "190dp" android: background = "#111"> <ImageView android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_alignParentBottom = "true" android: layout_centerHorizontal = "true" android: src = "@ drawable/shake_logo_up"/> </RelativeLayout> <RelativeLayout android: id = "@ + id/shakeImgDown" android: layout_width = "fill_parent" android: layout_height = "190dp" android: background = "#111"> <ImageView android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_centerHorizontal = "true" android: src = "@ drawable/shake_logo_down"/> </RelativeLayout> </LinearLayout> </RelativeLayout> <RelativeLayout android: id = "@ + id/shake_title_bar" android: layout_width = "fill_parent" android: layout_height = "45dp" android: background = "@ drawable/title_bar" android: gravity = "center_vertical"> <Button android: layout_width = "70dp" android: layout_height = "wrap_content" android: layout_centerVertical = "true" android: text = "return" android: textSize = "14sp" android: textColor = "# fff" android: onClick = "shake_activity_back" android: background = "@ drawable/title_btn_back"/> <TextView android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: text = "Shake" android: layout_centerInParent = "true" android: textSize = "20sp" android: textColor = "# ffffff"/> <ImageButton android: layout_width = "67dp" android: layout_height = "wrap_content" android: Expiration = "true" android: layout_centerVertical = "true" android: layout_marginRight = "5dp" android: src = "@ drawable/mm_title_btn_menu" android: background = "@ drawable/title_btn_right" android: onClick = "linshi"/> </RelativeLayout> <SlidingDrawer android: id = "@ + id/slidingDrawer1" android: layout_width = "match_parent" android: layout_height = "match_parent" android: content = "@ + id/content" android: handle = "@ + id/handle"> <Button android: id = "@ + id/handle" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: background = "@ drawable/shake_report_dragger_up"/> <LinearLayout android: id = "@ + id/content" android: layout_width = "match_parent" android: layout_height = "match_parent" android: background = "# background"> <ImageView android: layout_width = "match_parent" android: layout_height = "wrap_content" android: scaleType = "fitXY" android: src = "@ drawable/shake_line_up"/> </LinearLayout> </sshortingdrawer> </RelativeLayout>
Many relative la s are used in this layout. the outermost side is a relative layout (we call it R1 first). R1 contains two relative la S (R2 and R3 respectively) and a drawer component, r3 is the upper title bar. R2 has an ImageView and a linear layout. Both components are located at the center of R2. Therefore, the linear layout above will cover the following ImageView. Why, friends who have been shaking should understand.
SlidingDrawer hides content outside the screen and allows users to display hidden content through handle. It can slide vertically or horizontally. It consists of two views. One is the handle that can be dragged, and the other is the View that hides the content. the layout must be set for the controls in the layout file, and handle and content must be specified in the layout file.
Next let's take a look at how to check the mobile phone shake and shake the mobile phone
Package com. example. weixin. listener; import android. content. context; import android. hardware. sensor; import android. hardware. sensorEvent; import android. hardware. sensorEventListener; import android. hardware. sensorManager; import android. util. log;/*** a mobile phone shake detection listener */public class ShakeListener implements SensorEventListener {// speed threshold, when the shaking speed reaches this value, private static final int SPEED_SHRESHOLD = 3000; // between the two detection times Private static final int UPTATE_INTERVAL_TIME = 70; // Sensor manager private SensorManager sensorManager; // sensor private Sensor sensor; // gravity Sensor listener private OnShakeListener onShakeListener; // Context private Context mContext; // gravity sensing coordinates private float lastX; private float lastY; private float lati; // last detection time private long lastUpdateTime; // constructor public ShakeListener (Context c) {// obtain the listening object mContext = c; start () ;}// start publi C void start () {// obtain sensor manager sensorManager = (SensorManager) mContext. getSystemService (Context. SENSOR_SERVICE); if (sensorManager! = Null) {// obtain the gravity sensor Sensor = sensorManager. getdefasensensor (sensor. TYPE_ACCELEROMETER);} // register if (sensor! = Null) {sensorManager. registerListener (this, sensor, SensorManager. SENSOR_DELAY_GAME) ;}}// stop public void stop () {sensorManager. unregisterListener (this);} // set the gravity sensor listener public void setOnShakeListener (OnShakeListener listener) {onShakeListener = listener;} // The gravity sensor senses the change data public void onSensorChanged (SensorEvent) {// The current detection time is long currentUpdateTime = System. currentTimeMillis (); // interval between two checks long timeInterval = currentUpdateTime-lastUpdateTime; // you can determine whether the detection interval has been reached if (timeInterval <UPTATE_INTERVAL_TIME) return; // The current time is changed to lastUpdateTime = currentUpdateTime; // obtain the x, y, and zcoordinate float x = event. values [0]; float y = event. values [1]; float z = event. values [2]; // obtain the changing values of x, y, and z, float deltaX = x-lastX; float deltaY = y-lastY; float deltaZ = z-lastZ; // convert the current coordinate to the last coordinate lastX = x; lastY = y; lati = z; double speed = Math. sqrt (deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ)/timeInterval * 10000; // Log. v ("thelog ", "=========== log =================== "); // when the speed threshold is reached, the prompt if (speed> = SPEED_SHRESHOLD) {onShakeListener is sent. onShake () ;}} public void onAccuracyChanged (Sensor sensor, int accuracy) {}// shake listener interface public interface OnShakeListener {public void onShake ();}}
SensorManager is a service provided by a system to manage sensors.
SensorManager uses the getdefasensensor (int type) method to obtain the sensor of the specified type.
// Obtain the gravity sensor Sensor = sensorManager. getdefasensensor (sensor. TYPE_ACCELEROMETER );
SensorManager provides a method to register a sensor: registerListener
sensorManager.registerListener(this, sensor,SensorManager.SENSOR_DELAY_GAME);
The SensorEventListener interface defines two methods to be implemented.
OnSensorChanged () method, which is triggered when the sensor value changes.
OnAccuracyChanged () method, which is triggered when the accuracy of the sensor changes.
// The gravity sensor senses the changed data. public void onSensorChanged (SensorEvent event) {// The current detection time is long currentUpdateTime = System. currentTimeMillis (); // interval between two checks long timeInterval = currentUpdateTime-lastUpdateTime; // you can determine whether the detection interval has been reached if (timeInterval <UPTATE_INTERVAL_TIME) return; // The current time is changed to lastUpdateTime = currentUpdateTime; // obtain the x, y, and zcoordinate float x = event. values [0]; float y = event. values [1]; float z = event. values [2]; // obtain the changing values of x, y, and z, float deltaX = x-lastX; float deltaY = y-lastY; float deltaZ = z-lastZ; // convert the current coordinate to the last coordinate lastX = x; lastY = y; lati = z; double speed = Math. sqrt (deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ)/timeInterval * 10000; // Log. v ("thelog ", "=========== log =================== "); // when the speed threshold is reached, the prompt if (speed> = SPEED_SHRESHOLD) {onShakeListener is sent. onShake ();}}
See the relationship between coordinates.
The formula for calculating the speed here is the high school knowledge v = s/t = (a ^ 2 + B ^ 2 + c ^ 2)/t
double speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ* deltaZ)/ timeInterval * 10000;
Create a shake listener instance in the Activity and set the listener
MShakeListener = new ShakeListener (this); mShakeListener. setOnShakeListener (new OnShakeListener () {public void onShake () {// Toast. makeText (getApplicationContext (), "Sorry, no one has shaken at the same time. \ N try again! ", Toast. LENGTH_SHORT ). show (); startAnim (); // start shaking the palm animation mShakeListener. stop (); startVibrato (); // start to vibrate new Handler (). postDelayed (new Runnable () {@ Overridepublic void run () {// Toast. makeText (getApplicationContext (), "Sorry, \ n is not found at the same time. \ N try again! ", 500 ). setGravity (Gravity. CENTER, 0, 0 ). show (); Toast mtoast; mtoast = Toast. makeText (getApplicationContext (), "Sorry, \ n is not found at the same time. \ N try again! ", 10); // mtoast. setGravity (Gravity. CENTER, 0, 0); mtoast. show (); mVibrator. cancel (); mShakeListener. start () ;}}, 2000 );}});
Before setting the listener, you need to obtain the vibration service object provided by the system in the onCreate method of the Activity.
Vibrator mVibrator = (Vibrator)getApplication().getSystemService(VIBRATOR_SERVICE);
For use of Vibrator, see my other blog: http://blog.csdn.net/dawanganban/article/details/17531697
Public void startVibrato () {// defines the mVibrator. vibrate (new long [] {500,200,500,200},-1); // The first {} contains the rhythm array, the second parameter is the number of repetitions, and-1 is not repeated, non-1 Russian-Japanese repetition starts from the specified subscript of pattern}
When shaking, there is also an animation for moving images. The animation code is as follows:
Public void startAnim () {// defines the Animation set animup = new AnimationSet (true); 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); mytranslateanimup0.setDuration (1000); 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); mytranslateanimup1.setDuration (1000); mytranslateanimup1.setStartOffset (1000); animup. addAnimation (mytranslateanimup0); animup. addAnimation (mytranslateanimup1); mImgUp. startAnimation (animup); AnimationSet animdn = new AnimationSet (true); 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); mytranslateanimdn0.setDuration (1000); 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); mytranslateanimdn1.setDuration (1000); mytranslateanimdn1.setStartOffset (1000); animdn. addAnimation (mytranslateanimdn0); animdn. addAnimation (mytranslateanimdn1); mImgDn. startAnimation (animdn );}
The running effect is as follows:
Source code download: http://download.csdn.net/detail/lxq_xsyu/6990129