侧滑原理分析:
淘汰的思路:
第一:试图:ViewGroup
第二:事件:onTouchEvent
第三:思路:当手指触动屏幕时,根据touch的事件,去改变ViewGroup的左右试图的宽度。
第四:实现:(略)
这种思路我们要处理touch的move事件和up事件,并且对于冲突的处理并不理想。所以我使用HorizontalScrollView(水平滚动条),太晚了,我就不写了,明天再写。
今晚继续写:
首先说个思路哈,不知道对不对,觉得是这样的,当自定义视图时,要在构造方法中获得屏幕的宽度,其次重写onMeasure方法,确定子布局和自身的宽高,再次重写onLayout方法,确定子布局的位置,最后可以重写onTouchEvent方法,根据手势的改变去改变子布局的相对位置。下面我就带着这个思路去实现一款最简单的侧滑效果:
视图代码如下:
package com.imooc.cehua;
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;
/**
* @author 2015年7月23日,自定义试图。
*
* 一般分为三部分: 第一步:重写onMeasure方法,去确定自己和子布局的宽和高 第二步:重写onLayout方法,确定子布局放置的位置
* 第三步:重写onTouchEvent方法,确定手势的改变,对布局的影响(有时也不用重写他,根据需要选择重写)
*
*/
public class MyView extends HorizontalScrollView {
private LinearLayout mLayout;
private ViewGroup mMenu;
private ViewGroup mContent;
private boolean once;// 确保onMeasure不被重复调用
private int screenWidth;// 屏幕的宽度
private int mMenuPaddingRight;// 左侧菜单的左边距离手机屏幕左边的距离
private int mMenuWidth;// 因为菜单的宽度根据手势会有变化,所以把他的距离抽取出来
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
screenWidth = outMetrics.widthPixels;// 获取屏幕的像素值
// 把50像素转换为了50dip
mMenuPaddingRight = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50, context.getResources()
.getDisplayMetrics());
}
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* 测量自己和子布局的宽和高的
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (!once) {
mLayout = (LinearLayout) getChildAt(0);
mMenu = (ViewGroup) mLayout.getChildAt(0);
mContent = (ViewGroup) mLayout.getChildAt(1);
mContent.getLayoutParams().width = screenWidth;
mMenuWidth = mMenu.getLayoutParams().width = screenWidth
- mMenuPaddingRight;
once = true;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/**
* 这个是设置子布局的布局位置,因此首先把menu隐藏
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (changed) {
// 他的意思是,把菜单的左边距离屏幕的左边mMenuWidth(只不过这个是不显示的),而此时菜单的宽度刚好是这个值,因此就被隐藏了
scrollTo(mMenuWidth, 0);
}
}
/**
* 由于HorizontalScrollView,对移动和冲突处理的很好了,只需要判断手指抬起时,菜单左边距离屏幕左边的值和菜单宽度比较即可,如果,
* 大于就隐藏,小于就显示
*/
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_UP:
int x = getScrollX();// 这个就是判断整个视图的左边距离屏幕的左边的距离,而恰巧菜单在布局的左侧,因此也就是菜单左边距离屏幕左边的距离
if (x >= mMenuWidth / 2) {
smoothScrollTo(mMenuWidth, 0);
} else {
smoothScrollTo(0, 0);
}
return true;
}
// 不能让他一直返回true,不然没有滑动效果,具体因为啥,我不知道呀,可以查看onTouchEvent返回值的区别
return super.onTouchEvent(ev);
// return true;
}
}
两个布局文件如下:
主布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.imooc.cehua.MyView
android:id="@+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal" >
<include layout="@layout/left_menu" />
<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/content"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
</com.imooc.cehua.MyView>
</RelativeLayout>
菜单布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFD883"
android:gravity="center"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/id_img2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:src="@drawable/img2" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@id/id_img2"
android:text="第二个item"
android:textColor="#CEDDED"
android:textSize="30sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/id_img3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:src="@drawable/img3" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@id/id_img3"
android:text="第三个item"
android:textColor="#CEDDED"
android:textSize="30sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/id_img4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:src="@drawable/img4" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@id/id_img4"
android:text="第四个item"
android:textColor="#CEDDED"
android:textSize="30sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/id_img5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:src="@drawable/img5" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@id/id_img5"
android:text="第五个item"
android:textColor="#CEDDED"
android:textSize="30sp" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
工程目录结构如图所示: