隐藏另一个布局中的浮动操作按钮

7

我在 activity_main.xml 中有一个名为 fabBtnFloatingActionButton

我的应用程序使用了 ViewPager 和三个 Fragment。我想要当第一个 Fragment 检测到滚动时隐藏 FloatingActionButton,但是如果用户开始滚动,我会遇到 NullPointerException 问题。

我认为这可能是因为我的 fragment 无法从 activity_main.xml 布局获取 FloatingActionButton

这是我的 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>

这是我的第一个Fragment,我想隐藏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);
}
} 

这是我的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);
}
}               
2个回答

24

首先,改变你的路线

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


解决方案#1-获取视图(如果需要对象)

然后,在您的MainActivity中添加获取器以获取您的FloatingActionButton,例如:

public FloatingActionButton getFloatingActionButton {
    return fabBtn;
}

最后,在您的 Fragment 调用中:

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

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

解决方案 #2 - 在 MainActivity 中添加两个方法(如果你只需要特定的方法,比如 show() / hide()


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

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

并且在你的Fragment调用中隐藏:

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

或者展示:

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


注意

如果您使用多个Activity,必须检查它是否适当:

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

1
在您的片段中,您的根视图布局不是主布局,您不能期望根视图将返回fab按钮。这就是为什么您会收到空指针异常的原因。
最好使用接口来检测页面滚动,并通过您的活动对其进行控制。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接