刚刚开始学滑动菜单,参考博主jj的android 滑动菜单SlidingMenu的实现
原博客的实现效果(自己的为了简单,UI就没有实现的那么漂亮)

以下是学习心得:
(1)XML 讲解 ,先上代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/my_right"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:layout_marginLeft="80dp"
>
<ListView
android:id="@+id/my_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
<LinearLayout
android:id="@+id/my_left"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/my_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="@drawable/bg_guide_5"/>
</LinearLayout>
</RelativeLayout>
这个xml的写法也要有要求的,里面定义两个LinearLayout 要滑出显示的菜单的(就是有listview的LinearLayout) 一定要放在上面,不然的话第一个和第二个linearlayout会覆盖层叠的显示出来
(2)java代码讲解
1 程序必须实现两个接口,分别是OnGestureListener,OnTouchListener
public class MyTest extends Activity implements OnGestureListener,OnTouchListener{
private LinearLayout right_layout; //右边的linearlayout
private LinearLayout left_layout;
private ListView listView;
private int SPEED=30;//菜单显示速度
private int SCREEN_WIDTH; //手机屏幕的宽度
private int MAX_WIDTH; //右边linearlayout的宽度
private int mScrollX=0; //右边菜单偏移坐标
private boolean isScrolling=false;
private GestureDetector gestureDetector;
private String title[] = { "待发送队列", "同步分享设置", "编辑我的资料", "找朋友", "告诉朋友",
"节省流量", "推送设置", "版本更新", "意见反馈", "积分兑换", "精品应用", "常见问题", "退出当前帐号" };
boolean hasMeasured=false;
2 在onCreate方法中去掉activity的标题
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.mytest);
initView();
}
3 initView()方法 初始化部件 设置监听
public void initView(){
//右边菜单的布局文件
right_layout=(LinearLayout)findViewById(R.id.my_right);
//左边打开activity显示的布局文件
left_layout=(LinearLayout)findViewById(R.id.my_left);
//获取屏幕的宽度
SCREEN_WIDTH=getWindow().getWindowManager().getDefaultDisplay().getWidth();
System.out.println("SCREEN_WIDTH:"+SCREEN_WIDTH);
listView=(ListView)findViewById(R.id.my_list_view);
//为listview 简单设置数据
listView.setAdapter(new ArrayAdapter<String>(MyTest.this,
android.R.layout.simple_list_item_1,
title));
gestureDetector=new GestureDetector(this, this);
//设置touch事件的监听
left_layout.setOnTouchListener(this);
right_layout.setOnTouchListener(this);
//获取右边 布局(right_layout)文件的宽度
getMAX_WIDTH();
}
4 方法getMAX_WIDTH()获取右边布局(right_layout)的宽,作为左边布局移动的距离
public void getMAX_WIDTH() {
ViewTreeObserver viewTreeObserver = left_layout.getViewTreeObserver();
// 获取控件宽度
viewTreeObserver.addOnPreDrawListener(new OnPreDrawListener() {
@Override
public boolean onPreDraw() {
if (!hasMeasured) {
SCREEN_WIDTH = getWindowManager().getDefaultDisplay()
.getWidth();
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) left_layout
.getLayoutParams();
layoutParams.width = SCREEN_WIDTH;
left_layout.setLayoutParams(layoutParams);
MAX_WIDTH = right_layout.getWidth();
Log.v("fighter", "MAX_WIDTH=" + MAX_WIDTH + "width="
+ SCREEN_WIDTH);
hasMeasured = true;
}
return true;
}
});
}
在这里做下笔记:
函数:
16 /**注册一个回调函数,当一个视图树将要绘制时调用这个回调函数。 17 *参数 listener 将要被添加的回调函数 18 *异常 IllegalStateException 如果isAlive() 返回false 19 */ 20 public void addOnPreDrawListener (ViewTreeObserver.OnPreDrawListener listener) 21
使用ViewTreeObserver 监听左边layout 绘图之前调用该方法,所以才可以得到右边layout的宽度,否则在left_layout绘制之后,那么将得不到right_layout的真正宽度,在其他方法中再使用right_layout.getWidth(); 得到的值是0
5 实现OnGestureListener接口
@Override
public boolean onDown(MotionEvent arg0) {
mScrollX=0;
isScrolling = false;
return true;
}
@Override
public boolean onFling(MotionEvent event, MotionEvent arg1, float arg2,
float arg3) {
return false;
}
@Override
public void onLongPress(MotionEvent arg0) {
}
@Override
public boolean onScroll(MotionEvent event0, MotionEvent event1, float distanceX,
float distanceY) {
isScrolling = true;
RelativeLayout.LayoutParams layoutParams=(RelativeLayout.LayoutParams) left_layout.getLayoutParams();
mScrollX += distanceX;// distanceX:向左为正,右为负
layoutParams.leftMargin-=mScrollX;
System.out.println("*********************************");
System.out.println(event1.getX() -event0.getX()+"(-------)"+mScrollX+"(-------)"+distanceX);
if(layoutParams.leftMargin <= -MAX_WIDTH){
layoutParams.leftMargin=-MAX_WIDTH;
isScrolling = false;
}else if(layoutParams.leftMargin >=0){
layoutParams.leftMargin=0;
isScrolling = false;
}
left_layout.setLayoutParams(layoutParams);
return false;
}
@Override
public void onShowPress(MotionEvent arg0) {
}
@Override
public boolean onSingleTapUp(MotionEvent event) {
System.out.println("执行 onSingleTapUp");
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) left_layout
.getLayoutParams();
// 左移动
if (layoutParams.leftMargin >= 0) {
new myAscy().execute(-SPEED);
} else {
// 右移动
new myAscy().execute(SPEED);
}
return true;
}
这里的onScroll方法做下笔记:
一定要使用一个变量mScrollX来保存叠加distanceX的值,不能直接使用distanceX直接和layoutParams.leftMargin 操作,如果不叠加的话,也可以使用event0.getX() -event1.getX() 来代替mScrollX
6 实现AsyncTask 类,理解比较简单就不重复描述了
class myAscy extends AsyncTask<Integer, Integer, Void>{
@Override
protected Void doInBackground(Integer... params) {
int times=MAX_WIDTH/Math.abs(params[0]);
System.out.println("times:"+times+";max_width:"+MAX_WIDTH);
for(int i=0;i<times;i++){
publishProgress(params[0]);
try {
Thread.sleep(Math.abs(params[0]));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
RelativeLayout.LayoutParams LayoutParams=(RelativeLayout.LayoutParams) left_layout.getLayoutParams();
LayoutParams.width = SCREEN_WIDTH;
System.out.println("values"+values[0]);
//向右移动
if(values[0] > 0){
LayoutParams.leftMargin=Math.min(LayoutParams.leftMargin+values[0], 0);
}else{
LayoutParams.leftMargin=Math.max(LayoutParams.leftMargin+values[0], -MAX_WIDTH);
}
left_layout.setLayoutParams(LayoutParams);
}
}
7 实现OnTouchListener接口
@Override
public boolean onTouch(View arg0, MotionEvent event) {
if(event.getAction() ==MotionEvent.ACTION_UP && isScrolling==true){
RelativeLayout.LayoutParams layoutParams=(RelativeLayout.LayoutParams) left_layout.getLayoutParams();
if(layoutParams.leftMargin < -SCREEN_WIDTH/2){
new myAscy().execute(-SPEED);
}else{
new myAscy().execute(SPEED);
}
}
return gestureDetector.onTouchEvent(event);
}
这里做下笔记, 当用户执行ACTION_UP事件的时候 一定要 &&上 isScrolling 属性,否则的话菜单可能打不来,或者打开后自动合上,所以isScrolling属性是必须的
总结:
(1)缺陷1:ListView 的左右 不起效果,代码还不够精简,准备继续向原博客大神学习,实现ListView 的左右滑动
(2)缺陷2:显示菜单的时候菜单不是从右边滑出来的,而是靠左边布局文件移动慢慢浮现的,所以下次这个缺陷也要修改好
虽然已把李刚的android疯狂讲义大部分看完,也把大部分代码敲了一遍,但是总觉得还不是那么实在,看来还是得继续实战多一点小程序,练多点 
1406

被折叠的 条评论
为什么被折叠?



