安卓作业----慕课移动应用开发作业12之利用ViewFlipper+GestureDetector事件监听,实现手势滑动查看图片

本博客运用GridView、ViewFlipper、ImageView等进行界面布局,使用自定义适配器显示图片。通过GestureDetector事件监听,可手势滑动查看图片,并设置图片左右滑动出、入的效果。

同时这也是中国大学慕课移动终端应用开发的网课作业12,我会持续更新我的作业,如果有需要关注一下吧

说明

1.图片资源来自于阿里巴巴矢量图标库
2.部分内容参考了此篇博客
3.注意版本和AndroidManifest.xml文件的修改

效果图

在这里插入图片描述

代码部分

主Activity:HomeworkActivity.java

此Activity需要在AndroidManifest.xml上注册并设置为首页

public class HomeworkActivity extends Activity implements GestureDetector.OnGestureListener{
    private GridView mGridView1,mGridView2,mGridView3,mGridView4;//定义四个grid view
    private int[] mImages1,mImages2,mImages3,mImages4;//定义四个数据集
    private HomeWorkAdapter mAdapter1,mAdapter2,mAdapter3,mAdapter4;    //定义四个适配器

    private GestureDetector mGestureDetector;//定义手势监测
    private ViewFlipper mViewFlipper;//定义view flipper
    private Animation[] mAnimations;//定义过渡动画数组
    private final int MIN_DISTANCE = 50;//定义触发滑动最短距离

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_homework);

        mViewFlipper = findViewById(R.id.homework_view_flipper);

        initData();
        initView();
        initAnim();

        mGestureDetector = new GestureDetector(this,this);


    }
    //初始化动画数组
    private void initAnim(){
        mAnimations = new Animation[]{
                AnimationUtils.loadAnimation(this,R.anim.left_in)
                ,AnimationUtils.loadAnimation(this,R.anim.left_out)
                ,AnimationUtils.loadAnimation(this,R.anim.right_in)
                ,AnimationUtils.loadAnimation(this,R.anim.right_out)
        };
    }

    //初始化子页面
    private void initView(){
        mGridView1 = findViewById(R.id.homework_grid_view1);
        mAdapter1 = new HomeWorkAdapter(mImages1,HomeworkActivity.this);
        mGridView1.setAdapter(mAdapter1);
        mGridView1.setNumColumns(3);
        //由于子view布局覆盖了父view的监听事件,所以设置子view的监听也是gestureDetector.onTouchEvent()
        mGridView1.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return mGestureDetector.onTouchEvent(event);
            }
        });

        mGridView2 = findViewById(R.id.homework_grid_view2);
        mAdapter2 = new HomeWorkAdapter(mImages2,HomeworkActivity.this);
        mGridView2.setAdapter(mAdapter2);
        mGridView2.setNumColumns(3);
        mGridView2.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return mGestureDetector.onTouchEvent(event);
            }
        });


        mGridView3 = findViewById(R.id.homework_grid_view3);
        mAdapter3 = new HomeWorkAdapter(mImages3,HomeworkActivity.this);
        mGridView3.setAdapter(mAdapter3);
        mGridView3.setNumColumns(3);
        mGridView3.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return mGestureDetector.onTouchEvent(event);
            }
        });

        mGridView4 = findViewById(R.id.homework_grid_view4);
        mAdapter4 = new HomeWorkAdapter(mImages4,HomeworkActivity.this);
        mGridView4.setAdapter(mAdapter4);
        mGridView4.setNumColumns(3);
        mGridView4.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return mGestureDetector.onTouchEvent(event);
            }
        });
    }

    //初始化 数据
    private void initData(){
        int a = R.drawable.img1;
        int b = R.drawable.img2;
        int c = R.drawable.img3;
        int d = R.drawable.img4;
        mImages1 = new int[]{a, a, a, a, a, a, a, a, a, a, a, a};
        mImages2 = new int[]{b, b, b, b, b, b, b, b, b, b, b, b};
        mImages3 = new int[]{c, c, c, c, c, c, c, c, c, c, c, c};
        mImages4 = new int[]{d, d, d, d, d, d, d, d, d, d, d, d};
    }


    /**
     * 以下方法是监听事件
     * */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return mGestureDetector.onTouchEvent(event);
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        float moveLength = e1.getX() - e2.getX(); //获取移动距离
        Log.d("homeworkTag","e1.getX"+e1.getX());
        Log.d("homeworkTag","e2.getX"+e2.getX());

        if(moveLength < -MIN_DISTANCE){ //如果距离为负的,即往右边滑动大于最小临界值
            mViewFlipper.setInAnimation(mAnimations[0]);
            mViewFlipper.setOutAnimation(mAnimations[1]);
            mViewFlipper.showNext();//展示下一个
            return true;
        }else if( moveLength > MIN_DISTANCE ) { //如果距离为正的,即往左边滑动大于最小临界值
            mViewFlipper.setInAnimation(mAnimations[2]);
            mViewFlipper.setOutAnimation(mAnimations[3]);
            mViewFlipper.showPrevious();//展示上一个
            return true;
        }

        return false;
    }

    @Override
    public boolean onDown(MotionEvent e) {
        return false;
    }

    @Override
    public void onShowPress(MotionEvent e) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        return false;
    }

    @Override
    public void onLongPress(MotionEvent e) {

    }
}
主布局文件:activity_homework.xml
<?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">
    <ViewFlipper
        android:id="@+id/homework_view_flipper"
        android:flipInterval="2000"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <GridView
            android:id="@+id/homework_grid_view1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
        </GridView>

        <GridView
            android:id="@+id/homework_grid_view2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
        </GridView>

        <GridView
            android:id="@+id/homework_grid_view3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
        </GridView>

        <GridView
            android:id="@+id/homework_grid_view4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
        </GridView>

    </ViewFlipper>

