|
This article describes the Android sidebar custom implementation, in order to achieve the finger on the phone to the left or right, can move around the corresponding two views. Through the definition to achieve, without the help of third-party plug-ins. Implementation of the idea is very simple, by judging the finger sliding distance and speed to decide whether to scroll display menu items.
First, the realization of ideas
1. Ideas
Menu in the left, the content in the right, and then display the menu and the right side of the cell phone has a certain interval, the content shows a small part. When the contents are all displayed, the menu is not visible.
2. Judgment logic
This is to determine whether the finger should be displayed or hidden when the finger is lifted by the screen and finger
Second, the code list
First look at the next layout:
< LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android"
Xmlns: tools = "http://schemas.android.com/tools"
Android: id = "@ + id / layout"
Android: layout_width = "match_parent"
Android: layout_height = "match_parent"
Android: orientation = "horizontal"
Tools: context = ". MainActivity">
< LinearLayout
Android: id = "@ + id / menu"
Android: layout_width = "match_parent"
Android: layout_height = "match_parent"
Android: orientation = "horizontal"
Android: background = "@ drawable / pn">
< / LinearLayout>
< LinearLayout
Android: id = "@ + id / content"
Android: layout_width = "match_parent"
Android: layout_height = "match_parent"
Android: orientation = "horizontal"
Android: background = "@ drawable / sn">
< / LinearLayout>
< / LinearLayout>
Next, look at the code, have Notes:
Package com.example.learningjava;
Import com.example.learningjava.R.string;
Import android.R.integer;
Import android.R.menu;
Import android.os.AsyncTask;
Import android.os.Build;
Import android.os.Bundle;
Import android.annotation.SuppressLint;
Import android.annotation.TargetApi;
Import android.widget.LinearLayout.LayoutParams;
Import android.app.Activity;
Import android.util.DisplayMetrics;
Import android.util.Log;
Import android.view.Menu;
Import android.view.MotionEvent;
Import android.view.VelocityTracker;
Import android.view.View;
Import android.view.View.OnTouchListener;
Import android.view.Window;
Import android.widget.LinearLayout;
Public class MainActivity extends Activity implements OnTouchListener {
Private LinearLayout menuLayout; // Menu item
Private LinearLayout contentLayout; // content item
Private LayoutParams menuParams; // Parameters for menu items
Private LayoutParams contentParams; // The content item's contentLayout width value
Private int disPlayWidth; / / cell phone screen resolution
Private float xDown; / / pointing down the abscissa
Private float xMove; // The abscissa of the finger's movement
Private float xUp; / / record the abscissa of the finger after the lift
Private VelocityTracker mVelocityTracker; / / used to calculate the speed of finger sliding.
Float velocityX; / / Finger left and right speed
Public static final int SNAP_VELOCITY = 400; / / scroll display and hide the menu, the finger sliding speed needs to be achieved.
Private boolean menuIsShow = false; / / initialization menu items can not
Private static final int menuPadding = 80; / / menu to complete the display, leaving the width of the content
Protected void onCreate (BundleavedInstanceState) {
Super.onCreate (savedInstanceState);
RequestWindowFeature (Window.FEATURE_NO_TITLE);
SetContentView (R.layout.activity_main);
InitLayoutParams ();
}}
/ **
* Initialize the Layout and set its corresponding parameters
* /
Private void initLayoutParams ()
{
// Get the size of the screen
DisplayMetrics dm = new DisplayMetrics ();
GetWindowManager (). GetDefaultDisplay (). GetMetrics (dm);
DisPlayWidth = dm.widthPixels;
// Get the control
MenuLayout = (LinearLayout) findViewById (R.id.menu);
ContentLayout = (LinearLayout) findViewById (R.id.content);
FindViewById (R.id.layout) .setOnTouchListener (this);
// Get the control parameters
MenuParams = (LinearLayout.LayoutParams) menuLayout.getLayoutParams ();
ContentParams = (LinearLayout.LayoutParams) contentLayout.getLayoutParams ();
// Initializes the width and margin of the menu and content
MenuParams.width = disPlayWidth - menuPadding;
MenuParams.leftMargin = 0 - menuParams.width;
ContentParams.width = disPlayWidth;
ContentParams.leftMargin = 0;
//Setting parameters
MenuLayout.setLayoutParams (menuParams);
ContentLayout.setLayoutParams (contentParams);
}}
@Override
Public boolean onTouch (View v, MotionEvent event)
{
AcquireVelocityTracker (event);
Switch (event.getAction ())
{
Case MotionEvent.ACTION_DOWN:
XDown = event.getRawX ();
Break;
Case MotionEvent.ACTION_MOVE:
XMove = event.getRawX ();
IsScrollToShowMenu ();
Break
Case MotionEvent.ACTION_UP:
XUp = event.getRawX ();
IsShowMenu ();
ReleaseVelocityTracker ();
Break;
Case MotionEvent.ACTION_CANCEL:
ReleaseVelocityTracker ();
Break;
}}
Return true;
}}
/ **
* Determine whether to scroll the menu according to the distance pressed by the finger
* /
Private void isScrollToShowMenu ()
{
Int distanceX = (int) (xMove - xDown);
If (! MenuIsShow) {
ScrollToShowMenu (distanceX);
} Else {
ScrollToHideMenu (distanceX);
}}
}}
/ **
* Determine if you want to display the menu after lifting your finger
* /
Private void isShowMenu ()
{
VelocityX = getScrollVelocity ();
If (wantToShowMenu ()) {
If (shouldShowMenu ()) {
ShowMenu ();
} Else {
HideMenu ();
}}
}}
Else if (wantToHideMenu ()) {
If (shouldHideMenu ()) {
HideMenu ();
} Else {
ShowMenu ();
}}
}}
}}
/ **
* To display the menu, when the distance to the right is greater than 0 and the menu is not visible
* /
Private boolean wantToShowMenu () {
Return! MenuIsShow && xUp-xDown> 0;
}}
/ **
* To hide the menu when the distance to the left is greater than 0 and the menu is visible
* /
Private boolean wantToHideMenu () {
Return menuIsShow && xDown-xUp> 0;
}}
/ **
* Judge should display the menu, when the distance to move to the right of more than half of the menu or speed exceeds the given value
* /
Private boolean shouldShowMenu () {
Return xUp-xDown> menuParams.width / 2 || velocityX> SNAP_VELOCITY;
}}
/ **
* Judgment should hide the menu, when the distance to move left more than half of the menu or speed exceeds the given value
* /
Private boolean shouldHideMenu () {
Return xDown-xUp> menuParams.width / 2 || velocityX> SNAP_VELOCITY;
}}
/ **
* Display the menu bar
* /
Private void showMenu ()
{
New showMenuAsyncTask (). Execute (50);
MenuIsShow = true;
}}
/ **
* Hide the menu bar
* /
Private void hideMenu ()
{
New showMenuAsyncTask (). Execute (-50);
MenuIsShow = false;
}}
/ **
* When the pointer is pressed, scroll to display the menu slowly
* @ Param scrollX The distance to move each time you scroll
* /
Private void scrollToShowMenu (int scrollX)
{
If (scrollX> 0 && scrollX < = menuParams.width)
MenuParams.leftMargin = -menuParams.width + scrollX;
MenuLayout.setLayoutParams (menuParams);
}}
/ **
* When the pointer is pressed, scroll to hide the menu
* @ Param scrollX The distance to move each time you scroll
* /
Private void scrollToHideMenu (int scrollX)
{
If (scrollX> = - menuParams.width && scrollX < 0)
MenuParams.leftMargin = scrollX;
MenuLayout.setLayoutParams (menuParams);
}}
/ **
* Create VelocityTracker object, and will touch the sliding interface to join the content VelocityTracker them.
* @param event Add a MotionEvent to the VelocityTracker
* /
Private void acquireVelocityTracker (final MotionEvent event) {
If (null == mVelocityTracker) {
MVelocityTracker = VelocityTracker.obtain ();
}}
MVelocityTracker.addMovement (event);
}}
/ **
* Gets the speed at which the finger slides in the content interface.
* @return The sliding speed, in pixels per second.
* /
Private int getScrollVelocity () {
MVelocityTracker.computeCurrentVelocity (1000);
Int velocity = (int) mVelocityTracker.getXVelocity ();
Return Math.abs (velocity);
}}
/ **
* Free VelocityTracker
* /
Private void releaseVelocityTracker () {
If (null! = MVelocityTracker) {
MVelocityTracker.clear ();
MVelocityTracker.recycle ();
MVelocityTracker = null;
}}
}}
/ **
*
*: Simulates the animation process, allowing the naked eye to see the effect of scrolling
*
* /
Class showMenuAsyncTask extends AsyncTask < Integer, Integer, Integer>
{
@Override
Protected Integer doInBackground (Integer ... params)
{
Int leftMargin = menuParams.leftMargin;
While (true)
{// Rolling the interface according to the incoming speed, when the scroll reaches the left or right border, jump out of the loop.
LeftMargin + = params [0];
If (params [0]> 0 && leftMargin> 0)
{
LeftMargin = 0;
Break;
} Else if (params [0] < 0 && leftMargin < -menuParams.width)
{
LeftMargin = -menuParams.width;
Break;
}}
PublishProgress (leftMargin);
Try
{
Thread.sleep (40); / / sleep about the naked eye to see the rolling effect
} Catch (InterruptedException e)
{
E.printStackTrace ();
}}
}}
Return leftMargin;
}}
@Override
Protected void onProgressUpdate (Integer ... value)
{
MenuParams.leftMargin = value [0];
MenuLayout.setLayoutParams (menuParams);
}}
@Override
Protected void onPostExecute (Integer result)
{
MenuParams.leftMargin = result;
MenuLayout.setLayoutParams (menuParams);
}}
}}
}}
Third, the effect and description
Skate menu in many applications will see, in fact, the principle is very simple to achieve, but there is a lot of judgments, you have to determine the distance and direction of finger movement, but also to determine the speed of finger movement. So the code may be a bit more to write, but the principle is not difficult to understand. In addition, in order to scroll the effect can see the naked eye, add a showMenuAsyncTask class, it is in the process of rolling the view, every sleep (40) and then scroll, of course, here time can be changed to one, the effect will be even better.
|
|
|
|