Dolan Dolan - 28 days ago 11
Android Question

Hide a Floating Action Button of another Layout

I have a

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

My application is built with a
ViewPager
and three
Fragment
s.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);
}
}

Answer

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