Android No Touch Events after canvas translation

I searched the Internet for an answer to a question that had been listening to me for several days. I am creating a widget that allows the user to pan the entire widget by dragging (only around the Y axis) into the viewport. Then I have a smaller view (e.g. a button, listens onTouchEvent) that the user can also drag and drop. The idea is that the user will drag this view up or down, and if they want to go higher or lower, they can pan the entire widget and then continue dragging the image higher or lower. Now I have two problems. Firstly, after dragging and dropping the main view (the entire widget), the view that I would like to move is still in the area in which it was once before moving the entire canvas.

So, for example, if I move the entire canvas by 50 in position Y, then I want to move the smaller view, but I have to touch it in the old position, and not in the shifted one (by 50). So it seems like I am not pushing the smaller view where it is now, but where it was (hopefully this makes sense).

The next issue, after I moved the smaller view. I can no longer activate sensory events. I assume that since it has been moved outside of its parent (which is still viewable since I set clipChildren to false) and its “z-order” is lower than other views in the layout. Is there a way to always position this on top? I use the Android API 17. Even if I set this smaller view (which I move when I touch and the ACTION_MOVE event fires) as the last child in the main layout, I need to remove it from here (which I can) and continue to drag it to the new onTouchEvent . ANY help is appreciated. I added some xml layouts and code snippets below to help.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clipChildren="false"
            android:clipToPadding="false">

<RelativeLayout
        android:id="@+id/main_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipChildren="false"
        android:clipToPadding="false">

    <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_centerHorizontal="true"
            android:clipChildren="false"
            android:clipToPadding="false">

        <ImageView
                android:id="@+id/ref_image"
                android:layout_width="wrap_content"
                android:layout_height="216dp"
                android:src="@drawable/my_ref_image"
                android:layout_centerInParent="true"
                android:clipChildren="false"/>
        <RelativeLayout
                android:id="@+id/selection_view"
                style="@style/MyStyle"
                android:layout_alignTop="@id/ref_image"
                android:layout_marginTop="116dp"
                android:clipChildren="false"
                android:clipToPadding="false">
            <RelativeLayout
                    android:id="@+id/selection_area"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    android:clipChildren="false"
                    android:clipToPadding="false">
                <ImageView
                        android:id="@+id/underlay_image"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@drawable/translucent_image"
                        android:layout_centerInParent="true"/>
                <ImageView
                        android:id="@+id/point_area"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@drawable/point_image"
                        android:layout_centerInParent="true"/>
            </RelativeLayout>
        </RelativeLayout>
    </RelativeLayout>        
</RelativeLayout>

So, the code snippets that are of interest:

@Override
protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  if (DEBUG) {
     Log.d(TAG, TAG + "::onDraw: ");
  }

  canvas.translate(0, backgroundPositionY);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
  final int action = ev.getAction();
  Log.d(TAG, TAG + "::onTouchEvent: parent touch event");
  switch (action) {
  case MotionEvent.ACTION_DOWN: {
     final float y = ev.getY();

     // Remember where we started
     lastTouchY = y;

     if (DEBUG) {
        Log.d(TAG, TAG + "::onTouchEvent: parent ACTION_DOWN");
     }
     return true;
  }

  case MotionEvent.ACTION_MOVE: {
     final float y = ev.getY();

     // Calculate the distance moved
     final float dy = y - lastTouchY;

     backgroundPositionY += dy

     // Remember this touch position for the next move event
     lastTouchY = y;

     // Invalidate to request a redraw
     invalidate();
     break;
  }
  case MotionEvent.ACTION_UP: {         
     lastTouchY = ev.getY();
  }
  }
  return false;
}
// called upon initialization (selectionArea refs view id = selection_area)
private void initPointListener() {
  this.setClipChildren(false);
  this.setClipToPadding(false);

  if (selectionArea != null) {
     selectionArea .setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {

           RelativeLayout.LayoutParams pointParams = (RelativeLayout.LayoutParams) selectionArea.getLayoutParams();
           final int action = motionEvent.getAction();
           switch (action) {
           case MotionEvent.ACTION_DOWN: {
              pointLastTouchY = motionEvent.getY();
              }
              break;
           }

           case MotionEvent.ACTION_MOVE: {
              float moveY = motionEvent.getY();
              final float dy = moveY - pointLastTouchY;
              pointPosY += dy;

              selectionArea.setY(pointPosY);
              break;
           }
           }

           return true;
        }
     });
  }
}

, , SO :

-

Android: click/touch

0
3

, ... . , ( ) . , . , , x y , . , , , . onTouchEvent , , , . , . pannable

0

- . MotionEvents. , , . , - MotionEvents, . , - , , .

Also, it looks crazy in some implementations, I think the Galaxy Tab 10, it was just awfully fubar and impossible wrong. This makes the presentation invalidity slightly different than other tablets, and updates the incorrect parts of the view.

0
source

Source: https://habr.com/ru/post/1541278/


All Articles