Hide a Floating Action Button of another Layout

12,788

Solution 1

First of all, change your line

final FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fabBtn);

to

fabBtn = (FloatingActionButton)findViewById(R.id.fabBtn);


Solution #1 - get view (if you need object)

Then, in your MainActivity add getter for your FloatingActionButton, like

public FloatingActionButton getFloatingActionButton {
    return fabBtn;
}

Finally, in your Fragment call:

FloatingActionButton floatingActionButton = ((MainActivity) getActivity()).getFloatingActionButton();

and

if (floatingActionButton != null) {
    floatingActionButton.hide();
}

or

if (floatingActionButton != null) {
    floatingActionButton.show();
}


Solution #2 - add two methods in MainActivity (if you need only specific methods, like show() / hide())

public void showFloatingActionButton() {
     fabBtn.show();
};

public void hideFloatingActionButton() {
     fabBtn.hide();
};

And in your Fragment call to hide:

((MainActivity) getActivity()).hideFloatingActionButton();

or to show:

((MainActivity) getActivity()).showFloatingActionButton();


Note

If you use more than one Activity, you must check if it's proper Activity:

if (getActivity() instanceof MainActivity) {
    getActivity().yourMethod(); // your method here
}

Solution 2

In your fragment your rootView layout is not main layout and you cannot expect the rootView will return the fab button. Thats why you are getting null pointer exception

You better use interface to detect page scrolling and controll it via your activity

Share:
12,788
Dolan
Author by

Dolan

Updated on June 29, 2022

Comments

  • Dolan
    Dolan almost 2 years

    I have a FloatingActionButton inside of may activity_main.xml layout which is named fabBtn.

    My application is built with a ViewPager and three Fragments.I want to hide the FloatingActionButton when my first Fragment detects a scroll, but I keep getting a NullPointerException if the user starts scrolling.

    I believe it could be that my fragment can't get the FloatingActionButton from the activity_main.xml layout?

    Here is my activity_main.xml

        <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/rootLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="lh.com.newme.MainActivity"
    xmlns:fab="http://schemas.android.com/tools">
    
        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:layout_scrollFlags="scroll|snap"/>
    
            <android.support.design.widget.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:tabMode="fixed"
                app:layout_scrollFlags="snap|enterAlways"/>
    
        </android.support.design.widget.AppBarLayout>
    
        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:background="#ffffff" />
    
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fabBtn"
            android:layout_marginBottom="@dimen/codelab_fab_margin_bottom"
            android:layout_marginRight="@dimen/codelab_fab_margin_right"
            android:layout_width="wrap_content"
            fab:fab_type="normal"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|right"
            app:backgroundTint="@color/fab_ripple_color"
            android:src="@drawable/ic_plus"
            app:fabSize="normal"
            />
    
        </android.support.design.widget.CoordinatorLayout>
    

    Here is my first Fragment from where I want to hide the FloatingActionButton:

        public class Ernaehrung extends Fragment {
    
    NestedScrollView nsv;
    FloatingActionButton fab;
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        setHasOptionsMenu(true);
    
        final View rootView = inflater.inflate(R.layout.ernaehrung, container, false);
        Button Fruehstuck = (Button) rootView.findViewById(R.id.fruehstuck);
        Button Mittagessen = (Button) rootView.findViewById(R.id.mittagessen);
        Button Snacks = (Button) rootView.findViewById(R.id.snacks);
    
        Fruehstuck.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent FruehstuckScreen = new Intent(getActivity(), lh.com.newme.Fruehstuck.class);
                startActivity(FruehstuckScreen);
            }
        });
    
        Mittagessen.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent MittagScreen = new Intent(getActivity(), lh.com.newme.Mittagessen.class);
                startActivity(MittagScreen);
            }
        });
    
        Snacks.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent SnackScreen = new Intent(getActivity(), lh.com.newme.Snacks.class);
                startActivity(SnackScreen);
            }
        });
    
        nsv = (NestedScrollView)rootView.findViewById(R.id.Nsv);
        fab = (FloatingActionButton)rootView.findViewById(R.id.fabBtn);
        nsv.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
            @Override
            public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                if (oldScrollY < scrollY){
    
                    fab.hide();
                }
    
            else
                    fab.show();}
    
    
        });
    
        return rootView;
    }
    
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        menu.clear();
        inflater.inflate(R.menu.main_menu_ernaehrung, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle presses on the action bar items
        int id = item.getItemId();
        if (id == R.id.benutzer){
    
        }
        return super.onOptionsItemSelected(item);
    }
    } 
    

    This is my MainActivity.class :

      public class MainActivity extends AppCompatActivity {
    
    
    FloatingActionButton fabBtn;
    CoordinatorLayout rootLayout;
    Toolbar toolbar;
    TabLayout tabLayout;
    
       ...
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        final ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        viewPager.setAdapter(new SampleFragmentPagerAdapter(getSupportFragmentManager()));
        viewPager.setOffscreenPageLimit(2);
    
        // Give the TabLayout the ViewPager
        final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabLayout);
        tabLayout.setupWithViewPager(viewPager);
    
        final FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fabBtn);
    
    
    
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }
    
            @Override
            public void onPageSelected(int position) {
    
                switch (position) {
                    case 0:
                        fab.show();
                        ...
                        break;
    
                    case 1:
                        fab.show();
                        ...
                        break;
    
    
                    case 2:
                        fab.hide();
                        break;
    
                    default:
                        fab.hide();
                        break;
                }
            }
    
            @Override
            public void onPageScrollStateChanged(int state) {
    
            }
        });
    
        initInstances();
    }
    
    private void initInstances() {
    
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setHomeButtonEnabled(true);
        rootLayout = (CoordinatorLayout) findViewById(R.id.rootLayout);
        fabBtn = (FloatingActionButton) findViewById(R.id.fabBtn);
    
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main_menu_edit, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
    
        //noinspection SimplifiableIfStatement
        if (id == R.id.einstellungen) {
            return true;
        }
    
        return super.onOptionsItemSelected(item);
    }
    }