具有不同菜单和通用工具栏的 Viewpager 无法正常工作

2023-12-11

我的应用程序中有选项卡。每个选项卡都有不同的片段,并且有不同的菜单。下面是我正在使用的布局

    <?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/background">

            <include
                layout="@layout/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_scrollFlags="scroll|enterAlways" />


        </android.support.design.widget.AppBarLayout>

        <com.CustomViewPager
            android:id="@+id/view_pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tab_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="end"
            android:background="@color/background"
            app:layout_anchor="@id/view_pager"
            app:layout_anchorGravity="bottom|center_horizontal"
            app:layout_behavior="com.widget.ScrollTabBehavior"
            app:tabBackground="@color/background"
            app:tabIndicatorColor="@color/toolbar"
            app:tabIndicatorHeight="0dp"
            app:tabMode="fixed"
            app:tabPaddingEnd="0dp"
            app:tabPaddingStart="0dp" />

    </android.support.design.widget.CoordinatorLayout>

    <RelativeLayout
        android:id="@+id/left_drawer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:layout_marginLeft="-64dp"
        android:layout_marginStart="-64dp"
        android:background="@color/toolbar"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp">

        <ImageButton
            android:id="@+id/close_btn"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:background="@android:color/transparent"
            android:padding="5dp"
            android:src="@drawable/close_icon" />

        <view
            android:id="@+id/drawerlist"
            class="android.support.v7.widget.RecyclerView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/close_btn" />

    </RelativeLayout>
</android.support.v4.widget.DrawerLayout>

现在每个片段都在onCreate()我已经提到过setHasOptionsMenu(true);此外。我已经重写了该函数onCreateOptionsMenu()在每个片段中都有menu.clear();首先,然后调用它的超级构造函数,然后膨胀片段自己的菜单 xml。但我得到的结果是这样的 -

  • 假设有 5 个选项卡。第二个和第三个选项卡中都有 viewpager,每个选项卡中还包含两个片段
  • 第一个选项卡没有菜单
  • 第二个选项卡有 menu_2 (仅适用于第二个子片段)
  • 第三个选项卡再次没有菜单
  • 第四个选项卡有 menu_4 (仅适用于第一个子片段)
  • 第 5 个选项卡有 menu_5
  • 最初,选项卡 1 不应该有菜单,这是可以的。然后直接移动到第三个选项卡,它显示 menu_4,默认情况下不应显示菜单。然后滑动到选项卡 4,它将显示正确的 menu_4,然后滑回第三个选项卡,它将不显示菜单(这是根据需要的)。
  • 选项卡 5 也会发生同样的情况。如果我切换到第二个选项卡中的第二个子片段,则在第一个选项卡中会观察到相同的行为。

简而言之,根据我的观察,它显示了相邻选项卡的菜单,该菜单实际上是在当前片段之后执行的,因此正在发生这种行为。

那么如何避免这种情况呢?


我编写了小型测试应用程序来检查行为。

enter image description here

让我们看一下示例,看看您的片段是否有问题(如您在上面看到的,具有不同菜单的 ViewPager 工作起来就像一个魅力)

Activity's XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_below="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

Activity班级。重要的部分是invalidateOptionsMenu()每次ViewPager有 PageSelected 事件。然后,我们设置setHasOptionsMenu到所有片段和子片段(从嵌套的ViewPagers) to false如果他们走出屏幕。

public class MainActivity extends AppCompatActivity {

    PagerAdapter pagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Fragment[] fragments = {
                Fragment.instantiate(this, FragmentNoMenu.class.getName()),
                Fragment.instantiate(this, FragmentA.class.getName()),
                Fragment.instantiate(this, FragmentNoMenu.class.getName()),
                Fragment.instantiate(this, FragmentB.class.getName()),
        };

        TabLayout tabLayout = (TabLayout)findViewById(R.id.tabLayout);
        ViewPager viewPager = (ViewPager)findViewById(R.id.viewPager);
        pagerAdapter = new PagerAdapter(getSupportFragmentManager(), fragments);
        viewPager.setAdapter(pagerAdapter);
        viewPager.setOffscreenPageLimit(0);
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
            @Override
            public void onPageSelected(int position) {
                invalidateOptionsMenu(position);
            }
            @Override
            public void onPageScrollStateChanged(int state) {}
        });

        invalidateOptionsMenu(0);
        tabLayout.setupWithViewPager(viewPager);
    }

    private void invalidateOptionsMenu(int position) {
        for(int i = 0; i < pagerAdapter.getCount(); i++) {
            Fragment fragment = pagerAdapter.getItem(i);
            fragment.setHasOptionsMenu(i == position);

            if (fragment instanceof FragmentWithViewPager) {
                FragmentWithViewPager fragmentWithViewPager = (FragmentWithViewPager)fragment;
                if (fragmentWithViewPager.pagerAdapter != null) {
                    for (int j = 0; j < fragmentWithViewPager.pagerAdapter.getCount(); j++) {
                        fragmentWithViewPager.pagerAdapter.getItem(j).setHasOptionsMenu(i == position);
                    }
                }
            }
        }

        invalidateOptionsMenu();
    }
}

