Android——SideMenu侧滑菜单的实现
来源:互联网 发布:渐飞数据库 编辑:程序博客网 时间:2024/06/03 13:46
最近有些忙,有一段时间没有写博客了,今天跟大家分享下SideMenu侧滑菜单的实现,自定义的Animation效果,给别人看起来就感觉好屌的样子,哈哈!不多说,先看看实现的效果。
总体来说也并不复杂,下面给大家看下整个项目的结构:
以下是实现的源码及详细步骤:
新建android studio项目我这边就不讲述了,说一下android studio关联library项目,很简单,我贴几张图片大家就知道了,File->
然后
这样就可以了。
首先看下ViewAnimationUtils类
package com.lai.library.utils;import android.app.Activity;import android.os.Handler;import android.support.v4.widget.DrawerLayout;import android.view.View;import android.view.animation.AccelerateInterpolator;import android.view.animation.Animation;import android.widget.ImageView;import com.lai.library.animations.FlipAnimation;import com.lai.library.interfaces.Resourceble;import com.lai.library.interfaces.ScreenShortable;import java.util.ArrayList;import java.util.List;import static com.lai.sidemenu.R.layout;/** * Created by henry on 2016/5/11. * 自定义的动画效果 */public class ViewAnimationUtils<T extends Resourceble> { /** * 切换隐藏与显示的效果 */ private final int ANIMATION_DURATION = 10; public static final int CIRCULAR_REVEAL_ANIMATION_DURATION = 20; private Activity activity; private List<T> list; private List<View> viewList = new ArrayList<View>(); //View集合 private ScreenShortable screenShortable;//获取图片 private DrawerLayout drawerLayout; private ViewAnimatorListener viewAnimatorListener;//实现定义接口 /** * 构造器 */ public ViewAnimationUtils(Activity activity, List<T> list, ScreenShortable screenShortable, DrawerLayout drawerLayout, ViewAnimatorListener viewAnimatorListener) { this.activity = activity; this.list = list; this.screenShortable = screenShortable; this.drawerLayout = drawerLayout; this.viewAnimatorListener = viewAnimatorListener; } /** * 显示菜单的数量 */ public void showMenuCount() { setViewsClickable(false);//刚显示个数时view是出于false的状态 viewList.clear();//清空组件 double size = list.size(); for (int i = 0; i < size; i++) { View viewMenu = activity.getLayoutInflater().inflate(layout.menu_list_item, null); final int finalI = i; /** * view的点击事件 */ viewMenu.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int[] localtion = {0, 0};//用数组坐标记录位置 v.getLocationOnScreen(localtion);//垂直 switchItem(list.get(finalI), localtion[1] + v.getHeight() / 2); //点击后调用switchItem隐藏 } }); //得到资源并设置 ((ImageView) viewMenu.findViewById(com.lai.sidemenu.R.id.menu_item_image)).setImageResource(list.get(i).getImageRes()); viewMenu.setVisibility(View.GONE); viewMenu.setEnabled(false); viewList.add(viewMenu);//添加list中 viewAnimatorListener.addViewToContainer(viewMenu);//添加到动画接口中 final double position = i; final double delay = 3 * ANIMATION_DURATION * (position / size); /** * 耗时操作 */ new Handler().postDelayed(new Runnable() { @Override public void run() { if (position < viewList.size()) { animateView((int) position); } if (position == viewList.size() - 1) { screenShortable.takeScreenShort(); setViewsClickable(true); } } }, (long) delay); } } /** * 设置View */ private void animateView(int position) { final View view = viewList.get(position); view.setVisibility(View.VISIBLE);//可见 FlipAnimation rotation = new FlipAnimation(90, 0, 0.0f, view.getHeight() / 2.0f);//设置动画效果 rotation.setDuration(ANIMATION_DURATION); rotation.setFillAfter(true); rotation.setInterpolator(new AccelerateInterpolator()); //动画监听 rotation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { view.clearAnimation();//结束后清除动画效果 } @Override public void onAnimationRepeat(Animation animation) { } }); } /** * 点击的Item */ private void switchItem(Resourceble slideMenuItem, int topPosition) { this.screenShortable = viewAnimatorListener.onSwitch(slideMenuItem, screenShortable, topPosition); //点击后隐藏viewList hideMenuContent(); } /** * 隐藏menu */ private void hideMenuContent() { setViewsClickable(false); double size = list.size(); //隐藏全部 for (int i = list.size(); i >= 0; i--) { final double position = i;//记录在viewList中点击的position作为头部,添加动画效果 final double delay = 3 * ANIMATION_DURATION * (position / size); //线程时间(其实这一步没必要,线程的时间可以直接写死) //耗时操作应放在handler里面操作 new Handler().postDelayed(new Runnable() { @Override public void run() { if (position < viewList.size()) { //设置隐藏时的动画 animateHideView((int) position); } } }, (long) delay); } } /** * 设置view隐藏时的动画 */ private void animateHideView(final int position) { final View view = viewList.get(position);//得到点击的view //0表示正在处于的状态为0°,90为操作后的度数,0.0f表示起始精确位置,centerY为view高度的二分之一 FlipAnimation rotation = new FlipAnimation(0, 90, 0.0f, view.getHeight() / 2.0f);//设置动画 rotation.setDuration(ANIMATION_DURATION); //设置动画时间 rotation.setFillAfter(true); rotation.setInterpolator(new AccelerateInterpolator()); rotation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } /** * 结束时 * @param animation */ @Override public void onAnimationEnd(Animation animation) { view.clearAnimation(); view.setVisibility(View.INVISIBLE);//隐藏view if (position == viewList.size() - 1) //防止越界 { viewAnimatorListener.enableHomeButton(); drawerLayout.closeDrawers();//关闭drawers } } @Override public void onAnimationRepeat(Animation animation) { } }); view.startAnimation(rotation);//开始动画 } /** * 设置控件是否可用 */ private void setViewsClickable(boolean clickable) { //点击以后view不可再重新点击 viewAnimatorListener.disableHomeButton(); /** * 点击第几个view */ for (View view : viewList) { view.setEnabled(clickable); } } /** * 定义接口 */ public interface ViewAnimatorListener { //点击MenuItem public ScreenShortable onSwitch(Resourceble slideMenuItem, ScreenShortable screenShortable, int position); public void disableHomeButton(); public void enableHomeButton(); public void addViewToContainer(View view); }}
上面的注释写的非常详细了,一目了然。
下面是FlipAnimation类,自定义的动画效果,代码量很少,更容易理解!
package com.lai.library.animations;/** * Created by henry on 2016/5/11. */import android.graphics.Camera;import android.graphics.Matrix;import android.view.animation.Animation;import android.view.animation.Transformation;/** * 自定义动画效果 */public class FlipAnimation extends Animation { private final float mFromDegrees;//起始的度数 private final float mToDegrees;//要到达的度数 private final float mCenterX;// 水平方向X轴的位置 private final float mCenterY;//Y轴的位置 private Camera mCamera; /** * 构造器 * * @param fromDegrees * @param toDegrees * @param centerX * @param centerY */ public FlipAnimation(float fromDegrees, float toDegrees, float centerX, float centerY) { this.mFromDegrees = fromDegrees; this.mToDegrees = toDegrees; this.mCenterX = centerX; this.mCenterY = centerY; } /** * 初始化屏幕宽度创建Camera * * @param width * @param height * @param parentWidth * @param parentHeight */ public void initialize(int width, int height, int parentWidth, int parentHeight) { super.initialize(width, height, parentWidth, parentHeight); mCamera = new Camera(); } /** * 动画效果 */ public void applyTransformation(float interpolatedTime, Transformation transformation) { final float fromDegrees = mFromDegrees; float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);//总度数 /** * 获取值 */ final float centerX = mCenterX; final float centerY = mCenterY; final Camera camera = mCamera; /** * 对图片进行处理 * Translate 平移变换 Rotate 旋转变换 Scale 缩放变换 Skew 错切变换 */ final Matrix matrix = transformation.getMatrix(); camera.save(); //保存当前状态 ,与restore是成对出现的 camera.rotateY(degrees);//Y轴旋转 camera.getMatrix(matrix);//得到设置后的matrix camera.restore();//回复当前状态 /** * 下面两句标识以动画中心点为中央部分 */ matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); }}
还有几个要实现的接口就不贴出来了,到最后面可以自己去下载源码。
写完关联的library以后,接下来就是我们实际操作的页面了。我们只需要在MainActivity里面嵌套一个Fragment就行了,然后再实现完ViewAnimationUtils的四个接口,马上开始。
第一步写一个Fragment类
package com.lai.sidemenu.fragment;import android.app.Fragment;import android.graphics.Bitmap;import android.graphics.Canvas;import android.os.Bundle;import android.support.annotation.Nullable;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import com.lai.library.interfaces.ScreenShortable;import com.lai.sidemenu.R;/** * Created by henry on 2016/5/11. */public class ContentFragment extends Fragment implements ScreenShortable { /** * 点击图片需要切换的选项value */ public static final String CLOSE = "关闭"; public static final String BUILDING = "创建"; public static final String BOOK = "书本"; public static final String PAINT = "交点"; public static final String CASE = "案例"; public static final String SHOP = "商品"; public static final String PARTY = "派对"; public static final String MOVIE = "电影"; private View rootView; private ImageView mImageView; private int res; private Bitmap bitmap; public static ContentFragment newInstance(int resId) { ContentFragment contentFragment = new ContentFragment(); Bundle bundle = new Bundle(); bundle.putInt(Integer.class.getName(), resId); contentFragment.setArguments(bundle);//设置Arguments return contentFragment; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); this.rootView = view.findViewById(R.id.container); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); res = getArguments().getInt(Integer.class.getName());//获取Arguments的值 } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_main, null); mImageView = (ImageView) view.findViewById(R.id.image_content); mImageView.setClickable(true); mImageView.setFocusable(true); mImageView.setImageResource(res); return view; } /** * 设置bitmap * 耗时操作 */ @Override public void takeScreenShort() { Thread thread=new Thread(){ @Override public void run() { Bitmap bitmap=Bitmap.createBitmap(rootView.getWidth(),rootView.getHeight(),Bitmap.Config.ARGB_8888); Canvas canvas=new Canvas(bitmap); rootView.draw(canvas); ContentFragment.this.bitmap=bitmap; } }; thread.start(); } @Override public Bitmap getBitmap() { return bitmap; }}
在MainActivity中主要就是为Fragment页面添加菜单项,一些点击的操作,见下面代码:
package com.lai.sidemenu;import android.content.res.Configuration;import android.graphics.Color;import android.graphics.drawable.BitmapDrawable;import android.os.Bundle;import android.os.PersistableBundle;import android.support.v4.widget.DrawerLayout;import android.support.v7.app.ActionBarActivity;import android.support.v7.app.ActionBarDrawerToggle;import android.support.v7.widget.Toolbar;import android.view.MenuItem;import android.view.View;import android.view.animation.AccelerateDecelerateInterpolator;import android.widget.LinearLayout;import com.lai.library.interfaces.Resourceble;import com.lai.library.interfaces.ScreenShortable;import com.lai.library.model.SlideMenuitem;import com.lai.library.utils.ViewAnimationUtils;import com.lai.sidemenu.fragment.ContentFragment;import java.util.ArrayList;import java.util.List;public class MainActivity extends ActionBarActivity implements ViewAnimationUtils.ViewAnimatorListener { private ContentFragment contentFragment; private DrawerLayout drawerLayout; private ActionBarDrawerToggle drawerToggle; private List<SlideMenuitem> list = new ArrayList<SlideMenuitem>(); private ViewAnimationUtils viewAnimationUtils; private int res = R.drawable.content_music; private LinearLayout linearLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); contentFragment = ContentFragment.newInstance(R.drawable.content_music); getFragmentManager().beginTransaction().replace(R.id.container_frame, contentFragment).commit(); drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); drawerLayout.setScrimColor(Color.TRANSPARENT); linearLayout = (LinearLayout) findViewById(R.id.left_drawer); linearLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { drawerLayout.closeDrawers(); } }); setActionBar(); createMenuList(); viewAnimationUtils = new ViewAnimationUtils<>(this, list, contentFragment, drawerLayout, this); } /** * 设置ActionBar一些基础操作 */ private void setActionBar() { Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true); drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close) { public void onDrawerClosed(View view) { super.onDrawerClosed(view); linearLayout.removeAllViews(); linearLayout.invalidate(); } @Override public void onDrawerSlide(View drawerView, float slideOffset) { super.onDrawerSlide(drawerView, slideOffset); if (slideOffset > 0.6 && linearLayout.getChildCount() == 0) { viewAnimationUtils.showMenuCount(); } } @Override public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); } }; drawerLayout.setDrawerListener(drawerToggle); } /** * 创建menu菜单 */ private void createMenuList() { SlideMenuitem menuitemOne = new SlideMenuitem(ContentFragment.CLOSE, R.drawable.icn_close); list.add(menuitemOne); SlideMenuitem menuitemTwo = new SlideMenuitem(ContentFragment.BUILDING, R.drawable.icn_1); list.add(menuitemTwo); SlideMenuitem menuitemthree = new SlideMenuitem(ContentFragment.BOOK, R.drawable.icn_2); list.add(menuitemthree); SlideMenuitem menuitemFour = new SlideMenuitem(ContentFragment.CASE, R.drawable.icn_3); list.add(menuitemFour); SlideMenuitem menuitemFive = new SlideMenuitem(ContentFragment.MOVIE, R.drawable.icn_4); list.add(menuitemFive); SlideMenuitem menuitemSix = new SlideMenuitem(ContentFragment.PAINT, R.drawable.icn_5); list.add(menuitemSix); SlideMenuitem menuitemSeven = new SlideMenuitem(ContentFragment.SHOP, R.drawable.icn_6); list.add(menuitemSeven); SlideMenuitem menuitemEight = new SlideMenuitem(ContentFragment.PARTY, R.drawable.icn_7); list.add(menuitemEight); } /** * 开始状态 * * @param savedInstanceState * @param persistentState */ @Override public void onPostCreate(Bundle savedInstanceState, PersistableBundle persistentState) { super.onPostCreate(savedInstanceState, persistentState); drawerToggle.syncState(); } /** * 配置drawerToggle * * @param newConfig */ @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); drawerToggle.onConfigurationChanged(newConfig); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (drawerToggle.onOptionsItemSelected(item)) { return true; } return super.onOptionsItemSelected(item); } @Override public ScreenShortable onSwitch(Resourceble slideMenuItem, ScreenShortable screenShortable, int position) { switch (slideMenuItem.getName()) { case ContentFragment.CLOSE: return screenShortable; default: return replaceFragment(screenShortable, position); } } /** * 切换图片操作 * * @param screenShortable * @param position * @return */ private ScreenShortable replaceFragment(ScreenShortable screenShortable, int position) { this.res = this.res == R.drawable.content_music ? R.drawable.content_films : R.drawable.content_music; View view = findViewById(R.id.container_frame); int finalRadius = Math.max(view.getWidth(), view.getHeight()); io.codetail.animation.SupportAnimator animator = io.codetail.animation.ViewAnimationUtils.createCircularReveal(view, 0, position, 0, finalRadius); animator.setInterpolator(new AccelerateDecelerateInterpolator()); animator.setDuration(ViewAnimationUtils.CIRCULAR_REVEAL_ANIMATION_DURATION); findViewById(R.id.content_overlay).setBackgroundDrawable(new BitmapDrawable(getResources(), screenShortable.getBitmap())); animator.start();//开始动画 ContentFragment contentFragment = ContentFragment.newInstance(this.res); getFragmentManager().beginTransaction().replace(R.id.content_frame, contentFragment).commit(); return contentFragment; } /** * 设置button不可用 */ @Override public void disableHomeButton() { getSupportActionBar().setHomeButtonEnabled(false); } @Override public void enableHomeButton() { getSupportActionBar().setHomeButtonEnabled(true); drawerLayout.closeDrawers(); } @Override public void addViewToContainer(View view) { linearLayout.addView(view); }}
主要的代码已经贴出来了,如果感兴趣的话可以从下面下载项目。
项目源码
0 0
- Android——SideMenu侧滑菜单的实现
- SideMenu侧滑菜单栏
- ionic3学习笔记(五)-sidemenu的实现
- iOS中SideMenu侧边栏的实现,简易速成
- Android--侧滑菜单应用的实现
- Android--侧滑菜单应用的实现
- android 侧滑菜单的简单实现
- Android侧滑菜单的实现
- Android 侧滑菜单的实现
- Android侧滑菜单的实现
- Android--侧滑菜单应用的实现
- android: 侧滑菜单的实现(ViewDragHelper)
- Android之Drawerlayout——实现侧滑菜单
- Android 侧滑菜单实现
- android 侧滑菜单 实现
- android 侧滑菜单实现
- android 实现侧滑菜单
- android实现侧滑菜单
- oracle 密码永不过期
- HDU 1495 非常可乐
- Dynamics CRM 部署NLB后使用群集名称访问弹验证框验证不过的解决方法
- scala for 循环
- 【多线程-创建新线程】
- Android——SideMenu侧滑菜单的实现
- Android自定义视图动画(三)
- 加班草稿2
- 浏览器中音频兼容性问题(上)
- div内图片和文字水平垂直居中
- iOS 使用afnetworking3.0 时 真机编译出现问题: Undefined symbols for architecture armv7
- Prefix.pch文件的作用
- iOS开发中,应用内直接跳转到Appstore(适合版本强制升级和跳转appstore评分)
- 浅谈__declspec(selectany)该何时用