2011-04-13 20 views
11

Tengo una pantalla llena de botones, pero quiero que el método onTouch use todas las coordenadas de la pantalla. Primero intenté usar RelativeLayout con un OnTouchListener, pero nunca logré que se "conectara" con el oyente (es decir, no pasó nada cuando se tocó la pantalla), también intenté colocar un ImageView en la parte superior de la pantalla y luego hacer esta vista invisible .onTouchListener para toda la pantalla

Este último método dio respuestas correctas a onClicks, pero nunca logré hacerlo invisible.

Si esta es la mejor solución, que dudo mucho, ¿cómo hago que el ImageView sea totalmente invisible, sin perder su onTouchListener (he experimentado con white backgroundColor y setAlpha (0)).

¿Puedo de alguna manera hacer que el OnTouchListener reaccione a toda la pantalla, usando coordenadas globales, mientras la pantalla muestra (y altera) varios botones (preferiblemente sin la vista de imagen invisible)?

Si no entiende lo que estoy pidiendo, no dude en quejarse de eso. Trataré de llenar los vacíos según sea necesario.

Editar:

ahora he logrado resolver el problema utilizando el método onTouch-regular. Me encontré con varios problemas al hacer que ACTION_DOWN y ACTION_MOVE activaran los botones, pero finalmente lo hice funcionar. Para otras personas que lean esto: onInterceptTouchEvent podría usarse (pero nunca descubrí cómo obtener las coordenadas de la pantalla en lugar de las coordenadas de la vista).

Respuesta

8

Disculpe si me equivoco, pero creo que acabo de tener un problema similar. Quería una pantalla de título que mostrara una imagen y en las palabras que dicen "Haga clic para continuar" o algo similar. Me equivoqué un poco y descubrí que puedes hacer clic en un diseño.

android:focusable="true" 
    android:id="@+id/titlescreenframe"> 

está en mi archivo xml para mi diseño. La imagen de fondo no es más que en el atributo de fondo (me di cuenta que no está utilizando imágenes)

De todos modos, de vuelta en mi actividad

private FrameLayout fl; 
    ... 
    fl = (FrameLayout)findViewById(R.id.titlescreenframe); 
    fl.setOnClickListener(this); 

Y entonces utilizar una sentencia switch para manejar eso y los botones que están en el siguiente diseño. Aquí si lo necesita: Using Switch Statement to Handle Button Clicks

Parece que esto debería funcionar con otros diseños también, y no tengo literalmente ninguna vista en mi diseño principal. (a menos que el diseño mismo cuente como uno)

¡Ja! Solo me di cuenta de que dijiste que encontraste la solución. Tonto tiempo. Voy a publicar por si esto ayuda a alguien, feliz de codificar a todos. :)

+2

si su objetivo es más nuevo que 1.6, puede usar android: onClick = "nombre de función" directamente en lugar de establecer enfocable y asignar oyente onclick en el código. – Yenchi

3

¿Has probado onInterceptTouchEvent en el diseño?

+0

Dsouza lo probé, pero no estaba satisfecho. Ahora he logrado resolver el problema utilizando el método onTouch regular. Me encontré con varios problemas al hacer que ACTION_DOWN y ACTION_MOVE activaran los botones, pero finalmente lo hice funcionar. Para otras personas que lean esto: onInterceptTouchEvent podría usarse (pero nunca descubrí cómo obtener las coordenadas de la pantalla en lugar de las coordenadas de la vista). – keyser

3

He usado dispatchTouchEvent para un problema similar. Podría considerarlo un reemplazo directo para onTouchEvent, excepto que siempre le envía un evento, incluso si se trata de una vista existente.

Devuelve verdadero si está manejando el evento, de lo contrario, asegúrese de llamar al super.dispatchTouchEvent() y devolver su resultado.

