2016-07-06 2 views
0

Je trouve difficile d'implémenter une fonctionnalité probablement simple. J'ai un FrameLayout contenant un menu déroulant (comme celui de WhatsApp, apparaissant lorsque vous cliquez sur l'icône Pièce jointe). Je veux le fermer quand je clique à l'extérieur de ce FrameLayout. J'essaye de l'implémenter en utilisant un événement d'onTouch, sans la chance.onTouchListener sur FrameLayout: fermez-le lorsque vous cliquez dessus

FrameLayout

Mon code:

public class MainActivity extends AppCompatActivity { 

private LinearLayout mRevealView; 
private FrameLayout mRevealFrame; 

... 

@Override 
protected void onCreate(Bundle savedInstanceState) { 

    ... 

    mRevealView = (LinearLayout) findViewById(R.id.rows); 
    mRevealFrame = (FrameLayout) findViewById(R.id.reveal_frame); 

    ... 

} 

// This method is called when I click on the right menu icon. 
public void fuelTypes() { 
    // Looking for X and Y coordinates. 
    int cx = (mRevealView.getLeft() + mRevealView.getRight()); 
    int cy = (mRevealView.getTop()); 

    // Looking for radius when icon is tapped for showing layout. 
    int startRadius = 0; 
    int endRadius = Math.max(mRevealView.getWidth(), mRevealView.getHeight()); 

    // Performing circular reveal when icon will be tapped. 
    Animator animator = ViewAnimationUtils.createCircularReveal(mRevealView, cx, cy, startRadius, endRadius); 
    animator.setInterpolator(new AccelerateDecelerateInterpolator()); 
    animator.setDuration(400); 

    // Reverse animation to find radius when icon is tapped again for hiding layout. 
    // The starting radius will be the radius or the extent to which circular reveal animation is to be shown. 
    int reverseStartRadius = Math.max(mRevealView.getWidth(), mRevealView.getHeight()); 

    // End - radius will be zero. 
    int reverseEndRadius = 0; 

    // Performing circular reveal for reverse animation. 
    Animator animate = ViewAnimationUtils.createCircularReveal(mRevealView, cx, cy, reverseStartRadius, reverseEndRadius); 

    if (hidden) { 
     // To show the layout when the icon is tapped. 
     mRevealView.setVisibility(View.VISIBLE); 
     mRevealFrame.setVisibility(View.VISIBLE); 
     animator.start(); 
     hidden = false; 
    } else { 
     mRevealView.setVisibility(View.VISIBLE); 
     mRevealFrame.setVisibility(View.VISIBLE); 

     // To hide layout on animation end. 
     animate.addListener(new AnimatorListenerAdapter() { 

      @Override 
      public void onAnimationEnd(Animator animation) { 
       super.onAnimationEnd(animation); 
       mRevealView.setVisibility(View.INVISIBLE); 
       mRevealFrame.setVisibility(View.INVISIBLE); 
       hidden = true; 
      } 

     }); 

     animate.start(); 
    } 

    mRevealFrame.setOnTouchListener(new FrameLayout.OnTouchListener() { 
     @Override 
     public boolean onTouch(View view, MotionEvent motionEvent) { 
      Log.d("MOTION_EVENT", "getAction(): " + motionEvent.getAction()); 

      switch (motionEvent.getAction()) { 

       case MotionEvent.ACTION_UP: 
        Log.d("REVEAL_FRAME", "motion event: " + "ACTION_UP"); 
        fuelTypes(); 
        return true; 

      } 

      return true; 
     } 
    }); 

} 

Le premier Log.d() travaille, montrant que l'auditeur est déclenchée. Pourtant, la méthode ne va pas à l'intérieur du switch: j'ai déjà essayé beaucoup de drapeaux, sans chance. J'ai lu environ onInterceptTouchEvent et onTouchEvent, mais je ne sais pas comment les utiliser à la place du OnTouchListener.

Nous vous remercions de votre aide.

+0

essayer de vous déboguer programme et voir la différence entre MotionEvent.ACTION_CANCEL et valeur à l'intérieur motionEvent.getAction() –

+0

ACTION_CANCEL a un id = 3, alors que je ne peux voir un identifiant pour la FrameLayout en cliquant à l'intérieur de lui (habituellement les ids sont égaux à 0 et 1). – Davide3i

Répondre

1

Votre mise en page:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:id="@+id/main_layout"  // give id here 
tools:context="com.myfuel.MainActivity"> 

<include layout="@layout/activity_main"/> 

<FrameLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:id="@+id/reveal_frame" 
    android:layout_marginTop="?attr/actionBarSize"> 

    // EVERYTHING INSIDE THIS WILL BE AS IT IS 

</FrameLayout> 

</FrameLayout> 

Votre activité

public class MainActivity extends AppCompatActivity { 

private LinearLayout mRevealView; 
private FrameLayout mRevealFrame; 
private FrameLayout mMainLayout; 
... 

@Override 
protected void onCreate(Bundle savedInstanceState) { 

    ... 

    mRevealView = (LinearLayout) findViewById(R.id.rows); 
    mRevealFrame = (FrameLayout) findViewById(R.id.reveal_frame); 
    mMainLayout = (FrameLayout) findViewById(R.id.main_layout); 

    mMainLayout.setOnTouchListener(new FrameLayout.OnTouchListener() 
    { 
     @Override 
     public boolean onTouch(View view, MotionEvent motionEvent) { 
      Log.d("MOTION_EVENT", "getAction(): " + motionEvent.getAction()); 

        //Things changed here      

        if(!hidden) 
         fuelTypes(); 


      return false; 
     } 
    }); 
    ... 

} 

Comme votre mRevealFrame ne définit pas l'ensemble FrameLayout de votre activité, nous ne pouvons pas l'utiliser pour fermer mRevealView. Voir j'ai défini mMainLayout qui couvre la mise en page ENTIER, il va travailler maintenant. Essayez-le et faites-moi savoir s'il y a toujours un problème.

+0

Cela ne semble pas résoudre mon problème, car lorsque je clique en dehors de FrameLayout, le journal n'affiche aucun message. Maintenant, mon menu ne disparaît que lorsque je clique sur le FrameLayout lui-même. – Davide3i

+0

1. Nous avons défini l'écouteur tactile sur 'mRevealFrame' si vous cliquez sur le côté' mRevealFrame' de toute évidence il ne générera pas de journal. 2. ** Maintenant, mon menu ne disparaît que lorsque je clique sur le FrameLayout lui-même ** pour cette senetence je dois comprendre votre exigence entière non seulement le 'touchListner '. –

+0

Je vais mettre à jour la réponse avec une image. Je vais essayer de ré-expliquer mon objectif: fermer le menu déroulant comme WhatsApp quand je clique à l'extérieur de la FrameLayout le contenir (= cliquer dans tous les autres endroits de mon activité). Nous vous remercions de votre aide. – Davide3i