But if you would like to make a Sliding Menu like Facebook, you must use third-party library. Now a days most of the android application uses this sliding menu style, which must include Youtube, Facebook, LinkedIn,...
Today I am going to explain how to make this sliding menu type in an android application.
1. Download and import project
SlidingMenu is a famous project in Android. You can download it from @Github. This library required ActionBarSherlock, so you must download it from actionbarsherlock.com, too.1. Download and import project
After that, import 2 libraries to Android Studio project, it will become 2 modules called "library" and "actionbarsherlock".
NOTE: More details about importing Eclipse project to Android Studio module, you can see my previous post.
After done, you will see your
app/build.gradle
like this:
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.blogspot.hongthaiit.slidemenu"
minSdkVersion 14
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:22.0.0'
compile project(':library')
compile project(':actionbarsherlock')
}
2. Coding project core
Make a simple activity layout (only a 2. Coding project core
FrameLayout
as root):
activity_slide.xml
In activity programmatically code, we set some properties for Sliding Menu at <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
onCreate()
method (this activity must extends SlidingActivity
or SlidingFragmentActivity
):
SlidingActivity.java
Now, we'll create the menu layout (called
package com.blogspot.hongthaiit.slidemenu;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.Fragment;
import android.view.MenuItem;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;
import com.jeremyfeinstein.slidingmenu.lib.app.SlidingFragmentActivity;
public class SlidingActivity extends SlidingFragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sliding);
//set menu view for sliding menu in this activity
setBehindView();
// customize the SlidingMenu
SlidingMenu sm = getSlidingMenu();
sm.setShadowWidthRes(R.dimen.shadow_width);
sm.setShadowDrawable(R.drawable.shadow);
sm.setBehindOffsetRes(R.dimen.slidingmenu_offset);
sm.setFadeDegree(0.35f);
sm.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
getActionBar().setIcon(R.mipmap.menu);
getActionBar().setHomeButtonEnabled(true);
}
private void setBehindView() {
setBehindContentView(R.layout.menu_slide);
//transaction fragment to sliding menu
transactionFragments(MenuFragment.newInstance(), R.id.menu_slide);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
toggle();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Replace fragment by fragment transaction
* @param fragment
* @param viewResource
*/
public void transactionFragments(Fragment fragment, int viewResource) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(viewResource, fragment);
ft.commit();
toggle();
}
}
BehindView
of Sliding Menu). Designing a simple layout has only a container layout (FrameLayout
):
menu_slide.xml
In this menu layout, we replace a <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/menu_slide"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
Fragment
which contains a ListView
(you may using ListFragment
directly). Layout (xml file) for this fragment:
fragment_menu.xml
Customizing a <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
</ListView>
</FrameLayout>
ListView
adapter with data in programmatically code like this:
MenuFragment.java
As you can see in
package com.blogspot.hongthaiit.slidemenu;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class MenuFragment extends Fragment {
private View rootView;
private ListView listView;
private ArrayList<SlidingMenuItem> listMenuItems;
private final static String TAG = "MenuFragment";
public static Fragment newInstance() {
MenuFragment fragment = new MenuFragment();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//create menu items
listMenuItems = new ArrayList<SlidingMenuItem>();
listMenuItems.add(new SlidingMenuItem(R.mipmap.mercury, "Mecury"));
listMenuItems.add(new SlidingMenuItem(R.mipmap.venus, "Venus"));
listMenuItems.add(new SlidingMenuItem(R.mipmap.earth, "Earth"));
listMenuItems.add(new SlidingMenuItem(R.mipmap.mars, "Mars"));
listMenuItems.add(new SlidingMenuItem(R.mipmap.jupiter, "Jupiter"));
listMenuItems.add(new SlidingMenuItem(R.mipmap.saturn, "Saturn"));
listMenuItems.add(new SlidingMenuItem(R.mipmap.uranus, "Uranus"));
listMenuItems.add(new SlidingMenuItem(R.mipmap.neptune, "Neptune"));
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_menu, container, false);
listView = (ListView) rootView.findViewById(R.id.list);
return rootView;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setListViewAdapter();
}
private void setListViewAdapter() {
SlidingMenuAdapter adapter = new SlidingMenuAdapter(getActivity(), R.layout.item_menu, listMenuItems);
listView.setAdapter(adapter);
listView.setOnItemClickListener(onItemClickListener());
Log.i(TAG, "create adapter " + listMenuItems.size());
}
/**
* Go to fragment when menu item clicked!
*
* @return
*/
private AdapterView.OnItemClickListener onItemClickListener() {
return new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
SlidingMenuItem item = (SlidingMenuItem) parent.getItemAtPosition(position);
((SlidingActivity) getActivity()).transactionFragments(PageFragment.newInstance(item.getMenuItemName()),
R.id.container);
}
};
}
/**
* private class to make a listview adapter based on ArrayAdapter
*/
private class SlidingMenuAdapter extends ArrayAdapter<SlidingMenuItem> {
private FragmentActivity activity;
private ArrayList<SlidingMenuItem> items;
public SlidingMenuAdapter(FragmentActivity activity, int resource, ArrayList<SlidingMenuItem> objects) {
super(activity, resource, objects);
this.activity = activity;
this.items = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
// If holder not exist then locate all view from UI file.
if (convertView == null) {
// inflate UI from XML file
convertView = inflater.inflate(R.layout.item_menu, parent, false);
// get all UI view
holder = new ViewHolder(convertView);
// set tag for holder
convertView.setTag(holder);
} else {
// if holder created, get tag from view
holder = (ViewHolder) convertView.getTag();
}
holder.itemName.setText(getItem(position).getMenuItemName());
holder.itemImage.setImageResource(getItem(position).getImageResource());
return convertView;
}
private class ViewHolder {
private TextView itemName;
private ImageView itemImage;
public ViewHolder(View v) {
itemName = (TextView) v.findViewById(R.id.name);
itemImage = (ImageView) v.findViewById(R.id.image);
}
}
}
}
MenuFragment
code, when click at each ListView
row (item) in menu, app will replace a Fragment
to our SlidingActivity
above. Here is source code of PageFragment
:
PageFragment.java
And it's layout:
package com.blogspot.hongthaiit.slidemenu;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class PageFragment extends Fragment {
private static final String TAG = "PageFragment";
private String fragmentName;
private View root;
public static PageFragment newInstance(String fragmentName) {
PageFragment fragment = new PageFragment();
Bundle args = new Bundle();
args.putString("fragment_name", fragmentName);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
fragmentName = getArguments().getString("fragment_name");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
root = inflater.inflate(R.layout.fragment_page, container, false);
//locate view element and setting data
TextView textView = (TextView)root.findViewById(R.id.fragment_name);
textView.setText(fragmentName);
return root;
}
}
fragment_page.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:background="@android:color/holo_green_dark"
android:layout_height="match_parent">
<TextView
android:id="@+id/fragment_name"
android:layout_width="match_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@android:color/holo_red_dark"
android:layout_height="wrap_content" />
</RelativeLayout>
3. Some more necessary files
ListView
row):
item_menu.xml
- Setting Sliding Menu <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="30"
android:contentDescription="@string/app_name" />
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="70"
android:gravity="center"/>
</LinearLayout>
ShadowDrawable
in SlidingActivity
with this layout:
shadow.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<gradient
android:endColor="#33000000"
android:centerColor="#11000000"
android:startColor="#ffffff" />
</shape>