As of now we know that sliding menu is a simple dragging menu from any one side. This post will help you to create a simple sliding menu in Android.
Here sliding menu is a listview which is in INVISIBLE state. It will comes to VISIBLE state once you click the menu button. And it will go to INVISIBLE state again once you pick the item from listview. To change the state we are using animation, that is why it looks like sliding.
Complete code:
MainActivity.java
MainLayout.java
Layout1.java
Layout2.java
activity_main.xml
fragment_layout1.xml
fragment_layout2.xml
rec/values/menu_items.xml
Complete project on GITHUB
Here sliding menu is a listview which is in INVISIBLE state. It will comes to VISIBLE state once you click the menu button. And it will go to INVISIBLE state again once you pick the item from listview. To change the state we are using animation, that is why it looks like sliding.
Complete code:
MainActivity.java
- package com.android.slidingmenuexample;
- import android.os.Bundle;
- import android.support.v4.app.Fragment;
- import android.support.v4.app.FragmentActivity;
- import android.support.v4.app.FragmentManager;
- import android.support.v4.app.FragmentTransaction;
- import android.view.Menu;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.AdapterView;
- import android.widget.ArrayAdapter;
- import android.widget.Button;
- import android.widget.ListView;
- import android.widget.AdapterView.OnItemClickListener;
- import android.widget.TextView;
- public class MainActivity extends FragmentActivity {
- MainLayout mLayout;
- private ListView lvMenu;
- private String[] lvMenuItems;
- Button btMenu;
- TextView tvTitle;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mLayout = (MainLayout) this.getLayoutInflater().inflate(
- R.layout.activity_main, null);
- setContentView(mLayout);
- lvMenuItems = getResources().getStringArray(R.array.menu_items);
- lvMenu = (ListView) findViewById(R.id.menu_listview);
- lvMenu.setAdapter(new ArrayAdapter<String>(this,
- android.R.layout.simple_list_item_1, lvMenuItems));
- lvMenu.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view,
- int position, long id) {
- onMenuItemClick(parent, view, position, id);
- }
- });
- btMenu = (Button) findViewById(R.id.button_menu);
- btMenu.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // Show/hide the menu
- toggleMenu(v);
- }
- });
- tvTitle = (TextView) findViewById(R.id.activity_main_content_title);
- FragmentManager fm = MainActivity.this.getSupportFragmentManager();
- FragmentTransaction ft = fm.beginTransaction();
- Layout1 fragment = new Layout1();
- ft.add(R.id.activity_main_content_fragment, fragment);
- ft.commit();
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- public void toggleMenu(View v) {
- mLayout.toggleMenu();
- }
- private void onMenuItemClick(AdapterView<?> parent, View view,
- int position, long id) {
- String selectedItem = lvMenuItems[position];
- String currentItem = tvTitle.getText().toString();
- if (selectedItem.compareTo(currentItem) == 0) {
- mLayout.toggleMenu();
- return;
- }
- FragmentManager fm = MainActivity.this.getSupportFragmentManager();
- FragmentTransaction ft = fm.beginTransaction();
- Fragment fragment = null;
- if (selectedItem.compareTo("Layout 1") == 0) {
- fragment = new Layout1();
- } else if (selectedItem.compareTo("Layout 2") == 0) {
- fragment = new Layout2();
- }
- if (fragment != null) {
- ft.replace(R.id.activity_main_content_fragment, fragment);
- ft.commit();
- tvTitle.setText(selectedItem);
- }
- mLayout.toggleMenu();
- }
- @Override
- public void onBackPressed() {
- if (mLayout.isMenuShown()) {
- mLayout.toggleMenu();
- } else {
- super.onBackPressed();
- }
- }
- }
MainLayout.java
- package com.android.slidingmenuexample;
- import android.content.Context;
- import android.os.Handler;
- import android.util.AttributeSet;
- import android.util.Log;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.animation.Interpolator;
- import android.widget.LinearLayout;
- import android.widget.Scroller;
- public class MainLayout extends LinearLayout {
- private static final int SLIDING_DURATION = 500;
- private static final int QUERY_INTERVAL = 16;
- int mainLayoutWidth;
- private View menu;
- private View content;
- private static int menuRightMargin = 15;
- private enum MenuState {
- HIDING, HIDDEN, SHOWING, SHOWN,
- };
- private int contentXOffset;
- private MenuState currentMenuState = MenuState.HIDDEN;
- private Scroller menuScroller = new Scroller(this.getContext(),
- new EaseInInterpolator());
- private Runnable menuRunnable = new MenuRunnable();
- private Handler menuHandler = new Handler();
- int prevX = 0;
- boolean isDragging = false;
- int lastDiffX = 0;
- public MainLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public MainLayout(Context context) {
- super(context);
- }
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- mainLayoutWidth = MeasureSpec.getSize(widthMeasureSpec);
- menuRightMargin = mainLayoutWidth * 10 / 100;
- }
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- menu = this.getChildAt(0);
- content = this.getChildAt(1);
- content.setOnTouchListener(new OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- return MainLayout.this.onContentTouch(v, event);
- }
- });
- menu.setVisibility(View.GONE);
- }
- @Override
- protected void onLayout(boolean changed, int left, int top, int right,
- int bottom) {
- if (changed) {
- LayoutParams contentLayoutParams = (LayoutParams) content
- .getLayoutParams();
- contentLayoutParams.height = this.getHeight();
- contentLayoutParams.width = this.getWidth();
- LayoutParams menuLayoutParams = (LayoutParams) menu
- .getLayoutParams();
- menuLayoutParams.height = this.getHeight();
- menuLayoutParams.width = this.getWidth() - menuRightMargin;
- }
- menu.layout(left, top, right - menuRightMargin, bottom);
- content.layout(left + contentXOffset, top, right + contentXOffset,
- bottom);
- }
- public void toggleMenu() {
- if (currentMenuState == MenuState.HIDING
- || currentMenuState == MenuState.SHOWING)
- return;
- switch (currentMenuState) {
- case HIDDEN:
- currentMenuState = MenuState.SHOWING;
- menu.setVisibility(View.VISIBLE);
- menuScroller.startScroll(0, 0, menu.getLayoutParams().width, 0,
- SLIDING_DURATION);
- break;
- case SHOWN:
- currentMenuState = MenuState.HIDING;
- menuScroller.startScroll(contentXOffset, 0, -contentXOffset, 0,
- SLIDING_DURATION);
- break;
- default:
- break;
- }
- menuHandler.postDelayed(menuRunnable, QUERY_INTERVAL);
- this.invalidate();
- }
- protected class MenuRunnable implements Runnable {
- @Override
- public void run() {
- boolean isScrolling = menuScroller.computeScrollOffset();
- adjustContentPosition(isScrolling);
- }
- }
- private void adjustContentPosition(boolean isScrolling) {
- int scrollerXOffset = menuScroller.getCurrX();
- content.offsetLeftAndRight(scrollerXOffset - contentXOffset);
- contentXOffset = scrollerXOffset;
- this.invalidate();
- if (isScrolling)
- menuHandler.postDelayed(menuRunnable, QUERY_INTERVAL);
- else
- this.onMenuSlidingComplete();
- }
- private void onMenuSlidingComplete() {
- switch (currentMenuState) {
- case SHOWING:
- currentMenuState = MenuState.SHOWN;
- break;
- case HIDING:
- currentMenuState = MenuState.HIDDEN;
- menu.setVisibility(View.GONE);
- break;
- default:
- return;
- }
- }
- protected class EaseInInterpolator implements Interpolator {
- @Override
- public float getInterpolation(float t) {
- return (float) Math.pow(t - 1, 5) + 1;
- }
- }
- public boolean isMenuShown() {
- return currentMenuState == MenuState.SHOWN;
- }
- public boolean onContentTouch(View v, MotionEvent event) {
- if (currentMenuState == MenuState.HIDING
- || currentMenuState == MenuState.SHOWING)
- return false;
- int curX = (int) event.getRawX();
- int diffX = 0;
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- prevX = curX;
- return true;
- case MotionEvent.ACTION_MOVE:
- if (!isDragging) {
- isDragging = true;
- menu.setVisibility(View.VISIBLE);
- }
- diffX = curX - prevX;
- if (contentXOffset + diffX <= 0) {
- diffX = -contentXOffset;
- } else if (contentXOffset + diffX > mainLayoutWidth
- - menuRightMargin) {
- diffX = mainLayoutWidth - menuRightMargin - contentXOffset;
- }
- content.offsetLeftAndRight(diffX);
- contentXOffset += diffX;
- this.invalidate();
- prevX = curX;
- lastDiffX = diffX;
- return true;
- case MotionEvent.ACTION_UP:
- Log.d("MainLayout.java onContentTouch()", "Up lastDiffX "
- + lastDiffX);
- if (lastDiffX > 0) {
- currentMenuState = MenuState.SHOWING;
- menuScroller.startScroll(contentXOffset, 0,
- menu.getLayoutParams().width - contentXOffset, 0,
- SLIDING_DURATION);
- } else if (lastDiffX < 0) {
- currentMenuState = MenuState.HIDING;
- menuScroller.startScroll(contentXOffset, 0, -contentXOffset, 0,
- SLIDING_DURATION);
- }
- menuHandler.postDelayed(menuRunnable, QUERY_INTERVAL);
- this.invalidate();
- isDragging = false;
- prevX = 0;
- lastDiffX = 0;
- return true;
- default:
- break;
- }
- return false;
- }
- }
Layout1.java
- package com.android.slidingmenuexample;
- import android.os.Bundle;
- import android.support.v4.app.Fragment;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- public class Layout1 extends Fragment {
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.fragment_layout1, null);
- return view;
- }
- }
Layout2.java
- package com.android.slidingmenuexample;
- import android.os.Bundle;
- import android.support.v4.app.Fragment;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- public class Layout2 extends Fragment {
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.fragment_layout2, null);
- return view;
- }
- }
activity_main.xml
- <com.android.slidingmenuexample.MainLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <ListView
- android:id="@+id/menu_listview"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:background="@android:color/holo_purple"
- android:cacheColorHint="#00000000" >
- </ListView>
- </LinearLayout>
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <!-- This acts as Actionbar -->
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@android:color/darker_gray"
- android:orientation="horizontal" >
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:onClick="toggleMenu"
- android:text="Menu"
- android:id="@+id/button_menu" />
- <TextView
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:text="Layout 1"
- android:gravity="center"
- android:id="@+id/activity_main_content_title"
- android:layout_weight="1" />
- </LinearLayout>
- <!-- This is where fragment will show up -->
- <FrameLayout
- android:id="@+id/activity_main_content_fragment"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- </FrameLayout>
- </LinearLayout>
- </com.android.slidingmenuexample.MainLayout>
fragment_layout1.xml
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@android:color/holo_blue_dark" >
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true"
- android:gravity="center"
- android:text="Layout 1"
- android:textColor="@android:color/black"
- android:textSize="20sp" />
- </RelativeLayout>
fragment_layout2.xml
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@android:color/holo_green_dark"
- android:orientation="vertical" >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true"
- android:text="Layout2"
- android:textColor="@android:color/black"
- android:textSize="20sp" />
- </RelativeLayout>
rec/values/menu_items.xml
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <string-array name="menu_items">
- <item >Layout 1</item>
- <item >Layout 2</item>
- </string-array>
- </resources>
Complete project on GITHUB
No comments:
Post a Comment