FrameLayout上的onTouchListener:在外部单击时关闭它

时间:2016-07-06 08:43:56

标签: android ontouchlistener android-framelayout motionevent

我发现很难实现一个简单的功能。 我有一个包含下拉菜单的FrameLayout(就像WhatsApp中的那个,当你点击Attachment图标时弹出)。 当我在所述FrameLayout外面点击时,我想关闭它。

我正在尝试使用onTouch事件来实现它,但没有运气。

FrameLayout

我的代码:

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;
        }
    });

}

第一个Log.d()正在运行,表明已触发侦听器。 尽管如此,该方法还没有进入switch:我已经尝试了很多标志,没有运气。 我读过onInterceptTouchEventonTouchEvent,但我不知道如何使用它们代替OnTouchListener

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您的布局:

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

您的活动

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;
        }
    });
    ...

}

由于您的mRevealFrame未定义活动的全部FrameLayout,我们无法将其用于关闭mRevealView。请参阅我定义的mMainLayout,其中涵盖了现在可以使用的整个布局。

尝试一下,如果仍有问题请告诉我。

答案 1 :(得分:-1)

使用PopupWindow代替FrameLayout。它并不意味着以这种方式使用。

PopupWindow会做你想要的。

https://developer.android.com/reference/android/widget/PopupWindow.html