草庐IT

android - MVVM : Fragment overlapping issue in view pager with navigation view?

coder 2023-12-29 原文

当我在导航 View 的菜单之间切换时,我遇到了 fragment 重叠的问题。最初我的应用程序具有带有多个选项的导航 View 。在该主页选项 fragment 中,具有包含两个选项卡的 View 寻呼机。当我在 View 之间切换时寻呼机标签效果很好..

问题是当我从“设置”之类的导航切换菜单时,相应的 fragment 加载良好,然后我重新加载主页 fragment , View 寻呼机加载选项卡,但旧 fragment (设置)显示在背景中

此外,当我多次加载 home 选项时, fragment 会重叠多次而不是替换 fragment

我的代码如下

Activity 类:DashboardActivity.java

/**
 *   DashboardActivity.java
 */

public class DashboardActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener, FragmentManager.OnBackStackChangedListener,
        ViewPageListener {

    /**
     * Used as initializing the layout as data binding.
     */
    private ActivityDashboardBinding activityDashboardBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activityDashboardBinding = DataBindingUtil.setContentView(this, R.layout.activity_dashboard);
        activityDashboardBinding.setOnClickController(new DashboardController());
        setSupportActionBar(activityDashboardBinding.toolbar);
        getSupportActionBar().setDisplayShowTitleEnabled(false);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, activityDashboardBinding.drawerLayout, activityDashboardBinding.toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        activityDashboardBinding.drawerLayout.addDrawerListener(toggle);
        activityDashboardBinding.navigationView.setNavigationItemSelectedListener(this);
        toggle.syncState();
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDefaultDisplayHomeAsUpEnabled(false);
        toggle.setDrawerIndicatorEnabled(false);
        toggle.setHomeAsUpIndicator(R.drawable.ic_menu_hamburger);
        toggle.setToolbarNavigationClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (activityDashboardBinding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
                    activityDashboardBinding.drawerLayout.closeDrawer(GravityCompat.START);
                } else {
                    activityDashboardBinding.drawerLayout.openDrawer(GravityCompat.START);
                }
            }
        });
        displaySelectedScreen(R.id.nav_home);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_dashboard, 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();
        if (id == R.id.action_notification) {
            startActivity(new Intent(this, NotificationActivity.class));
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        // Handle navigation view item clicks here.
        displaySelectedScreen(item.getItemId());
        return true;
    }

    /**
     * Method used as navigation selection option.
     *
     * @param itemId Selected  id.
     */
    private void displaySelectedScreen(int itemId) {
        Fragment fragment = null;
        String fragmentName = null;
        if (itemId == R.id.nav_home) {
            activityDashboardBinding.toolBarTitle.setText(R.string.toolbar_name_dashboard);
            activityDashboardBinding.addNewRide.show();
            fragment = new HomePageFragment();
            fragmentName = Constants.NAME_NAVIGATION_DASHBOARD;
        } else if (itemId == R.id.nav_rides) {
        } else if (itemId == R.id.nav_profile) {
            activityDashboardBinding.toolBarTitle.setText(R.string.toolbar_name_my_profile);
            activityDashboardBinding.addNewRide.hide();
            fragment = new UserProfileFragment();
            fragmentName = Constants.NAME_NAVIGATION_MY_PROFILE;
        } else if (itemId == R.id.nav_settings) {
            activityDashboardBinding.toolBarTitle.setText(R.string.toolbar_name_settings);
            fragment = new SettingsFragment();
            activityDashboardBinding.addNewRide.hide();
            fragmentName = Constants.NAME_NAVIGATION_SETTINGS;
        } else if (itemId == R.id.nav_logout) {
            Intent logoutIntent = new Intent(getApplicationContext(), LoginActivity.class);
            logoutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            startActivity(logoutIntent);
        }

        if (fragment != null) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.addOnBackStackChangedListener(this);
            fragmentManager.beginTransaction().add(R.id.container, fragment)
                    .addToBackStack(fragmentName).commit();
        }
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
    }

    @Override
    public void onBackPressed() {
        if (activityDashboardBinding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
            activityDashboardBinding.drawerLayout.closeDrawer(GravityCompat.START);
        } else if (getFragmentName().equals(Constants.NAME_NAVIGATION_DASHBOARD)) {
            finish();
        } else {
            // Let super handle the back press
            super.onBackPressed();
        }
    }

    @Override
    public void onBackStackChanged() {
        if (getFragmentName().equals(Constants.NAME_NAVIGATION_DASHBOARD)) {
            activityDashboardBinding.toolBarTitle.setText(R.string.toolbar_name_dashboard);
            activityDashboardBinding.addNewRide.show();
        } else if (getFragmentName().equals(Constants.NAME_NAVIGATION_MY_PROFILE)) {
            activityDashboardBinding.toolBarTitle.setText(R.string.toolbar_name_my_profile);
            activityDashboardBinding.addNewRide.hide();
        } else {
            activityDashboardBinding.toolBarTitle.setText(R.string.toolbar_name_settings);
            activityDashboardBinding.addNewRide.hide();
        }
    }

    /**
     * Method used to get the fragment transaction name to identify the fragment.
     *
     * @return the fragment name.
     */
    private String getFragmentName() {
        FragmentManager fm = getSupportFragmentManager();
        return fm.getBackStackEntryAt(fm.getBackStackEntryCount() - 1).getName();
    }

    @Override
    public void onViewPageListener() {
        activityDashboardBinding.addNewRide.animate().translationY(0).setInterpolator(new LinearInterpolator()).start();
    }
}

