带有ListView界面左右滑动,切换界面
相信大家在做OnGestureListener滑动切换窗口的时候,会遇到这样的问题。就是当界面中含有listview的时候,OnGestureListener的左右触屏滑动就被listview自己吃掉了。
翻看api帮助文档和自己的一些理解,决定从对listview重写开始,开解决这个头疼的问题。
测试的源码:
http://download.csdn.net/detail/wanli_smile/4182584(推荐这个)
http://download.csdn.net/detail/wanli_smile/4178852
开始说明了:新建一个baseatvity实现Gesture滑动切换界面,让其他的activity继承它,这样其他的activity也可以继承它的滑动切换功能,提高代码复用。
下面是BaseActivity:
package com.gesturetest; import android.app.Activity; import android.content.Intent; import android.util.Log; import android.view.GestureDetector; import android.view.GestureDetector.OnGestureListener; import android.view.MotionEvent; /** * * @author liwan *所有activity的基类。继承这个activity的都具有滑动功能哦 */ public class BaseActivity extends Activity implements OnGestureListener{ /** * 手势监听 */ GestureDetector gestureDetector=new GestureDetector(this); /** * 标志位 */ public static int flag=0; @SuppressWarnings("rawtypes") /** * 所有切换的activity */ static Class[] myClass=new Class[]{TestActivity.class,GestureTestActivity.class}; @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub return gestureDetector.onTouchEvent(event); } @Override public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub return false; } @Override public void onShowPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onSingleTapUp(MotionEvent e) { // TODO Auto-generated method stub return false; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // TODO Auto-generated method stub return false; } @Override public void onLongPress(MotionEvent e) { // TODO Auto-generated method stub } @Override /** * 滑动事件的处理 */ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { Log.i("Fling", "baseactivity"); //左滑动 if (e1.getX() - e2.getX() > 80||e1.getY()-e2.getY()>80) { flag=(--flag+myClass.length)%myClass.length; Intent intent=new Intent(getBaseContext(), myClass[flag]); Log.d("flag",flag+""); startActivity(intent); return true; } //右滑动 else if (e1.getX() - e2.getX() <-80||e1.getY()-e2.getY()<-80) { Log.i("Fling", "baseactivity"); flag=++flag%myClass.length; Intent intent=new Intent(getBaseContext(),myClass[flag]); startActivity(intent); Log.d("flag",flag+""); return true; } return true; } }
继承它的两个activity。分别如下:
GestureTestActivity引入了我们自定义的gesturelist
GestureTestActivity
package com.gesturetest; import android.os.Bundle; /** * * @author liwan *这里的GestureList是在xml布局的 */ public class GestureTestActivity extends BaseActivity { /** * 自定义的listview */ GestureList gestureListView; /** * 自定义的adapter */ MyBaseAdapter myBaseAdapter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); myBaseAdapter=new MyBaseAdapter(this); gestureListView=(GestureList)this.findViewById(R.id.list1); gestureListView.setAdapter(myBaseAdapter); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="150dp" android:text="第一个activity,在这里滑动是调用activity的手势处理哦,在listview里面滑动式调用list自己的手势" /> <com.gesturetest.GestureList android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/list1"> </com.gesturetest.GestureList> </LinearLayout>
TestActivity的代码如下。它引用了gesturelist,但是它是使用addview()引入的。
package com.gesturetest; import android.os.Bundle; import android.widget.LinearLayout; /** * 这里的GestureList是用代码引入的,没有在xml布局 * @author liwan * */ public class TestActivity extends BaseActivity { /** * 自定义的listview */ GestureList gestureListView; /** * 自定义的adapter */ MyBaseAdapter myBaseAdapter; LinearLayout linearLayout; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.test); linearLayout=(LinearLayout)this.findViewById(R.id.li); gestureListView =new GestureList(TestActivity.this); myBaseAdapter=new MyBaseAdapter(TestActivity.this); gestureListView.setAdapter(myBaseAdapter); linearLayout.addView(gestureListView); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:id="@+id/li" > <TextView android:layout_width="fill_parent" android:layout_height="100dp" android:text="第二个activity,在这里滑动是调用activity的手势处理哦,在listview里面滑动式调用list自己的手势" /> </LinearLayout>
下面说下核心了,也就是我们的GestureList,由于它的重写,实现了它也可以捕获手势事件了。在onTouchEvent方法里,将处理交给手势监听器。
在xml布局里面使用GestureList,默认的会调用这个构造方法GestureList(Context context, AttributeSet attrs)。一定要重写这个构造方法。
代码如下:
package com.gesturetest; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.widget.ListView; /** * * @author liwan *自定义的listview,带有手势 */ class GestureList extends ListView { int flag=BaseActivity.flag; Context context; GestureDetector gestureDetector; /** * 在xml布局里面使用GestureList,默认的会调用这个构造方法 * @param context * @param attrs */ public GestureList(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub this.context=context; gestureDetector=new GestureDetector(context,new Gesture(context)); Log.d("12","2"); } public GestureList(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub this.context=context; gestureDetector=new GestureDetector(context,new Gesture(context)); Log.d("12","3"); } public GestureList(Context context) { super(context); // TODO Auto-generated constructor stub this.context=context; gestureDetector=new GestureDetector(context,new Gesture(context)); Log.d("12","1"); } @Override public boolean onTouchEvent(MotionEvent ev) { if(gestureDetector.onTouchEvent(ev)) return true; return super.onTouchEvent(ev); } }
package com.gesturetest; import android.content.Context; import android.content.Intent; import android.util.Log; import android.view.GestureDetector.OnGestureListener; import android.view.MotionEvent; public class Gesture implements OnGestureListener{ /** * 得到全局的标志位 */ int flag=BaseActivity.flag; @SuppressWarnings("rawtypes") /** * 得到activity数组 */ Class[] myClass=BaseActivity.myClass; Context context; public Gesture(Context context) { // TODO Auto-generated constructor stub this.context=context; } @Override public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub return false; } @Override public void onShowPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onSingleTapUp(MotionEvent e) { // TODO Auto-generated method stub return false; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // TODO Auto-generated method stub return false; } @Override public void onLongPress(MotionEvent e) { // TODO Auto-generated method stub } @Override /** * 滑动事件的处理 */ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { Log.i("Fling", "baseactivity"); //左滑动 if (e1.getX() - e2.getX() > 80) { flag=(--flag+myClass.length)%myClass.length; //改变BaseActivity,让其知道标志位改变了 BaseActivity.flag=flag; Intent intent=new Intent(context, myClass[flag]); //需要context才能启动activity context.startActivity(intent); return true; } //右滑动 else if (e1.getX() - e2.getX() <-80) { Log.i("Fling", "baseactivity"); flag=++flag%myClass.length; //改变BaseActivity,让其知道标志位改变了 BaseActivity.flag=flag; Intent intent=new Intent(context,myClass[flag]); //需要context才能启动activity context.startActivity(intent); return true; } return true; } }
推荐android等智能机开发QQ交流群:187651345
可以看看代码,上面有代码的下载地址。其实也很简单的