问题
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);
}
}
回答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