android 仿知乎sildmenu实现
先上一张效果图
强化后效果图处理viewpager与scroollview滑动冲突
slidmenu实现原理
slidmenu的实现思路是模仿张鸿洋大神的方法实现的
1.自定义sildview继承HorizontalScrollView
2.重写ontouchevent,onlayout,onscrollchanged方法
期间要理解onscollto onsmoothscrollto setTranslationX方法
slidmenu代码
package com.cust.myview;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
public class sildmenu extends HorizontalScrollView {
private int ScreenWidth;
private int menuWidth;
private ViewGroup menu;
private ViewGroup content;
private LinearLayout warp;
private int paddingright;
private boolean once=true;
private boolean isopen=false;
public sildmenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
WindowManager wm=(WindowManager)context.getSystemService(context.WINDOW_SERVICE);
//获取屏幕宽度
DisplayMetrics dm=new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
ScreenWidth=dm.widthPixels;
paddingright=(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100,context.getResources().getDisplayMetrics());
}
public sildmenu(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public sildmenu(Context context) {
this(context, null);
}
public void Toggle()
{
if(isopen)
{
this.smoothScrollTo(menuWidth, 0);
isopen=false;
return;
}
else{
this.smoothScrollTo(0, 0);
isopen=true;
return;
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
int action=ev.getAction();
int x=(int)ev.getX();
switch(action)
{
case MotionEvent.ACTION_DOWN:
if(x>50&&!isopen)
{
return false;
}
else{
return true;
}
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
if(this.getScrollX()>menuWidth/2)
{
this.smoothScrollTo(menuWidth,0);
isopen=false;
}
else{
this.smoothScrollTo(0,0);
isopen=true;
}
return true;
}
return super.onTouchEvent(ev);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if(once)
{
warp=(LinearLayout)this.getChildAt(0);
menu=(ViewGroup)warp.getChildAt(0);
content=(ViewGroup)warp.getChildAt(1);
content.getLayoutParams().width=ScreenWidth;
menuWidth=menu.getLayoutParams().width=ScreenWidth-paddingright;
once=false;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if(changed)
{
this.scrollTo(menuWidth, 0);
}
}
@SuppressLint("NewApi") @Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
content.getChildAt(0).setTranslationX(l-menuWidth);
float alpha=l/menuWidth*0.5f+0.5f;
content.setAlpha(alpha);
super.onScrollChanged(l, t, oldl, oldt);
}
}
sildmenu强化
有时会遇到这样的一个情况
我们的fragment中有个viewpager咋办 它显然会和scrollview发生滑动冲突
如何解决呢
很简单只需在自定义sildmenu重写onInterceptTouchEvent(MotionEvent ev)事件即可 告诉子布局我来处理你不用处理了或者我不处理了你处理吧
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
super.onInterceptTouchEvent( ev);
int x=(int)ev.getX();
if(x>50&&!isopen)
{
//当点击得位置距左边大于50px时不拦截让viewpager处理
return false;
}
// 否则我直接处理即产生滑动
return super.onInterceptTouchEvent( ev);
}