DashboardViewAdapter.java

/**
 * The class that contains the list of fragments and list of title. We can use the fragments using
 * view pager from here.
 *
 * @version 1.0
 */
public class DashboardViewAdapter extends FragmentStatePagerAdapter {
    /**
     * Title of the fragment list.
     */
    private String[] mTitle;
    /**
     * Fragment list Which contains the fragments on the adapter.
     */
    private List<Fragment> fragmentList;
    /**
     * Instantiates a new adapter dashboard view.
     *
     * @param fm the Instance of the FragmentManager.
     */
    public DashboardViewAdapter(FragmentManager fm) {
        super(fm);
    }
    /**
     * Set the list of title from the activity.
     *
     * @param titles Title list.
     */
    public void setTitle(String[] titles) {
        this.mTitle = titles;
    }
    /**
     * Set the fragment list for the particular view pager using FragmentStatePagerAdapter.
     *
     * @param fragmentList List of fragment.
     */
    public void setFragmentList(List<Fragment> fragmentList) {
        this.fragmentList = fragmentList;
    }
    @Override
    public Fragment getItem(int position) {
        return fragmentList.get(position);
    }
    @Override
    public int getCount() {
        return mTitle.length;
    }
    @Override
    public CharSequence getPageTitle(int position) {
        return mTitle[position];
    }
}

HomePageFragment.java

/**
 * Fragment used as home page to display the ride offered and my rides details.
 *
 * @version 1.0
 */
public class HomePageFragment extends Fragment implements ViewPager.OnPageChangeListener {

    /**
     * Binding the fragment.
     */
    private FragmentHomePageBinding homePageBinding;

    /**
     * Interface to listen the view pager changes.
     */
    private ViewPageListener viewPageListener;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        homePageBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_home_page, container, false);
        setTabs();
        setHasOptionsMenu(true);
        viewPageListener = (ViewPageListener) getActivity();
        return homePageBinding.getRoot();
    }

    /**
     * Set up the Ride offers and My rides fragments in the tab
     */
    private void setTabs() {
        String[] mTitle = new String[]{"Rides offered", "My Rides"};
        FragmentManager fm = getChildFragmentManager();
        DashboardViewAdapter mAdapter = new DashboardViewAdapter(fm);
        mAdapter.setTitle(mTitle);
        mAdapter.setFragmentList(getFragmentList());
        homePageBinding.viewPager.setAdapter(mAdapter);
        homePageBinding.tabLayout.setupWithViewPager(homePageBinding.viewPager);
        homePageBinding.viewPager.addOnPageChangeListener(this);
    }

    /**
     * Get the fragment list to display the view pager tabs. Recent chat and contacts fragment will
     * be return from this.
     *
     * @return List of the fragments for the viewpager
     */
    private List<Fragment> getFragmentList() {

        /**
         * Add the fragment as a list.
         */
        List<Fragment> fragmentList = new ArrayList<>();

        /**
         The fragment contacts which contains the ride offer list.
         */
        RidesOfferedFragment ridesOfferedFragment = new RidesOfferedFragment();

        /**
         The fragment contacts which contains the ride offer list.
         */
        MyRidesFragment myRidesFragment = new MyRidesFragment();
        fragmentList.add(ridesOfferedFragment);
        fragmentList.add(myRidesFragment);
        return fragmentList;
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        viewPageListener.onViewPageListener();
    }

    @Override
    public void onPageSelected(int position) {
        //Overridden Method
    }

    @Override
    public void onPageScrollStateChanged(int state) {
        //Overridden Method
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        menu.findItem(R.id.action_notification).setVisible(true);
        super.onPrepareOptionsMenu(menu);
    }
}

