The Sliding Menu navigation drawer is a list “ListView” of options on the left
edge of the screen. It is hidden most of the time, but is revealed
when the user swipes a finger from the left edge of the screen or,
the user touches the app icon in the action bar.
Using this code
1. Add this SlidingMenuLayout into activity_main.xml with proper package name and class name
activity_main.xml
<com.example.navigation_listview.utills.SlidingMenuLayout
xmlns:android="http://schemas.android.com/apk/res/android"
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="288dp"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000" >
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</RelativeLayout>
</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 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/padding_50"
android:background="#0174DF"
android:orientation="horizontal" >
<Button
android:id="@+id/button_menu"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentLeft="true"
android:layout_centerInParent="true"
android:layout_marginLeft="4dp"
android:background="@drawable/slide_menu_icon"
android:onClick="toggleMenu" />
<TextView
android:id="@+id/lk_profile_header_textview"
android:layout_width="match_parent"
android:layout_height="@dimen/padding_50"
android:layout_centerInParent="true"
android:gravity="center"
android:padding="@dimen/padding_10"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@color/white"
android:textSize="@dimen/text_size_20"
android:textStyle="bold"
android:text="Navigation Drawer"
/>
</RelativeLayout>
<!-- This is where fragment will show up -->
<FrameLayout
android:id="@+id/lk_profile_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white" >
</FrameLayout>
</LinearLayout>
</com.example.navigation_listview.utills.SlidingMenuLayout>
2. This Sliding Navigation is different from android inbuild navigation drawer
Use SlidingMenuLayout.java class for navigation drawer like Facebook Sliding Navigation.
SlidingMenuLayout.java
package com.example.navigation_listview.utills;
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 SlidingMenuLayout 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 = 50;
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 SlidingMenuLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SlidingMenuLayout(Context context) {
super(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mainLayoutWidth = MeasureSpec.getSize(widthMeasureSpec);
menuRightMargin = mainLayoutWidth * 15 / 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 SlidingMenuLayout.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;
}
}
3. Finally in MainActivity
MainActivity.java
//Sliding icon
//Fragment
package com.example.navigation_listview;
import java.util.ArrayList;
import com.example.navigation_listview.utills.SlidingMenuLayout;
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.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
public class MainActivity extends FragmentActivity {
ListView Listview;
static SlidingMenuLayout slidingmenu_layout;
Context context;
Button lk_profile_menu,lk_profile_filter_btn;
ArrayList<String> values=new ArrayList<String>();
String[] nearby_values={"Theaters","Restaurants","Cafe","ATM","Shopping Malls","Railway stations","Taxi stands","Gas_station","Banks","Hospitals","Pharmacy","Bar","Parks","Gym"};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
slidingmenu_layout = (SlidingMenuLayout) this.getLayoutInflater().inflate(
R.layout.activity_main, null);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(slidingmenu_layout);
context=this;
//Declare first called activity name
//Declare first called activity name
StartProfileActivity fragment = new StartProfileActivity();
start_fragment(fragment);
//Sliding icon
lk_profile_menu = (Button) findViewById(R.id.button_menu);
lk_profile_menu.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Show/hide the menu
Listview.smoothScrollToPosition(0);
toggleMenu(v);
}
});
Listview=(ListView)findViewById(R.id.list);
Listview.setDividerHeight(2);
Listview.setClickable(true);
Listview.setBackgroundColor(Color.GRAY);
ListAdapter adapter = new ListAdapter(context,nearby_values);
Listview.setAdapter(adapter);
}
public static void toggleMenu(View v)
{
{
slidingmenu_layout.toggleMenu();
}
//Fragment
private void start_fragment(Fragment frag){
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.lk_profile_fragment, frag);
fragmentTransaction.commit();
}
}
4. ListAdapter
slidingmenu listview values and designs
ListAdaper.java
package com.example.navigation_listview;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class ListAdapter extends BaseAdapter {
Context context;
String[] value;
LayoutInflater inflater;
public ListAdapter(Context context, String[] values) {
this.context = context;
this.value = values;
}
@Override
public int getCount() {
return value.length;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@SuppressLint("ViewHolder")
public View getView(int position, View convertView, ViewGroup parent) {
TextView txtNearby;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.list_item, parent, false);
txtNearby = (TextView) itemView.findViewById(R.id.title);
txtNearby.setText(value[position]);
return itemView;
}
}
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:background="@drawable/actionbar_style"
android:padding="5dp" >
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_margin="10dp"
android:layout_weight="1"
android:textColor="#FFFFFF"
android:textSize="15dp"
android:text="aaa"/>
</LinearLayout>
6.StartProfileActivity is the main screen for this application
StartProfileActivity.java
StartProfileActivity.java
package com.example.navigation_listview;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class StartProfileActivity extends Fragment{
static View view;
Context context;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
view = inflater.inflate(R.layout.activity_startprofile, null);
context=this.getActivity();
return view;
}
}
activity_startprofile.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="@drawable/lollipop"
android:orientation="vertical" >
</RelativeLayout>
5 comments
Write commentsHi Rajendran,
ReplyThanks For the nice tutorial, but i have found one issue, when we try to swipe the screen instead of clicking on the menu button and drag the screen till other end of the screen , screen goes to its position back.
Kindly let me know is there a fix.
Thanks & Regards.
Nagendra.
Hi,
ReplyVery simple Tutorial..Thanks for sharing your knowledge.I just have one query ,this
example is not supporting on gingerbread..I mean there is a minor space above my layout..i trying to fix by giving windows featur no title ..its not working in my case..So if there is any other wayto fix it please let me know...
Thanks You..
Hi
ReplyThanks for nice tutorial.
I stuck somewhere while implementing this.
I want to reduce the width of sliding menu.
Maybe I am so late, But hoping you will reply soon.
Thanks.
Hi
ReplyThanks for Sharing your knowledge .
Actually i successfully executed the Project .
I just need a little help from you as am stuck in the "SlidingMenuLayout" class.
I need is when i click on "lk_profile_menu" , toggle menu(v); is executing. All i need is to make the sliding screen appears half of the screen when i swipes from left to right.
Hi
ReplyThanks for sharing your knowledge.
Your tutorial is very useful and i successfully implemented it.
I need a little favour from you as on clicking the "lk_profile_menu" , "togglemenu(v)" is excuting which is in the "SlidingMenuLayout "
All i need is when we onclicking the menu button the listview should be appear half of the screen rather than sliding entire end of the screen .
Thanks and Regards.
EmoticonEmoticon