监听手势的关键是:GestureListener给我们提供了下述的回调方法:
- 按下(onDown): 刚刚手指接触到触摸屏的那一刹那,就是触的那一下。
- 抛掷(onFling): 手指在触摸屏上迅速移动,并松开的动作。
- 长按(onLongPress): 手指按在持续一段时间,并且没有松开。
- 滚动(onScroll): 手指在触摸屏上滑动。
- 按住(onShowPress): 手指按在触摸屏上,它的时间范围在按下起效,在长按之前。
- 抬起(onSingleTapUp):手指离开触摸屏的那一刹那。
知道了GestureListener的相关方法后,实现手势检测也很简单,步骤如下:
实现翻页效果的话,我们这边要用到的是:ViewFlipper(翻转视图)。还有动画效果,忘记了的话,可以去之前的博客: https://blog.csdn.net/lpcrazyboy/article/details/80754887
- Step 1: 创建GestureDetector对象,创建时需实现GestureListener传入
- Step 2: 将Activity或者特定组件上的TouchEvent的事件交给GestureDetector处理即可!我们写个简单的代码来验证这个流程,即重写对应的方法:
效果如下:
activity_main.xml的代码如下:
每一个翻转视图的页面布局activity_chnihealthreport.xml的代码如下:
接下来,要写一个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 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 questions = initData();
mQuestion.addAll(questions);
//3.为ViewFilpper添加子控件。
for (int i = 0;i 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 initData(){
List questions = new ArrayList<>();
Question q1 = new Question();
q1.setQuestion("1、\"红娘\"由来是出自下列哪部古典名剧:");
List 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 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 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 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;
}
}