2015-06-30 3 views
0

Я прочесал сеть в поисках ответа на вопрос, который прослушивал меня в течение нескольких дней. Я создаю виджет, который позволяет пользователю панорамировать весь виджет, перетаскивая (только вокруг оси Y) в область просмотра. Затем у меня есть меньший вид (например, кнопка, выслушивает onTouchEvent), которую пользователь может также перетаскивать. Идея состоит в том, что пользователь будет перетаскивать это представление вверх или вниз, и если они хотят идти выше или ниже, они могут панорамировать весь виджет, а затем продолжить перетаскивание изображения выше или ниже. Теперь у меня две проблемы. Во-первых, после перетаскивания основного вида (весь виджет) представление, которое я хотел бы переместить, все еще находится в области, в которой он когда-то был, прежде чем перевести весь холст.Android No Touch Events после перевода холста

Так, например, если я перемещаю весь холст на 50 в позиции Y, тогда я хочу перемещать меньший вид, но должен касаться в старой позиции, а не в смещенной (на 50). Таким образом, похоже, что я не нажимаю меньший вид, где он сейчас, но где он был (надеюсь, это имеет смысл).

Следующая проблема, после того как я переместил уменьшенный вид. Я не могу больше активировать сенсорные события. Я предполагаю, что это потому, что он был перемещен за пределы его родителя (который все еще доступен для просмотра, поскольку я устанавливаю clipChildren в false), а его «z-порядок» ниже, чем другие представления в макете. Есть ли способ всегда позиционировать это сверху? Я использую Android API 17. Даже если я установил это меньшее представление (которое я перемещаю при касании и событие ACTION_MOVE запускается) в качестве последнего дочернего элемента в основном макете, мне нужно убрать его отсюда (что я может) и продолжить перетаскивать его на новый onTouchEvent. ЛЮБАЯ помощь приветствуется. Я добавил некоторые макеты xml и фрагменты кода ниже, чтобы помочь.

<?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> 

Так что фрагменты кода, который представляет интерес:

@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, без хороших результатов:

How to translate the canvas and still get the touch events on the correct places

Android : click/touch event not working after canvas translate

ответ

0

Хорошо, хорошо ... Я нашел работу вокруг. В принципе, мой родительский вид (сам виджет) всегда мог видеть события касания. Но дети не могли дать обстоятельства, о которых я говорил выше. Итак, что я сделал, это отслеживать позиции x и y детского вида, которые я перетаскивал относительно области просмотра. Затем всякий раз, когда я получал событие касания, я бы проверял, не касался ли я детской области или нет. Если бы мне пришлось запускать onTouchEvent для ребенка, когда он был в своем старом расположении, я бы проигнорировал его, если он не прошел эту проверку. Его неряшливо, но это единственный способ заставить его работать. Теперь у меня есть подглядывающий вид и перетаскиваемый объект

0

Я не уверен, что я правильно понял все по вашей проблеме, но, возможно, это могло бы помочь вам View with horizontal and vertical pan/drag and pinch-zoom Вы должны попробовать код из ответа Алекса. Код делает некоторые дополнительные вещи, но вы можете просто взять скальпельустановку (для увеличения) и, конечно же, панорамирование по оси X. Этот код также перемещает дочерние элементы «внутри» холста, поэтому вам не нужно переводить позиции щелчка после вызова onTouch.

0

Лучшее решение - оставить свой взгляд на месте. Затем примените преобразование матрицы к вашему представлению и инвертированную матрицу в MotionEvents. Таким образом, вы всегда можете получить свое представление правильно и безжалостно делегировать свои события, и все панорамирование происходит на рисунке сцены. Перемещение представления вокруг также затронет в основном непроходимую проблему, из-за которой вы не можете получить MotionEvents, которые начинаются за пределами вашего реального вида.Поэтому, если вы уменьшите масштаб и нажмите что-то вне области, где на экране будет, он игнорирует это и не отправляет там события касания.

Кроме того, это выглядит безумным в некоторых реализациях, я думаю, что накладка 10 галактики, это было просто ужасно fubar и невозможно неправильно. Это делает недействительность представления немного иным, чем другие планшеты, и обновляет неправильные части представления.

Смежные вопросы