activity_dashboard.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="onClickController"
            type="com.contus.carpooling.dashboard.homepage.viewmodel.DashboardController" />
    </data>

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:openDrawer="start">

        <android.support.design.widget.CoordinatorLayout
            android:id="@+id/coordinator_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            tools:context="com.contus.carpooling.dashboard.homepage.view.DashboardActivity">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    android:background="?attr/colorPrimary"
                    app:layout_scrollFlags="scroll|enterAlways"
                    app:popupTheme="@style/AppTheme.PopupOverlay">

                    <TextView
                        android:id="@+id/tool_bar_title"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:text="Dashboard"
                        android:textColor="@android:color/white"
                        android:textSize="18sp" />
                </android.support.v7.widget.Toolbar>

                <FrameLayout
                    android:id="@+id/container"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

            </LinearLayout>

            <android.support.design.widget.FloatingActionButton
                android:id="@+id/add_new_ride"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="right|bottom"
                android:layout_margin="10dp"
                android:clickable="true"
                android:onClick="@{onClickController.fabBtnOnClick()}"
                android:src="@drawable/ic_action_add"
                app:backgroundTint="@color/colorSecondaryColor"
                app:fabSize="normal"
                app:layout_behavior="com.contus.carpooling.view.ScrollAwareFABBehavior" />

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

        <android.support.design.widget.NavigationView
            android:id="@+id/navigation_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:background="@android:color/white"
            android:fitsSystemWindows="true"
            app:headerLayout="@layout/navigation_header"
            app:itemIconTint="@color/colorPrimary"
            app:itemTextColor="#4b4b4b"
            app:menu="@menu/activity_dashboard_drawer"
            app:theme="@style/NavigationDrawerSelected" />
    </android.support.v4.widget.DrawerLayout>
</layout>

fragment_home_page.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data />
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.contus.carpooling.dashboard.homepage.view.HomePageFragment">

        <android.support.design.widget.TabLayout
            android:id="@+id/tab_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimary"
            android:minHeight="?attr/actionBarSize"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:tabIndicatorColor="@color/colorHighLightBlue"
            app:tabIndicatorHeight="4dp" />

        <android.support.v4.view.ViewPager
            android:id="@+id/view_pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    </LinearLayout>

</FrameLayout>
</layout>

设置显示在仪表板背景中..重叠图像

等待回复...提前致谢

最佳答案

这里的问题是添加的 fragment 将背景设置为透明,因此将背景设置为您要添加的布局 fragment 文件 例如:

    <FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorBackground"
>

关于android - MVVM : Fragment overlapping issue in view pager with navigation view?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42713680/