</LinearLayout>
子布局界面:homework_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="120dp">
    <ImageView
        android:layout_centerInParent="true"
        android:id="@+id/item_image"
        android:layout_width="80dp"
        android:layout_height="80dp"/>
</RelativeLayout>
自定义适配器:HomeWorkAdapter.java

继承自BaseAdapter类

public class HomeWorkAdapter extends BaseAdapter {
    private int[] images;
    private Context mContext;

    public HomeWorkAdapter(int[] images, Context context) {
        this.images = images;
        mContext = context;
    }

    @Override
    public int getCount() {
        return images.length;
    }

    @Override
    public Object getItem(int position) {
        return images[position];
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if(convertView == null){
            convertView = LayoutInflater.from(mContext).inflate(R.layout.homework_item,parent,false);
            holder = new ViewHolder();
            holder.mImageView = convertView.findViewById(R.id.item_image);

            convertView.setTag(holder);   //将Holder存储到convertView中
        }else{
            holder = (ViewHolder) convertView.getTag();
        }
        holder.mImageView.setImageResource(images[position]);
        return convertView;

    }

    class ViewHolder{
        private ImageView mImageView;
    }
}
动画文件

在res文件夹下新建anim目录,将以下代码复制进去

left_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="-100%"
        android:toXDelta="0"
        android:duration="1000"/>
</set>

left_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0"
        android:toXDelta="100%"
        android:duration="1000"/>
</set>

right_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="100%"
        android:toXDelta="0"
        android:duration="1000"/>
</set>

right_out.xml

扫描二维码关注公众号,回复: 10842897 查看本文章
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0"
        android:toXDelta="-100%"
        android:duration="1000"/>
</set>

聊一聊实现的一些细节

1.关于事件监听

由于子view覆盖了父view绝大多数地方,导致事件监听不到,所以我将子view的onTouch()方法也设置为gestureDetector.onTouchEvent()。

        mGridView1.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return mGestureDetector.onTouchEvent(event);
            }
        });
2.关于滑动方向

在onfling()方法中获取移动前X轴距离与滑动后X轴距离,通过互减,得出方向与移动距离,并设置最小临界移动距离,判断是否要通知mViewFlipper进行切换view

@Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        float moveLength = e1.getX() - e2.getX(); //获取移动距离
        Log.d("homeworkTag","e1.getX"+e1.getX());
        Log.d("homeworkTag","e2.getX"+e2.getX());

        if(moveLength < -MIN_DISTANCE){ //如果距离为负的,即往右边滑动大于最小临界值
            mViewFlipper.setInAnimation(mAnimations[0]);
            mViewFlipper.setOutAnimation(mAnimations[1]);
            mViewFlipper.showNext();//展示下一个
            return true;
        }else if( moveLength > MIN_DISTANCE ) { //如果距离为正的,即往左边滑动大于最小临界值
            mViewFlipper.setInAnimation(mAnimations[2]);
            mViewFlipper.setOutAnimation(mAnimations[3]);
            mViewFlipper.showPrevious();//展示上一个
            return true;
        }

        return false;
    }
3.关于数据初始化

我设置了四个页面,都是GridView,为了偷懒,我将每一个页面的图片都设置为相同的,但是如果愿意的话,可以设置成完全不同的,就和作业要求一样了

private void initData(){
        int a = R.drawable.img1;
        int b = R.drawable.img2;
        int c = R.drawable.img3;
        int d = R.drawable.img4;
        mImages1 = new int[]{a, a, a, a, a, a, a, a, a, a, a, a};
        mImages2 = new int[]{b, b, b, b, b, b, b, b, b, b, b, b};
        mImages3 = new int[]{c, c, c, c, c, c, c, c, c, c, c, c};
        mImages4 = new int[]{d, d, d, d, d, d, d, d, d, d, d, d};
    }
4.关于BaseAdapter的getView()写法

我推荐大家在菜鸟教程进行相关学习

 @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if(convertView == null){
            convertView = LayoutInflater.from(mContext).inflate(R.layout.homework_item,parent,false);
            holder = new ViewHolder();
            holder.mImageView = convertView.findViewById(R.id.item_image);

            convertView.setTag(holder);   //将Holder存储到convertView中
        }else{
            holder = (ViewHolder) convertView.getTag();
        }
        holder.mImageView.setImageResource(images[position]);
        return convertView;

    }

最后

可能我会粗心大意漏写些啥在博客里,如果有错误,希望大家指出,我会尽快修正。

咳咳!关注不迷路哈

发布了41 篇原创文章 · 获赞 102 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/baidu_41860619/article/details/105508678