这次跟大家介绍怎么简单的实现类似QQ消息Item的左右滑动菜单的实现。首先见效果图先:
这就实现了ListView或RecyclerView加载的item的View实现侧滑菜单。至于这么实现,很简单就是通过继承HorizontalScrollView,再判断滑动的距离以滑到对应的View或菜单。具体如下:
首先,在item的界面布局方面如下:
就是ScrollListViewItem包裹着LinearLayout里面的三个View,分别是左菜单,内容和右菜单对应的View。最为重点的就是ScrollListViewItem这个类,这就是我们继承HorizontalScrollView类所自定义的控制菜单滑动的类。
这个类的源码如下:
public class ScrollListViewItem extends HorizontalScrollView{
private static int ScreenWidth=0;
private static int MenuWidth=0;
private static int HalfMenuWidth=0;
private boolean operateLeft=false;
private boolean operateRight=false;
private boolean once;
ViewGroup left;
ViewGroup centre;
ViewGroup right;
public ScrollListViewItem(Context context) {
this(context, null);
}
public ScrollListViewItem(Context context, AttributeSet attrs) {
super(context, attrs,0);
}
public ScrollListViewItem(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr,0);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if(!once){
LinearLayout linearLayout=(LinearLayout)getChildAt(0);
left=(ViewGroup)linearLayout.getChildAt(0);
centre=(ViewGroup)linearLayout.getChildAt(1);
right=(ViewGroup)linearLayout.getChildAt(2);
ScreenWidth= ScreenUtils.getScreenWidth(getContext());
MenuWidth=ScreenWidth/4;
HalfMenuWidth=MenuWidth/2;
left.getLayoutParams().width=MenuWidth;
centre.getLayoutParams().width=ScreenWidth;
right.getLayoutParams().width=MenuWidth;
}
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);
once=true;
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch(ev.getAction()){
case MotionEvent.ACTION_UP:
//在左侧
if(operateLeft){
if(getScrollX()HalfMenuWidth&&getScrollX()MenuWidth+HalfMenuWidth){
//滑到最右
this.scrollTo(MenuWidth + MenuWidth, 0);
}else if(getScrollX()>HalfMenuWidth&&getScrollX()MenuWidth){
operateLeft=false;
operateRight=true;
}else{
operateLeft=true;
operateRight=false;
}
}
}
在onMeasure()这个自定义View的测量方法里,我们首先拿到左菜单,内容,右菜单所对用的view,即left,centre,right这三个View,然后获取屏幕的宽度,动态设定菜单的宽度为屏幕宽度的四分之一,而内容的宽度就是整个屏幕的宽度,即
left.getLayoutParams().width=MenuWidth;
centre.getLayoutParams().width=ScreenWidth;
right.getLayoutParams().width=MenuWidth;
然后我们在onLayout()方法里对这三个View进行定位,即让他滑到内容的那个View。
然后回调onScrollChanged(int l, int t, int oldl, int oldt)方法,当l大于菜单宽度时是右侧,当l小于菜单宽度时是右侧。(注:l是屏幕最右边到整个View最右边的距离)
其次就是最重要的onTouchEvent(MotionEvent ev)方法了。(注:是屏幕最右边到整个View最右边的距离).当operateLeft==true的时候,滑动在操作在左侧,当getScrollX()
this.scrollTo(0, 0);
,当getScrollX()>HalfMenuWidth&&getScrollX()
this.scrollTo(MenuWidth, 0);
,这两种情况除外都会滑到最后边的菜单,所以this.scrollTo(MenuWidth * 2, 0)
;
同样的道理,当operateRight==true时,getScrollX()>MenuWidth+HalfMenuWidth
时,即在最右菜单但滑动的距离小于菜单宽度的一半,所以只能恢复原状即this.scrollTo(MenuWidth + MenuWidth, 0);
,当getScrollX()>HalfMenuWidth&&getScrollX()
最后奉上源码