En cuanto a obtener coordenadas de pantalla - simplemente llamado de getRawX() y getRawY() en lugar de getX() y getY() la MotionEvent. Esas son las coordenadas absolutas de la pantalla, incluida la barra de acciones y todo. Si desea hacer una referencia cruzada con vistas, getLocationOnScreen es probablemente la solución más fácil.

1

toque el evento regresa a vistas secundarias primero. y si define onClick o onTouch listener para ellos, parnt view (por ejemplo, fragmento) no recibirá ningún detector táctil. Así que si quieres definir oyente golpe para el fragmento en esta situación, debe ponerla en práctica de una nueva clase:

package com.neganet.QRelations.fragments; 

import android.content.Context; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.widget.FrameLayout; 

public class SwipeListenerFragment extends FrameLayout { 
    private float x1,x2; 
    static final int MIN_DISTANCE=150; 
    private onSwipeEventDetected mSwipeDetectedListener; 


    public SwipeListenerFragment(Context context) { 
     super(context); 
    } 

    public SwipeListenerFragment(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public SwipeListenerFragment(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent ev) { 
     boolean result=false; 
     switch(ev.getAction()) 
     { 
      case MotionEvent.ACTION_DOWN: 
       x1 = ev.getX(); 
       break; 
      case MotionEvent.ACTION_UP: 
       x2 = ev.getX(); 
       float deltaX = x2 - x1; 
       if (Math.abs(deltaX) > MIN_DISTANCE) 
       { 
        if(deltaX<0) 
        { 
         result=true; 
         if(mSwipeDetectedListener!=null) 
          mSwipeDetectedListener.swipeLeftDetected(); 

        }else if(deltaX>0){ 
         result=true; 
         if(mSwipeDetectedListener!=null) 
          mSwipeDetectedListener.swipeRightDetected(); 
        } 
       } 
       break; 
     } 
     return result; 
    } 

    public interface onSwipeEventDetected 
    { 
     public void swipeLeftDetected(); 
     public void swipeRightDetected(); 

    } 

    public void registerToSwipeEvents(onSwipeEventDetected listener) 
    { 
     this.mSwipeDetectedListener=listener; 
    } 
} 

Usted puede hacer que los implementos para otros tipos de diseños completamente como esta. esta clase puede detectar tanto deslizamiento hacia la derecha como hacia la izquierda y especialmente devuelve onInterceptTouchEvent true after detect. es importante porque si no lo hacemos, algunas veces las vistas secundarias pueden recibir eventos y tanto Swipe for fragment como onClick for child view (por ejemplo) se ejecutan y causan algunos problemas. después de hacer esta clase, debe cambiar su fragmento de archivo xml:

<com.neganet.QRelations.fragments.SwipeListenerFragment xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" 
    android:id="@+id/main_list_layout" 
    android:clickable="true" 
    android:focusable="true" 
    android:focusableInTouchMode="true" 
    android:layout_height="match_parent" tools:context="com.neganet.QRelations.fragments.mainList" 
    android:background="@color/main_frag_back"> 

    <!-- TODO: Update blank fragment layout --> 
    <android.support.v7.widget.RecyclerView 
     android:id="@+id/farazList" 
     android:scrollbars="horizontal" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_gravity="left|center_vertical" /> 
</com.neganet.QRelations.fragments.SwipeListenerFragment> 

ves que empiezan etiqueta es la clase que hicimos. ahora en la clase fragmento:

  View view=inflater.inflate(R.layout.fragment_main_list, container, false); 
     SwipeListenerFragment tdView=(SwipeListenerFragment) view; 
     tdView.registerToSwipeEvents(this); 


and then Implement SwipeListenerFragment.onSwipeEventDetected in it: 

     @Override 
    public void swipeLeftDetected() { 
     Toast.makeText(getActivity(), "left", Toast.LENGTH_SHORT).show(); 
    } 

    @Override 
    public void swipeRightDetected() { 
     Toast.makeText(getActivity(), "right", Toast.LENGTH_SHORT).show(); 
    } 

Es un poco complicado, pero funciona perfecto :)

Cuestiones relacionadas