自定义左右侧滑菜单
来源:互联网 发布:hr人力资源软件免费 编辑:程序博客网 时间:2024/05/02 00:04
一、首先新建一个类,继承RelativeLayout,重写其构造方法。
public class MyMenu extends RelativeLayout { public MyMenu(Context context) { this(context, null); } public MyMenu(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyMenu(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); }}
二、把实现效果分成三个部分,即中间部分跟左右两个部分,以中间部分为主体,创建三个FrameLayout,并添加到布局。
private Context context; private FrameLayout leftMenu; private FrameLayout bodyMenu; private FrameLayout rightMenu; private FrameLayout bodyMask; private Scroller mScroller; /** * 初始化 * @param context */ private void init(Context context) { this.context = context; mScroller = new Scroller(context, new DecelerateInterpolator()); leftMenu = new FrameLayout(context); bodyMenu = new FrameLayout(context); rightMenu = new FrameLayout(context); bodyMask = new FrameLayout(context); leftMenu.setBackgroundColor(Color.YELLOW); bodyMenu.setBackgroundColor(Color.RED); rightMenu.setBackgroundColor(Color.GREEN); bodyMask.setBackgroundColor(0x88000000); leftMenu.setId(R.id.LETF_ID); bodyMenu.setId(R.id.BODY_ID); rightMenu.setId(R.id.RIGTH_ID); addView(leftMenu); addView(bodyMenu); addView(rightMenu); addView(bodyMask); bodyMask.setAlpha(0); }
其中setId() 用于添加页面,需要在values中创建一个ids.xml文件
<?xml version="1.0" encoding="utf-8"?><resources> <item name="LETF_ID" format="integer" type="id">0xaabbcc</item> <item name="BODY_ID" format="integer" type="id">0xaabbcc</item> <item name="RIGTH_ID" format="integer" type="id">0xaabbcc</item></resources>
三、重写onMeasure() 方法,获取屏幕的宽高,并计算FrameLayout的大小。
/** * 计算布局大小 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); bodyMenu.measure(widthMeasureSpec, heightMeasureSpec); bodyMask.measure(widthMeasureSpec,heightMeasureSpec); // 获取屏幕的最大宽度 int realWidth = MeasureSpec.getSize(widthMeasureSpec); // 屏幕百分之八十的宽度 int tempWidthMeasure = MeasureSpec.makeMeasureSpec((int) (realWidth * 0.8f), MeasureSpec.EXACTLY); leftMenu.measure(tempWidthMeasure, heightMeasureSpec); rightMenu.measure(tempWidthMeasure, heightMeasureSpec); }
四、重写onLayout() 方法,计算FrameLayout 的初始位置。
/** * 计算启始位置 */ @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); bodyMenu.layout(l, t, r, b); bodyMask.layout(l, t, r, b); leftMenu.layout(-leftMenu.getMeasuredWidth(), t, r, b); rightMenu.layout(l + bodyMenu.getMeasuredWidth(), t, l + bodyMenu.getMeasuredWidth() + r + rightMenu.getMeasuredWidth(), b); }
五、添加滑动监听事件。
/** * 事件监听处理 */ @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (!isTestCompete) { getEventType(ev); return true; } // 左右滑动 if (isleftrightEvent) { switch (ev.getActionMasked()) { case MotionEvent.ACTION_MOVE: int curScrollX = getScrollX(); // 获取滚动距离 int dis_x = (int) (ev.getX() - point.x); // 获取手指滑动距离 int expectX = -dis_x + curScrollX; int finalX = 0; if (expectX < 0) { finalX = Math.max(expectX, -leftMenu.getMeasuredWidth()); // 向左 } else { finalX = Math.min(expectX, rightMenu.getMeasuredWidth()); //向右 } scrollTo(finalX, 0); //移动 point.x = (int) ev.getX(); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: curScrollX = getScrollX(); if (Math.abs(curScrollX) > leftMenu.getMeasuredWidth() >> 1) { if (curScrollX < 0) { mScroller.startScroll(curScrollX,0,-leftMenu.getMeasuredWidth()-curScrollX,0,200); }else{ mScroller.startScroll(curScrollX,0,leftMenu.getMeasuredWidth()-curScrollX,0,200); } }else{ mScroller.startScroll(curScrollX,0,-curScrollX,0,200); } invalidate(); isleftrightEvent = false; isTestCompete = false; break; } } else { switch (ev.getActionMasked()) { case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: isleftrightEvent = false; isTestCompete = false; break; } } return super.dispatchTouchEvent(ev); } private Point point = new Point(); private static final int TEST_DIS = 20; private boolean isleftrightEvent; private void getEventType(MotionEvent ev) { switch (ev.getActionMasked()) { case MotionEvent.ACTION_DOWN: point.x = (int) ev.getX(); point.y = (int) ev.getY(); super.dispatchTouchEvent(ev); break; case MotionEvent.ACTION_MOVE: int dx = Math.abs((int) (ev.getX() - point.x)); int dy = Math.abs((int) (ev.getY() - point.y)); if (dx > TEST_DIS && dx > dy) { //左右滑动 isleftrightEvent = true; isTestCompete = true; point.x = (int) ev.getX(); point.y = (int) ev.getY(); } else if (dy > TEST_DIS && dy > dx) { //上下滑动 isleftrightEvent = false; isTestCompete = true; point.x = (int) ev.getX(); point.y = (int) ev.getY(); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: super.dispatchTouchEvent(ev); isTestCompete = false; isleftrightEvent = false; break; default: break; } }
六、添加左右滑动动画
private Scroller mScroller; private void init(Context context) { // 在init()方法中添加Scroller的初始化 mScroller = new Scroller(context, new DecelerateInterpolator()); } // 在事件监听dispatchTouchEvent()方法中添加滑动位置 case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: curScrollX = getScrollX(); if (Math.abs(curScrollX) > leftMenu.getMeasuredWidth() >> 1) { if (curScrollX < 0) { mScroller.startScroll(curScrollX,0,-leftMenu.getMeasuredWidth()-curScrollX,0,200); }else{ mScroller.startScroll(curScrollX,0,leftMenu.getMeasuredWidth()-curScrollX,0,200); } }else{ mScroller.startScroll(curScrollX,0,-curScrollX,0,200); } // 刷新 invalidate(); isleftrightEvent = false; isTestCompete = false; break; // 最后别忘了添加滑动方法,不然不会执行滑动效果 @Override public void computeScroll() { super.computeScroll(); if(!mScroller.computeScrollOffset()){ return; } int tempX = mScroller.getCurrX(); scrollTo(tempX,0); }
七、进行滑动阴影模板计算。
/** * 滑动 */ @Override public void scrollTo(int x, int y) { super.scrollTo(x, y); int curX = Math.abs(getScrollX()); float scale = curX/(float)leftMenu.getMeasuredWidth(); bodyMask.setAlpha(scale); System.out.println("透明度:"+scale); }
这样就完成一个简单的自定义左右侧滑菜单,在mainActivtiy中可以这样调用。
package com.niowoo.laok.iliaotian;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;public class MainActivity extends AppCompatActivity { private MyMenu myMenu; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); myMenu = new MyMenu(this); setContentView(myMenu); // 使用app包下的Framgnet添加布局 getFragmentManager().beginTransaction().replace(R.id.LETF_ID,new TestFragment()).commit(); }}
Fragment的代码,记住是app包下的Fragment。
package com.niowoo.laok.iliaotian;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;public class MainActivity extends AppCompatActivity { private MyMenu myMenu; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); myMenu = new MyMenu(this); setContentView(myMenu); // 使用app包下的Framgnet添加布局 getFragmentManager().beginTransaction().replace(R.id.LETF_ID,new TestFragment()).commit(); }}
Fragment的布局
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="New Button" android:id="@+id/button" android:layout_gravity="center_horizontal" /></LinearLayout>
1 0
- 自定义左右侧滑菜单
- 自定义左右侧滑菜单
- android的左右侧滑菜单实现
- android的左右侧滑菜单实现
- 左右侧滑菜单的使用
- Android 左右侧滑菜单的实现
- Android自定义LinearLayout实现左右侧滑菜单,完美兼容ListView、ScrollView、ViewPager等滑动控件
- DrawerLayout:左右侧拉菜单
- android 简单滑动菜单之左右侧滑
- android 左右侧滑菜单(点击+左右滑动)一
- 利用DrawLayout和Fragment实现左右侧滑菜单
- android左右侧滑菜单控件的简易实现
- android 左右侧滑菜单(点击+左右滑动)
- android左右侧滑
- 左右侧滑
- iOS自定义左滑菜单项UI
- Android 左右侧滑组件
- 实现左右侧滑功能
- IOS-swift 动画02 CAKeyframeAnimation
- java工程目录
- Android中SQLite应用详解
- XML语言
- 05 - UIWebView 内存泄漏问题
- 自定义左右侧滑菜单
- OSX给PHP添加pdo_mysql扩展
- PHP解决抢购、秒杀、抢楼、抽奖等阻塞式高并发库存防控超量的思路方法
- OSGI
- Android 使用三级缓存实现对图片的加载
- G
- oracle sql学习二
- mybatis 批量增加、删除、修改、查询
- UITableViewCell设置编辑功能