如何使imageView响应双击并识别何时按下,未按下imageView(向下,向上)?

时间:2015-10-08 06:27:03

标签: android gesture tap motionevent gesturedetector

我希望图片能够响应3个动作:

按下图像(向下操作) - 图像变大  图像未按下(动作向上) - 图像再次变为正常尺寸  双击图像 - 图像移动到某处

我一直试图这样做:

 realm.createOrUpdateAllFromJson(Dog.class, jsonStr);

}

但onTouch永远不会被触发!因为onDown(又名MotionEvent.ACTION_DOWN)会激活onDoubleTap和其他 - 单击,甩尾等。

我也尝试覆盖onShowPress() - 但它只识别动作。单击,singleTapconfirmed()也没有帮助。

2 个答案:

答案 0 :(得分:1)

问题是你从true返回onTouch,这会占用该事件而不会再召唤更多的听众。

如果您使用OnLongClickListener代替ACTION_DOWN事件,则可以截取其他事件。

此外,您必须仅在onTouch的true事件内返回ACTION_UP,否则返回false。也不会从onDown返回true,因此事件不会被吃掉。

像这样更改onTouch

@Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_UP:
                //image comes back to normal size
                Log.wtf("x", "action up!");
                return true;
        }
        return false;
    }

并使用OnLongClickListener进行新闻发布会。

答案 1 :(得分:1)

在用手势监听器及其方法挣扎之后 - onFling,onLongPress等我决定自己编写,我的想法与记录每次按下的时间没有什么不同,SO上有类似的解决方案。

我理解我的问题是什么:如果你使用onTouch - 所有的触摸都是通过它拦截和解释的,但是simpleGestureListener通过onDown处理它自己的事件,所以onTouch永远不会被调用;在这种情况下,我必须编写非常基本的逻辑:

  • 在ACTION_DOWN上,启动倒计时器300毫秒左右 - 在滴答约290后,再次检查事件是否仍在停止操作
  • 如果事件是行动失败 - 它基本上是长按并且我的图像相应地响应 - 变得更大,如果不是 - 只是什么都不做
  • 在ACTION_UP上:检查它是否长按,如果是 - 用户未按下按钮,图像变小,否则 - 快速点按!

以下代码:

public class DoubleTapWorking1 extends Activity implements View.OnTouchListener {
ImageView sample;
boolean still_down ;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    sample = (ImageView) findViewById(R.id.sample);
    sample.setOnTouchListener(this);
    still_down = false ;

}

@Override
public boolean onTouch(final View v,final MotionEvent e) {

     switch (e.getAction()){
         case MotionEvent.ACTION_DOWN:
             still_down =false;
             CountDownTimer timer = new CountDownTimer(500,10){
                 @Override
                 public void onTick(long millisUntilFinished) {
                     if((int)millisUntilFinished < 100 && e.getAction() == MotionEvent.ACTION_DOWN){
                         still_down = true ;
                     }
                 }
                 @Override
                 public void onFinish() {
                     if( still_down){                           
                         //code to make imageView larger
                     }
                 }
             }.start();
             break ;
         case MotionEvent.ACTION_UP:
             if(still_down) {
                 //your code to make image smaller
             }
             else{
                 action_on_single_tap(v);
             }
             break ;
     }

   return true;
  }

  private void action_on_single_tap(final View v){
      //your code to do with image on single tap - move somewhere else, make invisible etc.
}

}

编辑:另一个更好的解决方案。

我在倒数计时器方面遇到了一些问题 - 由于某种原因,它没有倒数到底。我应用了一些旧的想法 - 使用2个侦听器区分长按和单击 - LongClickListener,ClickListener。这比上面的解决方案好得多。

以下代码:

private class Gestures_future implements View.OnClickListener, View.OnLongClickListener{

     int margin_long_press_x1;
     int margin_long_press_y1;
     int margin_long_press_x2;
     int margin_long_press_y2;
     RelativeLayout.LayoutParams params_generic = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
public Gestures_future(final int margin_long_press_x1,final int margin_long_press_y1,final int margin_long_press_x2,final int margin_long_press_y2
    ){
        params_generic.leftMargin = 30;
        params_generic.topMargin = 40;

        this.margin_long_press_x1 = margin_long_press_x1;
        this.margin_long_press_y1 = margin_long_press_y1;
        this.margin_long_press_x2 = margin_long_press_x2;
        this.margin_long_press_y2 = margin_long_press_y2;
    }
    @Override
    public void onClick(View v) {
        Log.wtf("x", "on click!");
        TextView d = (TextView)v;
        int current_id = v.getId();
       String answer_content = d.getText().toString();
        if (answers_player1_ids.contains(current_id)) {
        if (Battlefield.getStateOfAnswer1PlacePlayer1() == false) {
            d.setText("");
            Battlefield.answer1_place_busy_player1 = true;
            answer_place1_player1.setTextSize(20);
            answer_place1_player1.setText(answer_content);
            upper_layout_answer_counter++;
        } else if (Battlefield.getStateOfAnswer2PlacePlayer1() == false) {
            d.setText("");
            Battlefield.answer2_place_busy_player1 = true;
            answer_place2_player1.setTextSize(20);
            answer_place2_player1.setText(answer_content);
            upper_layout_answer_counter++;
            if (upper_layout_answer_counter == 2) {
                upper_layout_answer_counter = 0;
                see_answers1.performClick();
            }
        }
    }
        else if (answers_player2_ids.contains(current_id)) {
        if (Battlefield.getStateOfAnswer1Place() == false){
            d.setText("");
            Battlefield.answer1_place_busy = true;
            answer_place1.setTextSize(20);
            answer_place1.setText(answer_content);
            lower_layout_answer_counter++;
        } else if (Battlefield.getStateOfAnswer2Place() == false) {
            d.setText("");
            Battlefield.answer2_place_busy = true;
            answer_place2.setTextSize(20);
            answer_place2.setText(answer_content);
            lower_layout_answer_counter++;
            if (lower_layout_answer_counter == 2) {
                lower_layout_answer_counter = 0;
                see_answers2.performClick();
            }
        }
    }
}
    @Override
    public boolean onLongClick(View v){
        Log.wtf("x", "on long click!");
        final TextView d = (TextView)v;
        Log.wtf("x", d.getText().toString() +  " long clicked!" );
                    d.setTextSize(30);
                    RelativeLayout.LayoutParams x = new RelativeLayout.LayoutParams(350, 500);
                    x.setMargins(margin_long_press_x1, margin_long_press_y1, 0, 0);
                    d.setLayoutParams(x);
                    d.requestLayout();
        new CountDownTimer(3000,500){
            @Override
            public void onTick(long millisUntilFinished) {
            }
            @Override
            public void onFinish() {
                RelativeLayout.LayoutParams t1 = new RelativeLayout.LayoutParams(130, 170);
                t1.setMargins(margin_long_press_x2, margin_long_press_y2, 0, 0);
                d.setTextSize(10);
                d.setLayoutParams(t1);
                d.requestLayout();
            }
        }.start();
        return true;
    }

}

上面的解决方案对我很有用。