123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- package com.xunao.effectdemo.activity;
- import static com.blankj.utilcode.util.ScreenUtils.getScreenHeight;
- import static com.blankj.utilcode.util.ScreenUtils.getScreenWidth;
- import androidx.appcompat.app.AppCompatActivity;
- import androidx.core.content.res.ResourcesCompat;
- import android.animation.Animator;
- import android.animation.AnimatorSet;
- import android.animation.ObjectAnimator;
- import android.app.Activity;
- import android.content.ClipData;
- import android.content.Context;
- import android.content.Intent;
- import android.graphics.Color;
- import android.os.Bundle;
- import android.os.SystemClock;
- import android.util.Log;
- import android.util.TypedValue;
- import android.view.DragEvent;
- import android.view.Gravity;
- import android.view.HapticFeedbackConstants;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.ViewGroup;
- import android.view.ViewTreeObserver;
- import android.view.animation.Animation;
- import android.view.animation.AnimationUtils;
- import android.view.animation.TranslateAnimation;
- import android.widget.FrameLayout;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- import android.widget.RelativeLayout;
- import android.widget.TextView;
- import com.xunao.effectdemo.R;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Random;
- import java.util.Timer;
- import java.util.TimerTask;
- public class DragActivity extends Activity{
- private static final String RED = "RED";
- RelativeLayout select_rl;
- RelativeLayout rl_bg;
- TextView tv_content;
- //进行滑动的TextView
- private TextView moveTextView;
- List<String> selectList;
- private int answerSize = 0;
- private int halfAnswerSize = 0;
- private int selectRootWidth = 0;
- private int selectRootHeight = 0;
- //选项位置的集合。初始的显示位置。用于后续拖动松手后,选项做回归动画
- private List<String> selectInitialLocationList;
- //分隔符
- private String SeparateSymbol = "-";
- //认为的最小滑动值。超过这个值,就认为是滑动;如果没有超过,就是认为是点击
- private int reputeMixMoveValue = 10;
- //按下时候的x,y坐标
- private float downX = 0;
- private float downY = 0;
- //当前点击或者按住了哪个选项
- private int currentOptionPosition = -1;
- //移动、滑动时候,当前位置的x,y坐标
- private float moveCurrentX;
- private float moveCurrentY;
- private String selectedContent = "";
- private final String correctAnswer = "选项2";
- private int wrongNum = 0;
- Timer timer = new Timer();
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_drag);
- tv_content = findViewById(R.id.tv_content);
- select_rl = findViewById(R.id.select_rl);
- rl_bg = findViewById(R.id.rl_bg);
- initData();
- }
- void initData(){
- selectInitialLocationList = new ArrayList<>();
- // 选项集合
- List<String> selectList = new ArrayList<>();
- selectList.add("选项1");
- selectList.add("选项2");
- selectList.add("选项3");
- this.selectList = selectList;
- answerSize = dp2px(50);
- halfAnswerSize = answerSize / 2;
- ViewTreeObserver.OnGlobalLayoutListener listener = new ViewTreeObserver.OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- View view = new View(DragActivity.this);
- RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
- params.width = getScreenWidth()/2;
- params.height = getScreenHeight();
- view.setLayoutParams(params);
- view.setBackgroundColor(getResources().getColor(R.color.textGrayColor));
- rl_bg.addView(view);
- select_rl.getViewTreeObserver().removeOnGlobalLayoutListener(this);
- handleSelect();
- }
- };
- select_rl.getViewTreeObserver().addOnGlobalLayoutListener(listener);
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- switch (event.getAction()){
- case MotionEvent.ACTION_DOWN:
- if (moveTextView != null) {
- break;
- }
- currentOptionPosition = -1;
- downX = event.getX();
- downY = event.getY();
- //指定当前滑动的TextView
- for (int i = 0; i < selectInitialLocationList.size(); i++) {
- float x1 = Float.parseFloat(selectInitialLocationList.get(i).split(SeparateSymbol)[0]);
- float x2 = x1 + answerSize*4;
- float y1 = Float.parseFloat(selectInitialLocationList.get(i).split(SeparateSymbol)[1]);
- float y2 = y1 + answerSize;
- //x1、y1,是选项左上角的坐标。x2、y2,是选项右下角的坐标
- if (downX > x1 && downX < x2 && downY > y1 && downY < y2) {
- if(select_rl.getChildAt(i).getVisibility() == View.VISIBLE){
- //拿到当前选择的这个选项的view
- moveTextView = (TextView) select_rl.getChildAt(i);
- //记下现在选的,是第几个选项
- currentOptionPosition = i;
- Log.e("按下", currentOptionPosition + "");
- break;
- }
- }
- }
- break;
- case MotionEvent.ACTION_MOVE:
- if (moveTextView == null) {
- return false;
- }
- moveCurrentX = event.getX();
- moveCurrentY = event.getY();
- if (Math.abs(moveCurrentX - downX) > reputeMixMoveValue && Math.abs(moveCurrentY - downY) > reputeMixMoveValue) {
- //这里,按下的坐标,要减去选项的一半,让选项的中间,跟着手指动。否则,就是选项的左上角,跟着手指移动,不美观
- moveTextView.setX(moveCurrentX - halfAnswerSize);
- moveTextView.setY(moveCurrentY - halfAnswerSize);
- }
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- if (moveTextView == null) {
- return false;
- }
- // 当移动到答案框内时
- if(moveCurrentX > tv_content.getX() && moveCurrentX < tv_content.getX() + tv_content.getWidth() &&
- moveCurrentY >tv_content.getY() && moveCurrentY < tv_content.getY() + tv_content.getHeight()){
- // 正确答案
- if(selectList.get(currentOptionPosition).equals(correctAnswer)){
- tv_content.setText(selectList.get(currentOptionPosition));
- tv_content.setBackground(ResourcesCompat.getDrawable(getResources(),R.drawable.drag_success_bg, null));
- moveTextView = null;
- select_rl.getChildAt(currentOptionPosition).setVisibility(View.INVISIBLE);
- }else{ // 错误答案
- // 先抖一抖再回去
- wrongAnimator();
- }
- }else {
- //说明没有放到答案框,就做回归动画
- moveAnimator(0, 0, 0, 0, 0, -1);
- }
- break;
- default:
- break;
- }
- return true;
- }
- //处理选项。计算选项,摆放选项的位置
- private void handleSelect() {
- selectRootWidth = select_rl.getWidth();
- selectRootHeight = select_rl.getHeight();
- //移除之前的子控件(避免数据造成冲突)
- select_rl.removeAllViews();
- float x = 0;
- float y = 0;
- for (int i = 0; i < selectList.size(); i++) {
- String option = selectList.get(i);
- TextView tvAnswer = createSelectTv(option);
- x = getScreenWidth()*3/5;
- y = getScreenHeight()/4 + dp2px(80) * i;
- //这里的setX、setY,是指选项(正方形)左上角的坐标位置
- tvAnswer.setX(x);
- tvAnswer.setY(y);
- //保存这个选项的坐标位置
- selectInitialLocationList.add(x + SeparateSymbol + y);
- select_rl.addView(tvAnswer);
- }
- }
- /**
- * 创建选项TextView
- *
- * @param str textView上要展示的内容
- * @return
- */
- private TextView createSelectTv(String str) {
- TextView tv = new TextView(this);
- tv.setBackground(ResourcesCompat.getDrawable(getResources(),R.drawable.drag_default_bg,null));
- tv.setText(str);
- tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
- RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
- params.width = answerSize*4;
- params.height = answerSize;
- tv.setLayoutParams(params);
- tv.setGravity(Gravity.CENTER);
- return tv;
- }
- // 抖一抖动画
- private void wrongAnimator(){
- wrongNum = wrongNum + 1;
- Animation anim = AnimationUtils.loadAnimation(DragActivity.this, R.anim.myanim);
- tv_content.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.drag_error_bg, null));
- tv_content.setText(selectList.get(currentOptionPosition));
- tv_content.startAnimation(anim);
- moveTextView.setVisibility(View.GONE);
- //抖完后回去
- timer.schedule(new TimerTask() {
- @Override
- public void run() {
- runOnUiThread(() -> {
- tv_content.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.drag_default_bg, null));
- tv_content.setText("");
- moveAnimator(0, 0, 0, 0, 0, -1);
- });
- }
- }, 1200);
- }
- /**
- * 回归动画
- * type:
- * 0、没有拖动到空格处,松开手后控件回到初始位置
- * 1、拖动到空格处,松开手后,隐藏控件,静默回归
- * 2、点击选项,控件移动到空缺的位置
- * 3、点击选项,内容填充到空格处后,控件需要静默回归
- */
- private void moveAnimator(final int type, float sX, float sY, float eX, float eY, final int position) {
- Log.e("type is ", type + "");
- Log.e("currentOptionPosition ", currentOptionPosition + "");
- if (currentOptionPosition == -1 || moveTextView == null) {
- return;
- }
- moveTextView.setVisibility(View.VISIBLE);
- try {
- float startX = 0;
- float startY = 0;
- float endX = 0;
- float endY = 0;
- AnimatorSet animatorSet = new AnimatorSet();
- ObjectAnimator translationX;
- ObjectAnimator translationY;
- String location = selectInitialLocationList.get(currentOptionPosition);
- startX = moveTextView.getX();
- startY = moveTextView.getY();
- endX = Float.parseFloat(location.split(SeparateSymbol)[0]);
- endY = Float.parseFloat(location.split(SeparateSymbol)[1]);
- translationX = ObjectAnimator.ofFloat(
- moveTextView,
- "translationX",
- startX,
- endX
- );
- translationY = ObjectAnimator.ofFloat(
- moveTextView,
- "translationY",
- startY,
- endY
- );
- animatorSet.playTogether(translationX, translationY);
- long durationTime = 1000;
- animatorSet.setDuration(durationTime);
- animatorSet.addListener(new Animator.AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animator) {
- }
- @Override
- public void onAnimationEnd(Animator animator) {
- //抬起手后,释放滑动的TextView
- moveTextView = null;
- currentOptionPosition = -1;
- if(wrongNum > 2){
- for(int i = 0; i < select_rl.getChildCount(); i ++){
- if(((TextView) select_rl.getChildAt(i)).getText().equals(correctAnswer)){
- ((TextView) select_rl.getChildAt(i)).setBackground(ResourcesCompat.getDrawable(getResources(),R.drawable.drag_hint_bg,null));
- }
- }
- }
- }
- @Override
- public void onAnimationCancel(Animator animator) {
- }
- @Override
- public void onAnimationRepeat(Animator animator) {
- }
- });
- animatorSet.start();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- private int dp2px(float dpValue) {
- final float scale = getResources().getDisplayMetrics().density;
- return (int) (dpValue * scale + 0.5f);
- }
- }
|