【问题标题】:Android: Multiple snackbars in separate Fragments (ViewPager)Android:单独片段中的多个快餐栏(ViewPager)
【发布时间】:2016-03-31 14:52:13
【问题描述】:

我有一个浏览器,当然有一些片段。这些片段中的每一个都有 CoordinatorLayout 作为父级。

我正在展示一个小吃店。问题是,如果 Fragment A 显示一个snackbar 没问题,但如果它相邻的 Fragment B 也显示一个snackbar,那么 Fragment A 中的snackbar 会自动隐藏。

由于预先加载了 viewpager 相邻片段,这是一个明显的问题。任何解决方法?还是我做错了?

【问题讨论】:

  • 嗨 KalpitJain!你找到答案了吗?我也有同样的问题。
  • 2 岁了,我记不太清了。我想,解决方案是保持消息在每个片段的小吃栏中显示 - 并在该特定片段对用户(以及其他人)可见时显示它

标签: android android-fragments android-design-library android-snackbar


【解决方案1】:

ViewPager 中多个 Fragments 中的snackbar 存在一些问题

1) 如果在 Fragment A(可见)和 Fragment B(不可见)上显示了snackbar,则两个snackbar 都不可见。

2) 如果我使用 @Override setUserVisibleHint 和 getUserVisibleHint() 的组合来根据片段可见性巧妙地显示和隐藏小吃栏,它只会在第一次工作。之后,调用snackbar.show() 不再显示snackbar(除非我重新创建snackbar)。

以下是我提出的解决方案(已使用 v23.1.1 测试):

public class SnackbarManager {
    private static final String TAG = SnackbarManager.class.getName();

    private Snackbar snackbar;
    private Create instance;
    // private boolean isMultiSnackbar;

    public interface Create {
        Snackbar create();
    }

    public SnackbarManager(Create instance) {
        // why not pass in snackbar? coz snackbar.show will fail after 1st show (it multiple snackbar), thus need to recreate it
        snackbar = instance.create();
        this.instance = instance;
    }

    public void show(Fragment fragment) {
        if (fragment.getUserVisibleHint()) {
            snackbar.show();
        }
    }

    public void onSetUserVisibleHint(boolean isVisible) {
        if (isVisible) {
            if (snackbar == null) {
                snackbar = instance.create();
            }
            snackbar.show();
            Log.d(TAG, "showSnackbar="+snackbar.isShown());
            // if snackbar.isShown()=false, if means multiple snackbar exist (might or might not be in same fragment)
            /*
            boolean isMultiSnackbar = !snackbar.isShown();
            // the following is inaccurate when I manually dismiss one of the snackbar
            // even when isShown()=true, the snackbar is not shown
            if (isMultiSnackbar) {
                snackbar = null;
                snackbar = instance.create();
                snackbar.show();
            }
             */
            }
            else {
                Log.d(TAG, "dismissSnackbar");
                snackbar.dismiss();
                // subsequent show will fail, make sure to recreate next
                snackbar = null;
            }
        }
    }
}

public class TestFragment extends Fragment {
    private SnackbarManager snackbarManager;

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (snackbarManager != null)
            snackbarManager.onSetUserVisibleHint(isVisibleToUser);
    }

    public void showSnackbar() {
        snackbarManager = new SnackbarManager(new SnackbarManager.Create() {
            @Override
            public Snackbar create() {
                Snackbar snackbar = Snackbar.make(snackbarLayout, "Create your first moment ;)", Snackbar.LENGTH_INDEFINITE);
                snackbar.setAction("Create", new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        snackbarManager = null;
                    }
                });
                // enable following if not Snackbar.LENGTH_INDEFINITE
                /*
                snackbar.setCallback(new Snackbar.Callback() {
                    @Override
                    public void onDismissed(Snackbar snackbar, int event) {
                        super.onDismissed(snackbar, event);
                        snackbarManager = null;
                    }
                })
                */
                return snackbar;
            }
        });
        snackbarManager.show(this);
    }
}

【讨论】:

    【解决方案2】:

    您可以使用 setUserVisibleHint(boolean isVisible) 更新片段可见性(例如在您的 ViewPager onPageSelected 上),然后在片段上使用 getUserVisibleHint() 以仅在片段可见时显示 Snackbar。

    假设您有片段 A、B 和 C

    片段 A 可见,Snackbar 也是可见的 如果 Fragment B 或 C 尝试打开 Snackbar,getUserVisibleHint() 将返回 false,它们不会弄乱 Fragment A Snackbar。

    观察。使用 FragmentStatePagerAdapter 执行此操作时要小心,因为您可以让 NPE 保留对 Fragments 的引用并在此引用上调用 setUserVisibleHint()。

    编辑:你不需要 setUserVisibleHint() 因为它已经被系统调用了。

    【讨论】:

      猜你喜欢
      • 2017-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-07
      • 2019-09-10
      • 1970-01-01
      • 2016-07-04
      • 2016-03-04
      相关资源
      最近更新 更多