Hide a Floating Action Button of another Layout

扶醉桌前 提交于 2019-12-12 08:38:32

问题


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

回答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
}



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



来源:https://stackoverflow.com/questions/34065037/hide-a-floating-action-button-of-another-layout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!