安卓作業----慕課移動應用開發作業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

<?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;

    }

最後

可能我會粗心大意漏寫些啥在博客裏,如果有錯誤,希望大家指出,我會盡快修正。

咳咳!關注不迷路哈

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章