Android Imitation QQ6.0 homepage side sideslip effect _android

Source: Internet
Author: User

1. Overview



Recently have been with interns to do projects, found that they have not written a blog for a long time, these days update will be more frequent, QQ today to find QQ home menu sliding effect has changed, it can not help the evening to realize it!






2. Realize



2.1. A variety of ways to achieve
2.1.1 Custom ViewGroup to handle its Ontouch events
2.1.2 Framelayout + gesture Processing class Gesturedetector
2.2.3 uses Google's own drawerlayout to modify it
2.2.4 inherits from horizontal scrolling Horizontalscrollview
You can take a look at this http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2016/0909/6612.html, this way inherits from ViewGroup, Personally think it's OK but still more cumbersome to deal with more things, then I will use the last kind of 2.2.4 way to achieve, some people say directly to download a source code on the Internet can, this I can only GG.



2.3. Custom Slidingmenu extends Horizontalscrollview and then write the layout file this is the same as the ScrollView usage, except that it is scrolled horizontally


/**
 * Description:
 * Imitation QQ5.0 homepage side sideslip Custom View
 * Created by Zeng Hui on 2016/11/1.
 * qq:240336124 * email:240336124@qq.com * version:1.0/public
class Slidingmenu extends Horizontalscrollview {public
 Slidingmenu (context) {
 super (context);
 }

 Public Slidingmenu (context, AttributeSet attrs) {
 Super (context, attrs);
 }

 Public Slidingmenu (context, AttributeSet attrs, int defstyleattr) {
 Super (context, attrs, defstyleattr); c17/>}
}


2.4. After the operation found that the layout is not correct, completely disorderly obviously are match_parent but just can't. Then we need to use code to specify the width of the menu and content:



Width of the menu = width of the screen-the width of the custom right left
Width of content = width of screen






/**
 * description:
 * Customized view of QQ5.0 main page sliding
 * Created by Zeng Hui on 2016/11/1.
 * QQ: 240336124
 * Email: 240336124@qq.com
 * Version: 1.0
 */
Public class SlidingMenu extends HorizontalScrollView {
 Private view mMenuView;
 Private view mContentView;
 Private int mMenuWidth;
 
 Public SlidingMenu(Context context) {
 This(context, null);
 }
 
 Public SlidingMenu(Context context, AttributeSet attrs) {
 This(context, attrs, 0);
 }
 
 Public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
 Super(context, attrs, defStyleAttr);
 / / Get the width of the custom left side
 TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.SlidingMenu);
 Float rightPadding = array.getDimension(
  R.styleable.SlidingMenu_rightPadding, dip2px(50));
 // Calculate the width of the menu = the width of the screen - customize the width left on the right
 mMenuWidth = (int) (getScreenWidth() - rightPadding);
 Array.recycle();
 }
 
 /**
 * Convert dip to pixels
 */
 Private float dip2px(int dip) {
 Return TypedValue.applyDimension(
  TypedValue.COMPLEX_UNIT_DIP, dip, getResources().getDisplayMetrics());
 }
 
 
 @Override
 Protected void onFinishInflate() {
 super.onFinishInflate();
 
 / / 1. Get the root View is also the outer LinearLayout
 ViewGroup container = (ViewGroup) this.getChildAt(0);
 
 Int containerChildCount = container.getChildCount();
 If(containerChildCount>2){
  // Only two layouts are allowed inside. One is Menu (menu layout) One is Content (home content layout)
  Throw new IllegalStateException("SlidingMenu root layout allows only two layouts under the LinearLayout, menu layout and home page content layout");
 }
 
 // 2. Get menu and content layout
 mMenuView = container.getChildAt(0);
 mContentView = container.getChildAt(1);
 
 // 3. Specify the width of the content and menu layout
 // 3.1 The width of the menu = the width of the screen - the width left on the right side of the custom
 mMenuView.getLayoutParams().width = mMenuWidth;
 // 3.2 width of the content = width of the screen
 mContentView.getLayoutParams().width = getScreenWidth();
 }
 
 /**
 * Get the width of the screen
 */
 Public int getScreenWidth() {
 Resources resources = this.getResources();
 DisplayMetrics dm = resources.getDisplayMetrics();
 Return dm.widthPixels;
 }
}


The current effect is to be able to slide, and the menu and master page content layout width is normal