PagerAdapter class:

public class PagerAdapter extends FragmentPagerAdapter {

    private final Fragment[] fragments;

    public PagerAdapter(FragmentManager fragmentManager, Fragment[] fragments) {
        super(fragmentManager);
        this.fragments = fragments;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return fragments[position].getClass().getSimpleName();
    }

    @Override
    public Fragment getItem(int position) {
        return fragments[position];
    }

    @Override
    public int getCount() {
        return fragments.length;
    }
}

这是我使用的测试片段:

FragmentNoMenu class:

public class FragmentNoMenu extends android.support.v4.app.Fragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_no_menu, container, false);
    }
}

FragmentNoMenu layout:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="#0F0F50"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

FragmentA类是一个带有嵌套 ViewPager 的 Fragment:

public class FragmentA extends FragmentWithViewPager {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_a, container, false);

        Fragment[] fragments = {
                Fragment.instantiate(getContext(), SubFragmentA.class.getName()),
                Fragment.instantiate(getContext(), SubFragmentB.class.getName()),
                Fragment.instantiate(getContext(), SubFragmentC.class.getName()),
        };

        if (pagerAdapter == null) {
            pagerAdapter = new PagerAdapter(getChildFragmentManager(), fragments);
        }

        viewPager = (ViewPager)rootView.findViewById(R.id.viewPager);
        viewPager.setAdapter(pagerAdapter);
        return rootView;
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.fragment_a, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }
}

FragmentA的布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="#B0B0B0"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_marginTop="80dp"
        android:layout_width="match_parent"
        android:layout_height="200dp"/>
</FrameLayout>

FragmentA's menu:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_item_1"
        android:title="Item 1"
        android:orderInCategory="250"
        app:showAsAction="never" />

    <item
        android:id="@+id/action_item_2"
        android:title="Item 2"
        android:orderInCategory="300"
        app:showAsAction="never" />
</menu>

NB! FragmentA延伸FragmentWithViewPager- 这是一个小的扩展Fragment为了更容易区分 MainActivity 中嵌套片段的片段:

public class FragmentWithViewPager extends Fragment {
    PagerAdapter pagerAdapter;
    ViewPager viewPager;
}

FragmentB:

public class FragmentB extends Fragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_b, container, false);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.fragment_b, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }
}

它的布局和菜单:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="#999999"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

.....

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_item3"
        android:title="Item 3"
        android:icon="@drawable/ic_triage_star"
        android:orderInCategory="250"
        app:showAsAction="always" />
</menu>

子片段(从代码角度来看它们看起来都是一样的):

Layouts:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="#AA0000"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:text="SubFragment C (with icon Menu)"
        android:textSize="24sp"
        android:textColor="#00BB00"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</FrameLayout>

Code:

public class SubFragmentB extends Fragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.subfragment_b, container, false);
    }
}

就是这样!我已将项目上传到我的保管箱 -请随意查看!

