效果图:
主activity:
public class MenuActivity extends Activity implements View.OnClickListener{
private ResideMenu resideMenu;
private MenuActivity mContext;
public static void startActivity(Context context) {
Intent intent = new Intent();
intent.setClass(context,MenuActivity.class);
context.startActivity(intent);
}
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu_activity);
mContext = this;
setUpViews();
setUpMenu();
}
private void setUpMenu() {
// attach to current activity;
resideMenu = new ResideMenu(this);
resideMenu.setBackground(R.drawable.menu_background);
resideMenu.attachToActivity(this);
resideMenu.setMenuListener(menuListener);
// create menu items;
String titles[] = { "Home", "Profile", "Calendar", "Settings" };
int icon[] = { R.drawable.icon_home, R.drawable.icon_profile, R.drawable.icon_calendar, R.drawable.icon_settings };
for (int i = 0; i < titles.length; i++){
ResideMenuItem item = new ResideMenuItem(this, icon[i], titles[i]);
item.setOnClickListener(this);
resideMenu.addMenuItem(item);
}
// add gesture operation's ignored views
FrameLayout ignored_view = (FrameLayout) findViewById(R.id.ignored_view);
resideMenu.addIgnoredView(ignored_view);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return resideMenu.onInterceptTouchEvent(ev) || super.dispatchTouchEvent(ev);
}
private void setUpViews() {
Button btn_open = (Button) findViewById(R.id.btn_open_menu);
btn_open.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
resideMenu.openMenu();
}
});
}
@Override
public void onClick(View view) {
resideMenu.closeMenu();
}
private ResideMenu.OnMenuListener menuListener = new ResideMenu.OnMenuListener() {
@Override
public void openMenu() {
Toast.makeText(mContext, "Menu is opened!", Toast.LENGTH_SHORT).show();
}
@Override
public void closeMenu() {
Toast.makeText(mContext, "Menu is closed!", Toast.LENGTH_SHORT).show();
}
};
}xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@android:color/white" android:orientation="vertical"> <LinearLayout android:id="@+id/layout_top" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:orientation="vertical"> <ImageView android:layout_width="match_parent" android:layout_height="3dp" android:background="#2ea3fe"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:padding="7dp" android:text="RESideMenu DEMO" android:textColor="#999999" android:textSize="24sp"/> <ImageView android:layout_width="match_parent" android:layout_height="5dp" android:background="#ebebeb"/> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_above="@+id/ignored_view" android:layout_below="@+id/layout_top" android:gravity="center" android:orientation="vertical"> <ImageView android:id="@+id/imageView" android:layout_width="60dp" android:layout_height="120dp" android:layout_gravity="center" android:scaleType="fitCenter" android:class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="@drawable/gesture"/> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:clickable="false" android:padding="5dp" android:text=" 1. Swipe right to open menu" android:textColor="#ffacacac" android:textSize="17sp"/> <Button android:id="@+id/btn_open_menu" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="4dp" android:background="@drawable/button_selector" android:padding="12dp" android:text="2. Click me to open menu" android:textColor="@android:color/white" android:textSize="17sp"/> </LinearLayout> <FrameLayout android:id="@+id/ignored_view" android:layout_width="fill_parent" android:layout_height="120dp" android:layout_alignParentBottom="true" android:layout_gravity="bottom" android:orientation="vertical" android:padding="10dp"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="@drawable/frame"/> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:padding="5dp" android:text="This is an ignored view,you can’t use gesture to operate menu here." android:textColor="#9a9a9a" android:textSize="17sp"/> </FrameLayout> </RelativeLayout>
ResideMenu代码:
public class ResideMenu extends FrameLayout implements GestureDetector.OnGestureListener{
private ImageView iv_shadow;
private ImageView iv_background;
private LinearLayout layout_menu;
private ScrollView sv_menu;
private AnimatorSet scaleUp_shadow;
private AnimatorSet scaleUp_activity;
private AnimatorSet scaleDown_activity;
private AnimatorSet scaleDown_shadow;
/** the activity that view attach to */
private Activity activity;
/** the decorview of the activity */
private ViewGroup view_decor;
/** the viewgroup of the activity */
private ViewGroup view_activity;
/** the flag of menu open status */
private boolean isOpened;
private GestureDetector gestureDetector;
private float shadow_ScaleX;
/** the view which don't want to intercept touch event */
private List<View> ignoredViews;
private List<ResideMenuItem> menuItems;
private DisplayMetrics displayMetrics = new DisplayMetrics();
private OnMenuListener menuListener;
public ResideMenu(Context context) {
super(context);
initViews(context);
}
private void initViews(Context context){
LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.residemenu, this);
sv_menu = (ScrollView) findViewById(R.id.sv_menu);
iv_shadow = (ImageView) findViewById(R.id.iv_shadow);
layout_menu = (LinearLayout) findViewById(R.id.layout_menu);
iv_background = (ImageView) findViewById(R.id.iv_background);
}
/**
* use the method to set up the activity which residemenu need to show;
*
* @param activity
*/
public void attachToActivity(Activity activity){
initValue(activity);
setShadowScaleXByOrientation();
buildAnimationSet();
}
private void initValue(Activity activity){
this.activity = activity;
menuItems = new ArrayList<ResideMenuItem>();
gestureDetector = new GestureDetector(this);
ignoredViews = new ArrayList<View>();
view_decor = (ViewGroup)activity.getWindow().getDecorView();
view_activity = (ViewGroup) view_decor.getChildAt(0);
}
private void setShadowScaleXByOrientation(){
int orientation = getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
shadow_ScaleX = 0.5335f;
} else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
shadow_ScaleX = 0.56f;
}
}
/**
* set the menu background picture;
*
* @param imageResrouce
*/
public void setBackground(int imageResrouce){
iv_background.setImageResource(imageResrouce);
}
/**
* the visiblity of shadow under the activity view;
*
* @param isVisible
*/
public void setShadowVisible(boolean isVisible){
if (isVisible)
iv_shadow.setImageResource(R.drawable.shadow);
else
iv_shadow.setImageBitmap(null);
}
/**
* add a single items;
*
* @param menuItem
*/
public void addMenuItem(ResideMenuItem menuItem){
this.menuItems.add(menuItem);
}
/**
* set the menu items by array list;
*
* @param menuItems
*/
public void setMenuItems(List<ResideMenuItem> menuItems){
this.menuItems = menuItems;
}
public List<ResideMenuItem> getMenuItems() {
return menuItems;
}
/**
* if you need to do something on the action of closing or opening
* menu, set the listener here.
*
* @return
*/
public void setMenuListener(OnMenuListener menuListener) {
this.menuListener = menuListener;
}
public OnMenuListener getMenuListener() {
return menuListener;
}
/**
* we need the call the method before the menu show, because the
* padding of activity can't get at the moment of onCreateView();
*/
private void setViewPadding(){
this.setPadding(view_activity.getPaddingLeft(),
view_activity.getPaddingTop(),
view_activity.getPaddingRight(),
view_activity.getPaddingBottom());
}
/**
* show the reside menu;
*/
public void openMenu(){
if(!isOpened){
isOpened = true;
showOpenMenuRelative();
}
}
private void removeMenuLayout(){
ViewGroup parent = ((ViewGroup) sv_menu.getParent());
parent.removeView(sv_menu);
}
/**
* close the reslide menu;
*/
public void closeMenu(){
if(isOpened){
isOpened = false;
scaleUp_activity.start();
}
}
/**
* return the flag of menu status;
*
* @return
*/
public boolean isOpened() {
return isOpened;
}
/**
* call the method relative to open menu;
*/
private void showOpenMenuRelative(){
setViewPadding();
scaleDown_activity.start();
// remove self if has not remove
if (getParent() != null) view_decor.removeView(this);
if (sv_menu.getParent() != null) removeMenuLayout();
view_decor.addView(this, 0);
view_decor.addView(sv_menu);
}
private Animator.AnimatorListener animationListener = new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
if (isOpened){
layout_menu.removeAllViews();
showMenuDelay();
if (menuListener != null)
menuListener.openMenu();
}
}
@Override
public void onAnimationEnd(Animator animation) {
// reset the view;
if(!isOpened){
view_decor.removeView(ResideMenu.this);
view_decor.removeView(sv_menu);
if (menuListener != null)
menuListener.closeMenu();
}
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
};
private void showMenuDelay(){
layout_menu.removeAllViews();
for(int i = 0; i < menuItems.size() ; i ++)
showMenuItem(menuItems.get(i), i);
}
/**
*
* @param menuItem
* @param menu_index the position of the menu;
* @return
*/
private void showMenuItem(ResideMenuItem menuItem,int menu_index){
layout_menu.addView(menuItem);
ViewHelper.setAlpha(menuItem, 0);
AnimatorSet scaleUp = new AnimatorSet();
scaleUp.playTogether(
ObjectAnimator.ofFloat(menuItem, "translationX", -100.f, 0.0f),
ObjectAnimator.ofFloat(menuItem, "alpha", 0.0f, 1.0f)
);
scaleUp.setInterpolator(AnimationUtils.loadInterpolator(activity,
android.R.anim.anticipate_overshoot_interpolator));
// with animation;
scaleUp.setStartDelay(50 * menu_index);
scaleUp.setDuration(400).start();
}
private void buildAnimationSet(){
scaleUp_activity = buildScaleUpAnimation(view_activity,1.0f,1.0f);
scaleUp_shadow = buildScaleUpAnimation(iv_shadow,1.0f,1.0f);
scaleDown_activity = buildScaleDownAnimation(view_activity,0.5f,0.5f);
scaleDown_shadow = buildScaleDownAnimation(iv_shadow,shadow_ScaleX,0.59f);
scaleUp_activity.addListener(animationListener);
scaleUp_activity.playTogether(scaleUp_shadow);
scaleDown_shadow.addListener(animationListener);
scaleDown_activity.playTogether(scaleDown_shadow);
}
/**
* a helper method to build scale down animation;
*
* @param target
* @param targetScaleX
* @param targetScaleY
* @return
*/
private AnimatorSet buildScaleDownAnimation(View target,float targetScaleX,float targetScaleY){
// set the pivotX and pivotY to scale;
int pivotX = (int) (getScreenWidth() * 1.5);
int pivotY = (int) (getScreenHeight() * 0.5);
ViewHelper.setPivotX(target, pivotX);
ViewHelper.setPivotY(target, pivotY);
AnimatorSet scaleDown = new AnimatorSet();
scaleDown.playTogether(
ObjectAnimator.ofFloat(target, "scaleX", targetScaleX),
ObjectAnimator.ofFloat(target, "scaleY", targetScaleY)
);
scaleDown.setInterpolator(AnimationUtils.loadInterpolator(activity,
android.R.anim.decelerate_interpolator));
scaleDown.setDuration(250);
return scaleDown;
}
/**
* a helper method to build scale up animation;
*
* @param target
* @param targetScaleX
* @param targetScaleY
* @return
*/
private AnimatorSet buildScaleUpAnimation(View target,float targetScaleX,float targetScaleY){
AnimatorSet scaleUp = new AnimatorSet();
scaleUp.playTogether(
ObjectAnimator.ofFloat(target, "scaleX", targetScaleX),
ObjectAnimator.ofFloat(target, "scaleY", targetScaleY)
);
scaleUp.setDuration(250);
return scaleUp;
}
/**
* if there ware some view you don't want reside menu
* to intercept their touch event,you can use the method
* to set.
*
* @param v
*/
public void addIgnoredView(View v){
ignoredViews.add(v);
}
/**
* remove the view from ignored view list;
* @param v
*/
public void removeIgnoredView(View v){
ignoredViews.remove(v);
}
/**
* clear the ignored view list;
*/
public void clearIgnoredViewList(){
ignoredViews.clear();
}
/**
* if the motion evnent was relative to the view
* which in ignored view list,return true;
*
* @param ev
* @return
*/
private boolean isInIgnoredView(MotionEvent ev) {
Rect rect = new Rect();
for (View v : ignoredViews) {
v.getGlobalVisibleRect(rect);
if (rect.contains((int) ev.getX(), (int) ev.getY()))
return true;
}
return false;
}
//--------------------------------------------------------------------------
//
// GestureListener
//
//--------------------------------------------------------------------------
@Override
public boolean onTouchEvent(MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
gestureDetector.onTouchEvent(ev);
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onDown(MotionEvent motionEvent) {
return false;
}
@Override
public void onShowPress(MotionEvent motionEvent) {
}
@Override
public boolean onSingleTapUp(MotionEvent motionEvent) {
return false;
}
@Override
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent2, float v, float v2) {
return false;
}
@Override
public void onLongPress(MotionEvent motionEvent) {
}
@Override
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent2, float v, float v2) {
if(isInIgnoredView(motionEvent) || isInIgnoredView(motionEvent2))
return false;
int distanceX = (int) (motionEvent2.getX() - motionEvent.getX());
int distanceY = (int) (motionEvent2.getY() - motionEvent.getY());
int screenWidth = (int) getScreenWidth();
if(Math.abs(distanceY) > screenWidth * 0.3)
return false;
if(Math.abs(distanceX) > screenWidth * 0.3){
if(distanceX > 0 && !isOpened ){
// from left to right;
openMenu();
}else if(distanceX < 0 && isOpened){
// from right th left;
closeMenu();
}
}
return false;
}
public int getScreenHeight(){
activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.heightPixels;
}
public int getScreenWidth(){
activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.widthPixels;
}
public interface OnMenuListener{
/**
* the method will call on the finished time of opening menu's animation.
*/
public void openMenu();
/**
* the method will call on the finished time of closing menu's animation .
*/
public void closeMenu();
}
}
點擊查看更多內容
為 TA 點贊
評論
評論
共同學習,寫下你的評論
評論加載中...
作者其他優質文章
正在加載中
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦

