Android开发中实现答题小程序手势翻页效果(总结)

GestureListener详解:

监听手势的关键是:GestureListener给我们提供了下述的回调方法:

  • 按下(onDown): 刚刚手指接触到触摸屏的那一刹那,就是触的那一下。
  • 抛掷(onFling): 手指在触摸屏上迅速移动,并松开的动作。
  • 长按(onLongPress): 手指按在持续一段时间,并且没有松开。
  • 滚动(onScroll): 手指在触摸屏上滑动。
  • 按住(onShowPress): 手指按在触摸屏上,它的时间范围在按下起效,在长按之前。
  • 抬起(onSingleTapUp):手指离开触摸屏的那一刹那。

知道了GestureListener的相关方法后,实现手势检测也很简单,步骤如下:

  • Step 1: 创建GestureDetector对象,创建时需实现GestureListener传入
  • Step 2: 将Activity或者特定组件上的TouchEvent的事件交给GestureDetector处理即可!我们写个简单的代码来验证这个流程,即重写对应的方法:
实现翻页效果的话,我们这边要用到的是:ViewFlipper(翻转视图)。还有动画效果,忘记了的话,可以去之前的博客: https://blog.csdn.net/lpcrazyboy/article/details/80754887

效果如下:

activity_main.xml的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:id="@+id/practise_rLayoutRoot"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/bg_white"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <TextView
                android:id="@+id/practise_tvNum"
                android:layout_width="50dp"
                android:layout_height="25dp"
                android:layout_alignParentLeft="true"
                android:layout_centerVertical="true"
                android:layout_marginTop="10dp"
                android:background="@drawable/text_shapestyle"
                android:gravity="center"
                android:paddingBottom="5dp"
                android:paddingTop="5dp"
                android:text="1/122"
                android:textColor="@color/text_white"
                android:textSize="@dimen/text_elementsize" />

            <TextView
                android:id="@+id/practise_tvQType"
                android:layout_width="wrap_content"
                android:layout_height="25dp"
                android:layout_centerVertical="true"
                android:layout_marginLeft="5dp"
                android:layout_marginTop="10dp"
                android:layout_toRightOf="@+id/practise_tvNum"
                android:gravity="center_vertical"
                android:text="单选题"
                android:textColor="@color/text_black"
                android:textSize="@dimen/text_elementsize" />

            <Button
                android:id="@+id/practise_btnSetTextSize"
                android:layout_width="60dp"
                android:layout_height="25dp"
                android:layout_marginLeft="10dp"
                android:layout_marginTop="10dp"
                android:paddingLeft="5dp"
                android:layout_toRightOf="@+id/practise_tvQType"
                android:background="@drawable/btn_shapestyle"
                android:layout_centerVertical="true"
                android:drawableLeft="@drawable/textsize_image"
                android:text="字号"
                android:textColor="@color/text_white"
                android:textSize="@dimen/text_elementsize"/>

            <TextView
                android:id="@+id/practise_tvTestTime"
                android:layout_width="wrap_content"
                android:layout_height="25dp"
                android:layout_centerVertical="true"
                android:layout_marginRight="5dp"
                android:layout_marginTop="10dp"
                android:layout_toLeftOf="@+id/practise_ivCollectYN"
                android:gravity="center_vertical"
                android:text="00:00:00"
                android:textColor="@color/text_black"
                android:textSize="@dimen/text_elementsize" />

            <ImageView
                android:id="@+id/practise_ivCollectYN"
                android:layout_width="wrap_content"
                android:layout_height="25dp"
                android:scaleType="fitCenter"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:layout_marginRight="5dp"
                android:src="@drawable/fav"
                android:visibility="invisible"/>

        </RelativeLayout>
        <ViewFlipper
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/viewFlipper"/>

    </LinearLayout>

    <!-- 按钮功能模块 -->
    <TableLayout
        android:id="@+id/practise_tlfunction"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        >
        <!-- 分割线 -->
        <View
            android:layout_width="match_parent"
            android:layout_height="0.5dp"
            android:background="#33000000" />
        <TableRow
            android:id="@+id/practise_trfunctionBtns"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            >
            <Button
                android:id="@+id/practise_btnSubmit"
                android:layout_width="wrap_content"
                android:layout_height="60dp"
                android:drawableTop="@drawable/lock"
                android:background="@drawable/btnclick_bg_lightgray"
                android:gravity="center"
                android:text="交卷"
                android:textSize="@dimen/text_elementsize"
                android:textColor="@color/text_black"
                android:paddingTop="4dp"
                android:layout_weight="1"
                />
            <Button
                android:id="@+id/practise_btnPrevious"
                android:layout_width="wrap_content"
                android:layout_height="60dp"
                android:drawableTop="@drawable/previous"
                android:background="@drawable/btnclick_bg_lightgray"
                android:gravity="center"
                android:text="上一题"
                android:textSize="@dimen/text_elementsize"
                android:textColor="@color/text_black"
                android:paddingTop="4dp"
                android:layout_weight="1"
                />
            <Button
                android:id="@+id/practise_btnNext"
                android:layout_width="wrap_content"
                android:layout_height="60dp"
                android:drawableTop="@drawable/next"
                android:background="@drawable/btnclick_bg_lightgray"
                android:text="下一题"
                android:textSize="@dimen/text_elementsize"
                android:textColor="@color/text_black"
                android:gravity="center"
                android:paddingTop="4dp"
                android:layout_weight="1"
                />
            <Button
                android:id="@+id/practise_btnMark"
                android:layout_width="wrap_content"
                android:layout_height="60dp"
                android:drawableTop="@drawable/collect"
                android:background="@drawable/btnclick_bg_lightgray"
                android:text="标记"
                android:textSize="@dimen/text_elementsize"
                android:textColor="@color/text_black"
                android:gravity="center"
                android:paddingTop="4dp"
                android:layout_weight="1"
                />
            <Button
                android:id="@+id/practise_btnNumMenu"
                android:layout_width="wrap_content"
                android:layout_height="60dp"
                android:drawableTop="@drawable/numbermenu"
                android:background="@drawable/btnclick_bg_lightgray"
                android:text="题卡"
                android:gravity="center"
                android:textSize="@dimen/text_elementsize"
                android:paddingTop="4dp"
                android:layout_weight="1"
                />
        </TableRow>
    </TableLayout>

</RelativeLayout >

每一个翻转视图的页面布局activity_chnihealthreport.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:padding="5dp"
    android:fitsSystemWindows="true"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="16dp"
        android:paddingLeft="10dp"
        android:paddingRight="5dp"
        android:paddingTop="5dp"
        android:textColor="#646464"
        android:text="您的皮肤在不知不觉中会出现青紫瘀斑、皮下出血吗?(指皮肤在没有外伤的情况下出现青一块紫一块的情况)"
        android:id="@+id/tv_question" />

    <ListView
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/lv_question_answer"/>
</LinearLayout>

接下来,要写一个ListView的数据适配器:ChineseMedicineReportAdapter.java的代码如下:(选项内容)

package com.deepreality.gesturechangepagedemo;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class ChineseMedicineReportAdapter extends BaseAdapter {

    Context context;
    Question quesions;

    public ChineseMedicineReportAdapter(Context context, Question quesions) {
        this.context = context;
        this.quesions = quesions;
    }

    @Override
    public int getCount() {
        return quesions.getAnswer().size();
    }

    @Override
    public Object getItem(int position) {
        return quesions.getAnswer().get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            convertView = View.inflate(context, R.layout.item_answer_list, null);
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        Question.Answer answer = quesions.getAnswer().get(position);
        holder.tvText.setText(answer.getAnswerMessage());
        holder.tvText.setTextSize(16);
        return convertView;
    }

    static class ViewHolder {

        TextView tvText;

        ViewHolder(View view) {
            tvText = view.findViewById(R.id.tv_answer);
        }
    }
}

最后,在相应的Activity中调用并处理相关操作。

GestureFilpActivity.java的代码如下:

package com.deepreality.gesturechangepagedemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;

import java.util.ArrayList;
import java.util.List;

public class GestureFilpActivity extends AppCompatActivity implements GestureDetector.OnGestureListener{

    ViewFlipper mViewFlipper;
    //1.定义手势检测器对象
    GestureDetector mGestureDetector;
    //2.定义一个动画数组,用于为ViewFilpper指定切换动画效果。
    Animation[] animations = new Animation[4];
    //3.定义手势两点之间的最小距离
    private static int FLIP_DISTANCE = 100 ;

    List<Question> mQuestion = new ArrayList<>();
    ChineseMedicineReportAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mViewFlipper = findViewById(R.id.viewFlipper);
        //1.构建手势检测器
        mGestureDetector = new GestureDetector(GestureFilpActivity.this,this);
        //2准备数据
        List<Question> questions = initData();
        mQuestion.addAll(questions);
        //3.为ViewFilpper添加子控件。
        for (int i = 0;i<mQuestion.size();i++){
            Question question = mQuestion.get(i);
            mViewFlipper.addView(addQuestionView(question));
        }
        //4.初始化Animation数组
        animations[0] = AnimationUtils.loadAnimation(this,R.anim.left_in);
        animations[1] = AnimationUtils.loadAnimation(this,R.anim.left_out);
        animations[2] = AnimationUtils.loadAnimation(this,R.anim.right_in);
        animations[3] = AnimationUtils.loadAnimation(this,R.anim.right_out);

    }

    private View addQuestionView(Question question){
        View view = View.inflate(this, R.layout.activity_chnihealthreport, null);
        TextView tes = (TextView) view.findViewById(R.id.tv_question);
        ListView listview = (ListView) view.findViewById(R.id.lv_question_answer);
        listview.addHeaderView(new View(this));
        listview.addFooterView(new View(this));
        adapter = new ChineseMedicineReportAdapter(this, question);
        listview.setAdapter(adapter);
        tes.setText(question.getQuestion());
        listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(GestureFilpActivity.this,position + "", Toast.LENGTH_SHORT).show();
                if (mViewFlipper.getDisplayedChild() == mQuestion.size() - 1) {
                    Toast.makeText(GestureFilpActivity.this,"最后一个题", Toast.LENGTH_SHORT).show();
                    mViewFlipper.stopFlipping();
                    return;
                }else {
                    mViewFlipper.setInAnimation(animations[0]);
                    mViewFlipper.setOutAnimation(animations[1]);
                    mViewFlipper.showNext();
                }
            }
        });
        return view;
    }

    @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) {
        Toast.makeText(GestureFilpActivity.this,"按下",Toast.LENGTH_SHORT).show();
    }

    //重点实现在这里切换
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        if (e1.getX() - e2.getX() < FLIP_DISTANCE){
            if (mViewFlipper.getDisplayedChild() == 0) {
                mViewFlipper.stopFlipping();
                Toast.makeText(GestureFilpActivity.this,"第一个题",Toast.LENGTH_SHORT).show();
                return false;
            } else {
                mViewFlipper.setInAnimation(animations[2]);
                mViewFlipper.setOutAnimation(animations[3]);
                mViewFlipper.showPrevious();
                return true;
            }
        }else if (e1.getX() - e2.getX() > FLIP_DISTANCE){
            if (mViewFlipper.getDisplayedChild() == mQuestion.size() - 1) {
                Toast.makeText(GestureFilpActivity.this,"最后一个题",Toast.LENGTH_SHORT).show();
                mViewFlipper.stopFlipping();
                return false;
            }else {
                mViewFlipper.setInAnimation(animations[0]);
                mViewFlipper.setOutAnimation(animations[1]);
                mViewFlipper.showNext();
                return true;
            }
        }
        return false;
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //将Activity上的触发的事件交个GestureDetector处理
        return mGestureDetector.onTouchEvent(event);
    }

    private List<Question> initData(){
        List<Question> questions = new ArrayList<>();
        Question q1 = new Question();
        q1.setQuestion("1、\"红娘\"由来是出自下列哪部古典名剧:");
        List<Question.Answer> mA = new ArrayList<>();
        Question.Answer a1 = new Question.Answer();
        a1.setAnswerMessage("A《琵琶记》");
        Question.Answer a2 = new Question.Answer();
        a2.setAnswerMessage("B《西厢记》");
        Question.Answer a3 = new Question.Answer();
        a3.setAnswerMessage("C《长生殿》");
        Question.Answer a4 = new Question.Answer();
        a4.setAnswerMessage("D《桃花扇》");
        mA.add(a1);
        mA.add(a2);
        mA.add(a3);
        mA.add(a4);
        q1.setAnswer(mA);
        questions.add(q1);

        Question q2 = new Question();
        q2.setQuestion("2.我国第一部有声影片是:");
        List<Question.Answer> mB = new ArrayList<>();
        Question.Answer b1 = new Question.Answer();
        b1.setAnswerMessage("A《歌女红牡丹》");
        Question.Answer b2 = new Question.Answer();
        b2.setAnswerMessage("B《定军山》");
        Question.Answer b3 = new Question.Answer();
        b3.setAnswerMessage("C《林则徐》");
        Question.Answer b4 = new Question.Answer();
        b4.setAnswerMessage("D《玉人何处》");
        mB.add(b1);
        mB.add(b2);
        mB.add(b3);
        mB.add(b4);
        q2.setAnswer(mB);
        questions.add(q2);
        Question q3= new Question();
        q3.setQuestion("3.下列哪座山不属于我国四大佛山之一:( A)");
        List<Question.Answer> mC = new ArrayList<>();
        Question.Answer c1 = new Question.Answer();
        c1.setAnswerMessage("A《歌女红牡丹》");
        Question.Answer c2 = new Question.Answer();
        c2.setAnswerMessage("B《定军山》");
        Question.Answer c3 = new Question.Answer();
        c3.setAnswerMessage("C《林则徐》");
        Question.Answer c4 = new Question.Answer();
        c4.setAnswerMessage("D《玉人何处》");
        mC.add(c1);
        mC.add(c2);
        mC.add(c3);
        mC.add(c4);
        q3.setAnswer(mC);
        questions.add(q3);
        Question q4 = new Question();
        q4.setQuestion("4.下面哪个是对“惊蛰”这个节气的正确描述?");
        List<Question.Answer> mD = new ArrayList<>();
        Question.Answer d1 = new Question.Answer();
        d1.setAnswerMessage("A《歌女红牡丹》");
        Question.Answer d2 = new Question.Answer();
        d2.setAnswerMessage("B《定军山》");
        Question.Answer d3 = new Question.Answer();
        d3.setAnswerMessage("C《林则徐》");
        Question.Answer d4 = new Question.Answer();
        d4.setAnswerMessage("D《玉人何处》");
        mD.add(d1);
        mD.add(d2);
        mD.add(d3);
        mD.add(d4);
        q4.setAnswer(mD);
        questions.add(q4);

        return questions;
    }
}

猜你喜欢

转载自blog.csdn.net/lpcrazyboy/article/details/80818271