Search code examples
androidtouch

How do I handle touch event with stylus-first strategy in android?


How do I get android paint(stylus) size?

Regarding to the above question.

I can create a stylus-only strategy by MotionEvent.getSize()

public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction()==MotionEvent.ACTION_MOVE) {
            float paintsize = event.getSize();
            Log.i(TAG,String.valueOf(paintsize));
            if (paintsize == 0.02) {
                canvas.drawLine(mov_x, mov_y, event.getX(), event.getY(), paint);
                invalidate();
            }
        }
        ......
        return true;
}

But this cause my hand cannot draw anything.

So, I want to design a stylus-first strategy, for example, when my hand and stylus touch the screen at the same time, system should only shows stylus's path; when only my hand touch the screen, system shows my hand's path as usual.

In my opinion, the stylus cannot broadcast any message to device, so I only have one value to detect: Size

My hand's size is between 0.06 and 0.8999... and stylus's size is 0.02

How do I handle the touch event's priority ? I have no idea about this situation.


Solution

  • Because I can only detect my stylus by its size, retrieve its PointerID is the only way to do that.

    According to https://developer.android.com/reference/android/view/MotionEvent.html#getPointerId%28int%29

    getPointerID: Return the pointer identifier associated with a particular pointer data index in this event. The identifier tells you the actual pointer number associated with the data, accounting for individual pointers going up and down since the start of the current gesture.

    Here's an example.

    @Override
    public boolean onTouchEvent(MotionEvent event){
      float inputsize = event.getSize();
      int index = event.getActionIndex();
      int inputid = event.getPointerID(index);
      boolean isStylus = false;
      int stylusid = -1;
    
      switch(event.getAction())
      {
        case MotionEvent.ACTION_DOWN:
          if(inputsize==0.02 && isStylus==false){
            isStylus = true;
            stylusid = inputid;
          }
          if((isStylus==true) && (inputid==stylusid)){
            mov_x = event.getX();
            mov_y = event.getY();
            //If the new input event is stylus, then move to new coordinate.
            mPath.moveTo(mov_x,mov_y);
          }
          ......
          break;
        case MotionEvent.ACTION_MOVE:
          ......
      }
    }
    

    Although this way isn't perfect, but still can work.