我希望,它有帮助

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有不同菜单和通用工具栏的 Viewpager 无法正常工作 的相关文章

  • 如何使用导航组件在单一活动设计中使用偏好?

    我想使用导航组件迁移到单一活动设计 我正在使用一项活动 其他活动是片段 对于某些屏幕 我只有布局 没有偏好 使碎片膨胀没有问题 但当我尝试按偏好工作时 我遇到了问题 我的要求是 我需要在片段中膨胀工具栏和首选项列表 我的做法 使用以下代码添
  • Android短音的正确播放方法?

    我正在创建一个应用程序 屏幕上将有多个图像 这些图像将是按钮 点击时会播放短促的声音 我对此进行了研究 只能找到我当前用来播放声音的方法 这似乎根本没有响应 我希望声音能够快速播放并且能够响应多次快速点击 我不确定这在 Android 中是
  • Cheesesquare:enterAlways 会产生错误的布局

    Adding enterAlways到 Cheesesquare 演示的滚动标志
  • Xamarin Android Webview Javascript

    我正在尝试通过 Xamarin for Android 创建一个移动应用程序 它有一个显示网站的 WebView 问题是正常按钮会触发 但 javascript 事件不会触发 我已经启用了 Javascript 但没有运气 如何在 Andr
  • 如何在android中显示保存在sdcard文件夹中的图像[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 当我正在显
  • fetchUuidsWithSdp 的奇怪 UUID 逆转

    我有一个在树莓派上运行的 python 蓝牙服务器 使用 PyBluez 我在服务器中使用的uuid是 8f86d132 4ab8 4c15 b8df 0b70cf10ea56 我正在打电话device fetchUuidsWithSdp
  • 如何在 Linux 内核中定义并触发我自己的新软中断?

    我想在 Linux 内核中创建自己的软中断 这是正确的方法吗 In the init我想触发该模块的softirq我将添加一个调用 394 void open softirq int nr void action struct softir
  • Recyclerview 动态部分不使用任何第三个库

    我想将标头添加到 recyclerview 我正在尝试使用来实现它 Override public int getItemViewType int position depends on your problem if position 0
  • 自定义首选项中的android首选项水平分隔线?

    我创建了自己的自定义首选项对象来扩展首选项 我创建它们只是因为这些自定义数据类型没有首选项 一切正常 但我的自定义首选项没有相同的外观 因为它们缺少系统首选项对象具有的水平分隔线 我已经查找了创建水平分隔线的代码 但我找不到它是在哪里完成的
  • 如何重定向到 instagram://user?username={username}

    我的 html 页面上有这个链接 可以在特定用户上打开 Instagram 应用程序 a href Link to Instagram Profile a 我一直在寻找自动运行 url instagram user username USE
  • 当它的父级是 ConstraintLayout 时设计 CardView 吗?

    我在编辑包含Relativelayout的Cardview内的RelativeLayout时搞砸了 ConstraintLayout会将相对布局的wrap content更改为0并添加工具 layout editor absoluteX 1
  • 在 android 中建立与 MySQL 的池连接

    我需要从我的 Android 应用程序访问 MySQL 数据库 现在所有的工作都通过 DriverManager getConnection url 等等 但我必须从多个线程访问数据库 所以我必须使用连接池 问题1 是 com mysql
  • Android:后台Activity可以执行代码吗?

    后台的活动是否被视为 正在运行 并且可以执行代码 还是处于挂起状态 他们暂停了 活动生命周期 http developer android com reference android app Activity html ActivityLi
  • Android 手机作为 GSM 调制解调器在 PC 上发送/接收短信?

    是否可以将 Android 移动设备用作 PC 上的 GSM 调制解调器 我正在 net下开发应用程序来发送 接收短信等 现在我想通过 USB 将我的 Android 设备连接到我的 PC 并将其用作 GSM 调制解调器来与其通信 这里是参
  • 当 OnFocusChangeListener 应用于包装的 EditText 时,TextInputLayout 没有动画

    不能比标题说得更清楚了 我有一个由文本输入布局包裹的 EditText 我试图在 EditText 失去焦点时触发一个事件 但是 一旦应用了事件侦听器 TextInputLayout 就不再对文本进行动画处理 它只是位于 editText
  • Android 中如何通过彩信发送图片?

    我正在开发多媒体应用程序 我正在通过相机捕获一张图像 并希望将该图像和文本发送到其他号码 但我不知道如何通过彩信发送图像 MMS 只是一个 http post 请求 您应该使用执行请求额外的网络功能 final ConnectivityMa
  • Android 2.3 模拟器在更新位置时崩溃

    我正在使用 Eclipse 编写和调试 Android 应用程序 我需要做的事情之一是更新设备的位置 因此我尝试使用模拟器控制窗口中的位置控制面板 在 手动 选项卡上 我选择 十进制 输入有效的纬度和经度 然后单击 发送 不幸的是 接下来发
  • Android 中的处理程序与异步调用

    目前我正在使用处理程序来调用 Web 服务方法以使其在后台运行 问题是它需要更多的时间来给出响应 在性能方面似乎更昂贵 现在我计划使用异步调用 哪一个是最好的 Android 中的处理程序和异步调用有什么区别 请帮我想出一个最好的解决方案
  • 插件“Android Bundle Support”不兼容

    大家好 自从上次更新以来 当我启动 android studio 时 我遇到了一个非常奇怪的错误 我有这个错误 插件错误 插件 Android Bundle Support 不兼容 直到构建 AI 195 SNAPSHOT 我在网上找不到任
  • 错误:(23, 13) 无法解决:com.google.android.gms:play-services:11.2.0“安装存储库和同步项目”不起作用

    我正在尝试在我的 Android 应用程序中获取位置并更新到服务器 这是我的 Gradle 代码 我在这里包含了compile com google android gms play services 11 2 0 这条线是从文档中 htt

随机推荐

  • Mechanize 不显示 FB 消息表单

    import mechanize cookielib br mechanize Browser cookie jar cookielib CookieJar br set cookiejar cookie jar br addheaders
  • Android同步cookies webview和httpclient

    我有一个登录 webview 和 httpclient 需要确认用户是否登录 问题是 webview 和 httpclient 正在使用其他 cookie 因此 httpclient 无法获取 webview cookie 我读了很多人的问
  • 更改 Html.TextBox 的大小

    我正在使用新的 Razor 视图引擎开发 ASP NET MVC3 应用程序 但在更改 TextBox 使其成为多行时遇到一些困难 到目前为止 我通过谷歌找到的只是我需要将多行属性设置为 true 但我不知道如何设置 查看代码如下所示 di
  • Java 绑定异常

    即使重用地址设置为 true 什么会导致 TCP 套接字抛出 java net BindException 地址已在使用中 仅当应用程序快速重新启动时才会发生这种情况 在 CentOS 5 Linux 操作系统上运行 这有点解释它 http
  • Tinymce 与 Angular 2/4 的双向绑定

    这是我的tinymce component ts import Component OnDestroy AfterViewInit EventEmitter Input Output from angular core Component
  • 如何为 Web 客户端打开自动重定向

    我有这个代码 class CustomWebclient WebClient System Security SecuritySafeCritical public CustomWebclient base public CookieCon
  • FastMember列顺序保存

    使用 TypeAccessor Create FastMember 时似乎总是返回按字母顺序排序的列列表 是否可以告诉它保留类中列的顺序 例如 var testClass new B 1 A 2 将从 GetMembers 返回 A 列 然
  • 如何使用 JWT 授权 SignalR Core Hub 方法

    我在 ASP NET Core 2 0 应用程序中使用 OpenIddict 进行 JWT 身份验证 我正在遵循的想法这个线程并打电话AuthorizeWithJWTSignalR 握手后的方法 但现在我不知道我应该设置什么Authoriz
  • 尝试修复 AVAudioPlayer 初次使用时的滞后问题

    这个问题已经出现在其他几个问题中 第一次播放声音时 AVAudioPlayer 启动缓慢 使用 AVAudioPlayer 播放声音时出现延迟 我已尝试实施建议的修复 但没有一个能解决我的问题 我的应用程序向用户呈现一系列可供触摸的对象 当
  • 如何使用 JavaScript 正则表达式进行跨换行匹配?

    我有这样的表达 document ready function validator addMethod regex function value element return this optional element www http c
  • 如何根据用户的请求暂停和恢复多个 Java 线程?

    我正在创建一个 20 分钟倒计时器应用程序 我正在使用 JavaFX SceneBuilder 来执行此操作 计时器由两个标签组成 一个代表分钟 一个代表秒 每个标签由一个CountdownTimer类对象 和进度条 计时器看起来像this
  • C++ 中的 char* 和 cin

    我想使用 cin 将不定长度的字符串输入到 char 变量中 我可以做这个 char tmp My string cout lt lt tmp lt lt endl system pause 它工作完美 但我没能做到这一点 char tmp
  • Socket.IO node.js websocket连接无效端口8081

    我在这个论坛上看到过一些关于 Socket IO 和 node js 的帖子 但仍然没有达到最佳工作状态 我的网络服务器将端口 80 和端口 8080 用于不同的应用程序 因此 在 App js 和我的套接字连接中 我添加了端口 8081
  • 我无法在框架布局内移动按钮

    我尝试使用图形界面和 XML 文件中的 android layout alignParentLeft 移动按钮 无论如何它不起作用 我的Android Studio版本是2 2 3 你有遇到过这个问题吗 你需要相对布局或其他与父容器类似的布
  • MySQL Workbench 获得管理访问权限吗?

    我从一个月开始就运行 MySQL 5 6 一切都很顺利 还有 MySQL Workbench 6 如果我想查看 服务器状态 我会收到两个错误 第一个错误 Could not acquire management access for adm
  • 如何获取从一个集合到另一个集合的数据引用?蒙古数据库

    router get productSelect req res next gt productSchema aggregate lookup from supplierSchema localField supplierId foreig
  • 带有前导零的数字的奇怪行为[重复]

    这个问题在这里已经有答案了 我有一些带有一些整数的 PHP 代码 并且一切正常 除非我有08 or 0X作为整数 当我把它们放在引号中时 一切都很好 示例数字 2 Works fine 08 Doesn t work 012 Doesn t
  • java中如何将json对象转换为HTML格式?

    java中如何将json对象转换为HTML 此代码将任何 Json 对象显示为 HTML 使用 org json lib Get the JSON data formated in HTML public String getHtmlDat
  • Swift 中导入 NS_OPTIONS (RawOptionSetType) 的 Switch 语句?

    Swift 中的 switch 语句更具表现力 我想知道这是否可能 让我们看看 UIViewAutoresizing 的例子 它在 Objective C 中的定义如下 typedef NS OPTIONS NSUInteger UIVie
  • 具有不同菜单和通用工具栏的 Viewpager 无法正常工作

    我的应用程序中有选项卡 每个选项卡都有不同的片段 并且有不同的菜单 下面是我正在使用的布局