Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing an OnClickListener on a view remove all touch events on the views behind

I have a top bar layout with a header, a vertical menu and a transparent background view.

When the btn_menu is pressed, the vertical menu is opened using an animation. When the menu is open, I set an OnClickListener on the transparent background view which closes the menu when the transparent background is clicked. When closing the menu, I remove the OnClickListener from the background view, using:

mTopBarBg.setOnClickListener(null);

The problem is that it seems to remove all the touch events of the views behind it (set in the content_container of the main layout). Eg. a ViewPager which does not detect swipe anymore, or a ListView which does not scroll and can't be clicked anymore, while they worked correctly before.

What's wrong?

in top bar fragment

private void toggleMenu(int duration){
    if(mMenuIsOpen){

        TranslateAnimation anim1 = new TranslateAnimation(0,0,0,-(mHeight-mMenuVerticalOffset));
        anim1.setFillAfter(true);
        anim1.setDuration(duration);
        mVerticalMenu.setAnimation(anim1);

        AlphaAnimation anim2 = new AlphaAnimation(0.7f, 0.0f);
        anim2.setFillAfter(true);
        anim2.setDuration(duration);
        mTopBarBg.setAnimation(anim2);

        mTopBarBg.setOnClickListener(null);

        mMenuIsOpen = false;
    }
    else{

        TranslateAnimation anim1 = new TranslateAnimation(0,0,-(mHeight-mMenuVerticalOffset),0);
        anim1.setFillAfter(true);
        anim1.setDuration(duration);
        mVerticalMenu.setAnimation(anim1);

        AlphaAnimation anim2 = new AlphaAnimation(0.0f, 0.7f);
        anim2.setFillAfter(true);
        anim2.setDuration(duration);
        mTopBarBg.setAnimation(anim2);

        mTopBarBg.setOnClickListener(mBgClickListener);

        mMenuIsOpen = true;
    }
}

main layout

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

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/mainbg" 
        android:scaleType="centerCrop"/>

    <FrameLayout
        android:id="@+id/content_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingTop="44dp" />

    <FrameLayout
        android:id="@+id/top_bar_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipChildren="false" />

</RelativeLayout>

top bar layout

<RelativeLayout 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:background="#00000000" >

    <View
        android:id="@+id/top_bar_bg"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#000000"
        android:visibility="gone" />

    <LinearLayout
        android:id="@+id/vertical_menu"
        android:layout_width="50dp"
        android:layout_height="match_parent"
        android:layout_marginTop="44dp"
        android:background="#ffffff"
        android:orientation="vertical"
        android:visibility="gone" >

        <!-- vertical menu layout -->

    </LinearLayout>

    <RelativeLayout
        android:id="@+id/header"
        android:layout_width="match_parent"
        android:layout_height="44dp"
        android:background="#ffffff" >

        <Button
            android:id="@+id/btn_menu"
            android:layout_width="50dp"
            android:layout_height="44dp"
            android:background="@drawable/menubtn" />       

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="44dp"
            android:layout_toRightOf="@id/btn_menu"
            android:gravity="center" >

            <ImageView
                android:layout_width="130dp"
                android:layout_height="44dp"
                android:src="@drawable/logo" />
        </LinearLayout>
    </RelativeLayout>

</RelativeLayout>

top bar with menu open

enter image description here

like image 432
jul Avatar asked Apr 17 '13 17:04

jul


2 Answers

Instead of removing onClickListener you can do one thing.Always set the onClickListener and use a boolean variable to trace the menu on and off. So your code will be something like

 boolean is_menu_open = false;
 public void onClick(View v){
        if(is_menu_open){
             hidemenu;
             is_menu_open = false;
        } else
             do nothing
  }

and whenever you shows the menu then set is_menu_open to true

like image 30
stinepike Avatar answered Sep 23 '22 15:09

stinepike


Try to also use setClickable(false) on your overlay View. Using the setOnClickListener() method makes the View clickable and this probably "eats" your future events(even after using null as that doesn't modify the previous set clickable property).

As a side not your layout is very complicated in relation to what you try to do. More precisely the layout is deeper than it should be. There is no point in having a FrameLayout container when it has the same properties as the RelativeLayout of your bar(you could use an include tag to include the bar without the need for that extra FrameLayout). You coud also lose the top_bar_bg View and set the listener directly on the root RelativeLayout. Last, the inner RelativeLayout(header) could be removed and replaced by properly positioning the child views in the root Relativelayout with a white empty View under them(with the appropriate dimensions to simulate the white background).

like image 173
user Avatar answered Sep 24 '22 15:09

user