有关android - MVVM : Fragment overlapping issue in view pager with navigation view?的更多相关文章

  1. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  2. Android Studio开发之使用内容组件Content获取通讯信息讲解及实战(附源码 包括添加手机联系人和发短信) - 2

    运行有问题或需要源码请点赞关注收藏后评论区留言一、利用ContentResolver读写联系人在实际开发中,普通App很少会开放数据接口给其他应用访问。内容组件能够派上用场的情况往往是App想要访问系统应用的通讯数据,比如查看联系人,短信,通话记录等等,以及对这些通讯数据及逆行增删改查。首先要给AndroidMaifest.xml中添加响应的权限配置 下面是往手机通讯录添加联系人信息的例子效果如下分成三个步骤先查出联系人的基本信息,然后查询联系人号码,再查询联系人邮箱代码 ContactAddActivity类packagecom.example.chapter07;importandroid

  3. Android 10.0 设置默认launcher后安装另外launcher后默认Launcher失效的功能修复 - 2

    1.前言 在10.0的系统rom定制化开发中,在系统中有多个launcher的时候,会在开机进入launcher的时候弹窗launcher列表,让用户选择进入哪个launcher,这样显得特别的不方便所以产品开发中,要求用RoleManager的相关api来设置默认Launcher,但是在设置完默认Launcher以后,在安装一款Launcher的时候,默认Launcher就会失效,在系统设置的默认应用中Launcher选项就为空,点击home键的时候会弹出默认Launcher列表,让选择进入哪个默认Launcher.所以需要从安装Launcher的流程来分析相关的设置。来解决问题设置默认La

  4. AiBote 2022 新研发的自动化框架,支持 Android 和 Windows 系统。速度非常快 - 2

    Ai-Bot基于流行的Node.js和JavaScript语言的一款新自动化框架,支持Windows和Android自动化。1、Windowsxpath元素定位算法支持支持Windows应用、.NET、WPF、Qt、Java和Electron客户端程序和ie、edgechrome浏览器2、Android支持原生APP和H5界面,元素定位速度是appium十倍,无线远程自动化操作多台安卓设备3、基于opencv图色算法,支持找图和多点找色,1080*2340全分辨率找图50MS以内4、内置免费OCR人工智能技术,无限制获取图片文字和找字功能。5、框架协议开源,除官方node.jsSDK外,用户可

  5. Android Gradle 7.1+新版本依赖变化 - 2

    前一段时间由于工作需要把可爱的小雪狐舍弃了,找到了小蜜蜂。但是新版本的小蜜蜂出现了很多和旧版本不一样的位置。1.功能位置迁移,原来在工程build.gradle的buildscript和allprojects移动至setting.gradle并改名为pluginManagement和dependencyResolutionManagement。里面的东西依旧可以按照原来的copy过来。pluginManagement{repositories{gradlePluginPortal()google()mavenCentral()}}dependencyResolutionManagement{r

  6. ruby - Ruboto 的最佳教程(适用于 Android 的 ruby​​)? - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于StackOverflow来说是偏离主题的,因为它们往往会吸引自以为是的答案和垃圾邮件。相反,describetheproblem以及迄今为止为解决该问题所做的工作。关闭9年前。Improvethisquestion我几乎用完了Ruby,但现在想试试Ruboto,android上的ruby​​。谷歌未能给我足够的(几乎没有结果)。所以任何人都可以分享一些关于Ruboto的教程。

  7. Android Studio 解决Could not resolve com.android.tools.build:gradle:7.4.2问题 - 2

    Aproblemoccurredconfiguringrootproject'MyApplication2'.>Couldnotresolveallfilesforconfiguration':classpath'.  >Couldnotresolvecom.android.tools.build:gradle:7.4.2.   Requiredby:     project:>com.android.application:com.android.application.gradle.plugin:7.4.2     project:>com.android.library:com.andr

  8. Android对话框的详细介绍(提示对话框,自定义对话框) - 2

    简介:我们都知道在Android开发中,当我们的程序在与用户交互时,用户会得到一定的反馈,其中以对话框的形式的反馈还是比较常见的,接下来我们来介绍几种常见的对话框的基本使用。前置准备:(文章最后附有所有代码)我们首先先写一个简单的页面用于测试这几种Dialog(对话框)代码如下,比较简单,就不做解释了一、提示对话框(即最普通的对话框)首先我们给普通对话框的按钮设置一个点击事件,然后通过AlertDialog.Builder来构造一个对象,为什么不直接Dialog一个对象,是因为Dialog是一个基类,我们尽量要使用它的子类来进行实例化对象,在实例化对象的时候,需要将当前的上下文传过去,因为我这

  9. android 多屏幕显示activity,副屏,无线投屏 - 2

    目录1.首先,需要一个副屏1.1可以通过代码的形式自己创建VirtualDispaly,创建副屏。1.2或者,在手机的开发者模式中直接开启模拟副屏,也是可以的。2.0怎么利用这个副屏幕?2.1 用作presentation演示ppt:2.2克隆主屏幕的内容,就是主屏幕显示什么,副屏显示同样的内容,镜像模式。2.3 将一个activity从第二个屏幕上启动,作为一个独立的屏幕首先说明一下这个多屏幕的概念,这里不是指分屏显示。分屏显示:是一个屏幕分出多个窗口,分别显示不同app.多屏支持:是一个设备有多个屏幕,怎么让不同的屏幕显示不同的app,或者是一个app同时用两个屏幕来显示不同的页面内容。多

  10. 【Android】获取TextView宽度或高度 - 2

    需要提前知道的一些东西Android中获取View的宽度或者高度,可以通过View自带的方法getWidth()、getHeight(),但这仅限于layout_width和layout_height的值是具体的dp或者match_parent,如果值是wrap_content,那么直接调用getWidth()、getHeight()方法,可能返回的会是0。直接调用getWidth()、getHeight()可能返回0的原因是,View可能还没有被添加到界面上(这里添加到界面上是指View执行了onMeasure方法),View添加到界面上之后,才计算完宽度和高度,所以如果宽度或高度如果设置w

随机推荐