2.5 Next start let the menu slide to the off state, the fingers slide up the judgment menu to open and close and do the corresponding processing onlayout () Ontouch () Smoothscrollto (), Toggle the state of the menu when the finger is fast use gesturedetector gestures to process classes:


 /** * Description: * Imitation QQ5.0 homepage side sideslip of the custom view * Created by Zeng Hui on 2016/11/1. * qq:240336124 * email:240336124@qq.com * version:1.0/public class Slidingmenu extends Horizontalscrollview {priv
 Ate View Mmenuview;
 Private View Mcontentview;
 private int mmenuwidth;

 Gesture processing class is mainly used to deal with gesture fast sliding private gesturedetector mgesturedetector;

 Whether the menu opens private Boolean mmenuisopen = false;
 Public Slidingmenu {This (context, NULL);
 Public Slidingmenu (context, AttributeSet attrs) {This (context, attrs, 0);
 Public Slidingmenu (context, AttributeSet attrs, int defstyleattr) {Super (context, attrs, defstyleattr);
 Gets the width of the custom left TypedArray array = context.obtainstyledattributes (Attrs, R.styleable.slidingmenu);
 float rightpadding = array.getdimension (r.styleable.slidingmenu_rightpadding, dip2px (50));
 Calculate the width of the menu = screen width-Customize the width left on the right mmenuwidth = (int) (Getscreenwidth ()-rightpadding);

 Array.recycle (); Materialized gesture processing Class Mgesturedetector = new GeSturedetector (Context,new Gesturelistener ()); /** * Convert dip to pixel/private float dip2px (int dip) {return typedvalue.applydimension (Typedvalue.complex_unit_dip
 , Dip, Getresources (). Getdisplaymetrics ());

 } @Override protected void Onfinishinflate () {super.onfinishinflate ();

 1. Obtain the root view that is the outer linearlayout viewgroup container = (viewgroup) this.getchildat (0);
 int containerchildcount = Container.getchildcount (); if (Containerchildcount > 2) {//inside only allowed to place two layouts one is the content (menu layout) One is content (home page contents layout) throw new IllegalStateException ("Sli
 Dingmenu Root layout linearlayout only two layouts, menu layouts, and home page content layouts are allowed below.
 //2. Get menu and Content layout Mmenuview = container.getchildat (0);

 Mcontentview = Container.getchildat (1);
 3. Specify the width of the content and menu layout//3.1 Menu width = width of the screen-the width mmenuview.getlayoutparams () on the right side of the custom. Width = mmenuwidth;
 3.2 width of the content = width of the screen mcontentview.getlayoutparams (). Width = Getscreenwidth (); @Override public boolean ontouchevent (motionevent ev) {//Handle finger fast sliding if (mgesturedetector.ontouchevent) (EV)) {return mgesturedetector.ontouchevent (EV);
  Switch (ev.getaction ()) {case MOTIONEVENT.ACTION_UP://fingers raised to get the scrolling position int currentscrollx = GETSCROLLX ();
  if (Currentscrollx > MMENUWIDTH/2) {//Close menu Closemenu ();
  else {//Open menu Openmenu ();
 return false;
 return super.ontouchevent (EV);
 /** * Open Menu * * private void Openmenu () {smoothscrollto (0, 0);
 Mmenuisopen = true;
 /** * Close Menu */private void Closemenu () {smoothscrollto (mmenuwidth, 0);
 Mmenuisopen = false; @Override protected void OnLayout (Boolean changed, int l, int t, int r, int b) {super.onlayout (changed, L, T, R, B)
 ;
 Layout specified will be placed in the new child layout, when it is placed, let the menu scroll to the invisible State if (changed) {Scrollto (mmenuwidth, 0);
 /** * Get the width of the screen * * * public int getscreenwidth () {resources = This.getresources ();
 Displaymetrics DM = Resources.getdisplaymetrics ();
 return dm.widthpixels; Private class Gesturelistener extends gesturedetector.simpleongesturelistener{@OverriDe public boolean onfling (Motionevent E1, motionevent E2, float Velocityx, float velocityy) {//callback method when the finger is fast sliding log.e
  ("TAG", velocityx+ "");
   If the menu is open and is fast to the left, toggle the status of the menu (Mmenuisopen) {if (velocityx<-500) {togglemenu ();
  return true;
   }else{//If the menu is off and is fast sliding to the right, toggle the status if (velocityx>500) {togglemenu ();
  return true;
 return false;
 }/** * Toggle the status of the menu * * private void Togglemenu () {if (Mmenuisopen) {closemenu ();
 }else{Openmenu ();

 }
 }
}
/**
 * description:
 * Customized view of QQ5.0 main page sliding
 * Created by Zeng Hui on 2016/11/1.
 * QQ: 240336124
 * Email: 240336124@qq.com
 * Version: 1.0
 */
Public class SlidingMenu extends HorizontalScrollView {
 Private view mMenuView;
 Private view mContentView;
 Private int mMenuWidth;
 / / Gesture processing class is mainly used to handle gestures and rapid sliding
 Private GestureDetector mGestureDetector;
 
 // Is the menu open?
 Private boolean mMenuIsOpen = false;
 
 Public SlidingMenu(Context context) {
 This(context, null);
 }
 
 Public SlidingMenu(Context context, AttributeSet attrs) {
 This(context, attrs, 0);
 }
 
 Public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
 Super(context, attrs, defStyleAttr);
 / / Get the width of the custom left side
 TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SlidingMenu);
 Float rightPadding = array.getDimension(
  R.styleable.SlidingMenu_rightPadding, dip2px(50));
 // Calculate the width of the menu = the width of the screen - customize the width left on the right
 mMenuWidth = (int) (getScreenWidth() - rightPadding);
 Array.recycle();
 
 // instantiate gesture handling class
 mGestureDetector = new GestureDetector(context,new GestureListener());
 }
 
 /**
 * Convert dip to pixels
 */
 Private float dip2px(int dip) {
 Return TypedValue.applyDimension(
  TypedValue.COMPLEX_UNIT_DIP, dip, getResources().getDisplayMetrics());
 }
 
 
 @Override
 Protected void onFinishInflate() {
 super.onFinishInflate();
 
 / / 1. Get the root View is also the outer LinearLayout
 ViewGroup container = (ViewGroup) this.getChildAt(0);
 
 Int containerChildCount = container.getChildCount();
 If (containerChildCount > 2) {
  // Only two layouts are allowed inside. One is Menu (menu layout) One is Content (home content layout)
  Throw new IllegalStateException("SlidingMenu root layout allows only two layouts under the LinearLayout, menu layout and home page content layout");
 }
 
 // 2. Get menu and content layout
 mMenuView = container.getChildAt(0);
 mContentView = container.getChildAt(1);
 
 // 3. Specify the width of the content and menu layout
 // 3.1 The width of the menu = the width of the screen - the width left on the right side of the custom
 mMenuView.getLayoutParams().width = mMenuWidth;
 // 3.2 width of the content = width of the screen
 mContentView.getLayoutParams().width = getScreenWidth();
 }
 
 @Override
 Public boolean onTouchEvent(MotionEvent ev) {
 
 / / Handle fingers to quickly slide
 If(mGestureDetector.onTouchEvent(ev)){
  Return mGestureDetector.onTouchEvent(ev);
 }
 
 Switch (ev.getAction()) {
  Case MotionEvent.ACTION_UP:
  // Lift your finger to get the scroll position
  Int currentScrollX = getScrollX();
  If (currentScrollX > mMenuWidth / 2) {
   // close the menu
   closeMenu();
  } else {
   // open the menu
   openMenu();
  }
  Return false;
 }
 Return super.onTouchEvent(ev);
 }
 
 /**
 * Open the menu
 */
 Private void openMenu() {
 smoothScrollTo(0, 0);
 mMenuIsOpen = true;
 }
 
 /**
 * Close menu
 */
 Private void closeMenu() {
 smoothScrollTo(mMenuWidth, 0);
 mMenuIsOpen = false;
 }
 
 @Override
 Protected void onLayout(boolean changed, int l, int t, int r, int b) {
 super.onLayout(changed, l, t, r, b);
 // After the layout is specified, the sub-layout will be placed newly, and when it is placed, the menu will be scrolled to the invisible state.
 If (changed) {
  scrollTo(mMenuWidth, 0);
 }
 }
 
 /**
 * Get the width of the screen
 */
 Public int getScreenWidth() {
 Resources resources = this.getResources();
 DisplayMetrics dm = resources.getDisplayMetrics();
 Return dm.widthPixels;
 }
 
 
 Private class GestureListener extends GestureDetector.SimpleOnGestureListener{
 @Override
 Public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
  // The method of callback when the finger swipes quickly
  Log.e("TAG",velocityX+"");
  // If the menu is open and swipe to the left to toggle the state of the menu
  If(mMenuIsOpen){
  If(velocityX<-500){
   toggleMenu();
   Return true;
  }
  }else{
  // If the menu is closed and swipe right, toggle the state of the menu
  If(velocityX>500){
   toggleMenu();
   Return true;
  }
  }
 
  Return false;
 }
 }
 
 /**
 * Switch the status of the menu
 */
 Private void toggleMenu() {
 If(mMenuIsOpen){
  closeMenu();
 }else{
  openMenu();
 }
 }
}


After this step we can switch the menu, and handle the quick slide of the fingers, can't wait to see the effect

2.6. Implementation of the menu to the left drawer style animation effect, monitoring the method of scrolling callback onscrollchanged () This is very simple a word will be done, the effect is not seen together to see the ultimate effect bar


@Override
 protected void onscrollchanged (int l, int t, int oldl, int Oldt) {
 super.onscrollchanged (L, T, OLDL, old t);

 L is the current scrolling x distance in the scrolling time will be repeatedly callback this method
 log.e (tag,l+ "");

 Mmenuview.settranslationx (l*0.8f);
 }


2.7. Implementation of the menu to the right menu shadow transparency effect, this plan in the main Page content layout above add a layer of shadow, with ImageView can, then our content view will need to change






/**
 * description:
 * Customized view of QQ5.0 main page sliding
 * Created by Zeng Hui on 2016/11/1.
 * QQ: 240336124
 * Email: 240336124@qq.com
 * Version: 1.0
 */
Public class SlidingMenu extends HorizontalScrollView {
 Private static final String TAG = "HorizontalScrollView";  Private Context mContext;
 
 // 4. Specify the width and height for the menu and content View - left menu View
 Private view mMenuView;
 
 // 4. Specify the width and height of the menu and content View - the width of the menu
 Private int mMenuWidth;
 // 5.3 gesture processing class is mainly used to handle gestures and swipe
 Private GestureDetector mGestureDetector;
 // 5.3 Is the menu open?
 Private boolean mMenuIsOpen = false;
 
 // 7(4). The layout of the main page content View includes the shadow ImageView
 Private ViewGroup mContentView;
 // 7. Add a shadow effect to the content - Shadow ImageView
 Private ImageView mShadowIv;
 
 Public SlidingMenu(Context context) {
 This(context, null);
 }
 
 Public SlidingMenu(Context context, AttributeSet attrs) {
 This(context, attrs, 0);
 }
 
 Public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
 Super(context, attrs, defStyleAttr);
 //4.1 Calculate the width of the left menu
 //4.1.1 Get the width left by the custom right side
 TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SlidingMenu);
 Float rightPadding = array.getDimension(
  R.styleable.SlidingMenu_rightPadding, dip2px(50));
 // 4.1.2 Calculate the width of the menu = the width of the screen - the width left by the custom right
 mMenuWidth = (int) (getScreenWidth() - rightPadding);
 Array.recycle();
 
 // 5.3 instantiating gesture handling class
 mGestureDetector = new GestureDetector(context,new GestureListener());
 
 this.mContext = context;
 }
 
 /**
 * Convert dip to pixels
 */
 Private float dip2px(int dip) {
 Return TypedValue.applyDimension(
  TypedValue.COMPLEX_UNIT_DIP, dip, getResources().getDisplayMetrics());
 }
 
 
 @Override
 Protected void onFinishInflate() {
 super.onFinishInflate();
 // 4.2 Specify the width of the menu and content View
 // 4.2.1. Getting the root View is the outer LinearLayout
 ViewGroup container = (ViewGroup) this.getChildAt(0);
 
 Int containerChildCount = container.getChildCount();
 If (containerChildCount > 2) {
  // Only two layouts are allowed inside. One is Menu (menu layout) One is Content (home content layout)
  Throw new IllegalStateException("SlidingMenu root layout allows only two layouts under the LinearLayout, menu layout and home page content layout");
 }
 
 // 4.2.2. Get menu and content layout
 mMenuView = container.getChildAt(0);
 
 // 7. Add a shadow effect to the content
 // 7.1 First, a new main content layout is used to put the shadow and the original layout of the LinearLayout.
 mContentView = new FrameLayout(mContext);
 ViewGroup.LayoutParams contentParams = new ViewGroup.LayoutParams(
  ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
 
 // 7.2 Get the original content layout and make the original content layout from the LinearLayout exception
 View oldContentView = container.getChildAt(1);
 container.removeView(oldContentView);
 
 // 7.3 Add the original content View and shadow to our newly created content layout
 mContentView.addView(oldContentView);
 // 7.3.1 Creating a shadow ImageView
 mShadowIv = new ImageView(mContext);
 mShadowIv.setBackgroundColor(Color.parseColor("#99000000"));
 mContentView.addView(mShadowIv);
 
 // 7.4 Add a new content view containing shadows to the LinearLayout
 container.addView(mContentView);
 
 // 4.2.3. Specify the width of the content and menu layout
 // 4.2.3.1 The width of the menu = the width of the screen - the width left on the right side of the custom
 mMenuView.getLayoutParams().width = mMenuWidth;
 // 4.2.3.2 Width of content = width of the screen
 mContentView.getLayoutParams().width = getScreenWidth();
 }
 
 /**
 * 5. Handle finger lift and swipe to switch menu
 */
 @Override
 Public boolean onTouchEvent(MotionEvent ev) {
 // 5.3 handle finger swipe
 If(mGestureDetector.onTouchEvent(ev)){
  Return mGestureDetector.onTouchEvent(ev);
 }
 
 Switch (ev.getAction()) {
  Case MotionEvent.ACTION_UP:
  // 5.1 Finger lifts to get the position of the scroll
  Int currentScrollX = getScrollX();
  If (currentScrollX > mMenuWidth / 2) {
   // 5.1.1 Close menu
   closeMenu();
  } else {
   // 5.1.2 Open the menu
   openMenu();
  }
  Return false;
 }
 Return super.onTouchEvent(ev);
 }
 
 @Override
 Protected void onScrollChanged(int l, int t, int oldl, int oldt) {
 super.onScrollChanged(l, t, oldl, oldt);
 
 // l is the current scrolling x distance. This method is repeated repeatedly when scrolling.
 Log.e(TAG,l+"");
 // 6. Animate the drawer style on the left side of the menu
 mMenuView.setTranslationX(l*0.8f);
 
 // 7. Add a shadow to the content - Calculate the gradient value
 Float gradientValue = l * 1f / mMenuWidth;// This is the value of 1 - 0 change
 
 // 7. Add a shadow effect to the content - Specify a transparency for the shaded View 0 - 1 Changed value
 Float shadowAlpha = 1 - gradientValue;
 mShadowIv.setAlpha(shadowAlpha);
 }
 
 /**
 * 5.1.2 Open menu
 */
 Private void openMenu() {
 smoothScrollTo(0, 0);
 mMenuIsOpen = true;
 }
 
 /**
 * 5.1.1 Close menu
 */
 Private void closeMenu() {
 smoothScrollTo(mMenuWidth, 0);
 mMenuIsOpen = false;
 }
 
 @Override
 Protected void onLayout(boolean changed, int l, int t, int r, int b) {
 super.onLayout(changed, l, t, r, b);
 // After the layout is specified, the sub-layout will be placed newly, and when it is placed, the menu will be scrolled to the invisible state.
 If (changed) {
  scrollTo(mMenuWidth, 0);
 }
 }
 
 /**
 * Get the width of the screen
 */
 Public int getScreenWidth() {
 Resources resources = this.getResources();
 DisplayMetrics dm = resources.getDisplayMetrics();
 Return dm.widthPixels;
 }
 
 
 /**
 * 5.3 Handling fingers for quick swipe
 */
 Private class GestureListener extends GestureDetector.SimpleOnGestureListener{
 @Override
 Public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
  // The method of callback when the finger swipes quickly
  Log.e(TAG,velocityX+"");
  // 5.3.1 If the menu is open and is swiping left, toggle the state of the menu
  If(mMenuIsOpen){
  If(velocityX<0){
   toggleMenu();
   Return true;
  }
  }else{
  // 5.3.2 If the menu is closed and swipe right, toggle the state of the menu
  If(velocityX>0){
   toggleMenu();
   Return true;
  }
  }
  Return false;
 }
 }
 
 /**
 * Switch the status of the menu
 */
 Private void toggleMenu() {
 If(mMenuIsOpen){
   closeMenu();
  }else{
   openMenu();
  }
  }
}

Let's take a look at the final results, the final code is not much, the need to download the source, if it is to achieve QQ5.0 or cool dog sideslip effect can be changed.






The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.