问题 片段中的元素在重新添加相同片段后无法正常工作


UPDATE:我发现标题不是唯一受影响的东西,但是 listeners 片段中的其他元素未初始化。 (比如FAB)。唯一能正常运作的东西就是内置的东西 adapter (即 ListView 行)

问题:打开导航抽屉,单击打开新的列表项 Fragment 在相同的 Activity。再次打开导航抽屉,单击应该只替换现有的相同项目 Fragment 而且 Fragment 如果打开,所有以Java编程设置的元素(文本,颜色,侦听器)都不会更改/添加到 Fragment。视图只是默认视图 xml 布局。我已经确认了 Log.d 设置这些东西的代码  正在奔跑。 (如果你打开一个不同的 Fragment 然后回到原来的一切,一切正常)

确认的原因:  更改此时:

    compile "com.android.support:appcompat-v7:25.0.1"
    compile 'com.android.support:design:25.0.1'

    compile "com.android.support:appcompat-v7:25.1.0"
    compile 'com.android.support:design:25.1.0'

(如果只更改了其中一个库,那么哪个库仍然无关紧要)

我已经确认更改这两个库是问题(在第二个应用程序中也证实了这个问题 - 并且正在改变 只要 这段代码,有完全相同的结果)

我的问题是,为什么会发生这种情况,如何解决?

原始问题的代码和更详细的描述:

                FragmentTransaction tItems = fm.beginTransaction();
                ListFragment mFrag = new PlannerFragment();
                tItems.replace(R.id.main_frag, mFrag, TAG_CALC_FRAGMENT);
                tItems.commit();

我的抽屉里有大约4个选项都可以打开这个片段,但在每个选项之前,我设置了一个像这样的全局变量:

MyApp.PlanType = "highbal";
MyApp.PlanType = "lowbal";
etc.

基于 PlanType 价值(上图),那 Fragment 加载了不同的数据(但是,在完全相同的xml布局中)。它只是一个 ListView 带头。

这个 Fragment,((PlannerFragment)第一次装好。

当我点击另一个项目(另一个 PlanType)这是相同的 Fragment (上面执行的代码相同): ListView 在实际列表中加载正常。  在里面 header 在列表中,没有一个 setText() 值正确设置新数据。它使用我的默认值 xml 布局。

现在,如果我加载一个不同的 Fragment 在这之间,一切都很好。只有当我添加或替换(我已经尝试过两者)时才这样 Fragment 在旧的之上,这种情况会发生。

这是顶部的标题代码 PlannerFragment

@Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        // Setup listview
        lv = getListView();

        LayoutInflater inflaterHeader = getActivity().getLayoutInflater();
        ViewGroup header = (ViewGroup) inflaterHeader.inflate(R.layout.planner_listview_header, lv, false);
        lv.addHeaderView(header, null, false);

        // Load Data then Set Textviews, e.g.:
        TextView title = (TextView) getActivity().findViewById(R.id.tvPlannerTitle);
    dateOutput = (TextView) getActivity().findViewById(R.id.tvDebtOutDate);

如果我添加到该代码, dateOutput.setText("test"); 它不会发生。我可以做一个 Log.d和我的数据寄存器,因此正在读取此代码,但未设置UI。

我甚至试过删除 Fragment 首先这样检查:

                Fragment fragment = fm.findFragmentByTag(TAG_CALC_FRAGMENT);
                if(fragment != null)
                    fm.beginTransaction().remove(fragment).commit();

这没有效果。

同样,这只发生在我更改上面的库时。这是库中的错误还是现在响应不同?


12376
2017-12-30 22:41


起源

试着打电话 ft.executePendingTransactions() 后 tItems.commit(); - Oleg Bogdanov
@OlegBogdanov我做了一个 fm.executePendingTransactions(); 在你说的那条线之后,我最终得到了相同的结果。 - KickingLettuce
请更新你的问题,并把你的片段 onCreateView - Rajesh Kushvaha


答案:


有很多 appcompat 25.1.0上片段的更改和问题。第一个似乎与您的问题有关,但下一个应该被阅读,因为它可能很重要。


FragmentTransaction替换行为

替换在appCompat 25.1.0中无法正常工作
当前状态 (2017年1月4日):错误 分配
问题链接


片段生命周期在25.1.0上更改

onStart on new Fragment在之前的onStop之前调用
当前状态 :按预期工作。对我而言,它可能是app compat 25.0.x的重大变化 问题链接

还有一个问题 恢复活动两次 在片段中,请参阅 这里

TLDR。 也许最好的临时解决方案是在新版本发布之前不使用25.1.0。


12
2018-01-04 09:04



我有一种强烈的感觉,这是图书馆里的一个错误。谢谢你的确认。 - KickingLettuce
在最近几次支持库升级中,错误的数量与上面提到的严重程度相似,令人非常失望;感谢@Hugo的链接 - Forrest Bice


你可以加 list_view_header.xml 在 navigationDrawer() 方法并改变所选项目的位置 selectItem(position - 1)

  private void navigationDrawer() {

        mTitle = mDrawerTitle = getTitle();
        // mNavigationDrawerItemTitles = getResources().getStringArray(R.array.navigation_drawer_items_array);

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);

        LayoutInflater inflater = getLayoutInflater();
        View listHeaderView = inflater.inflate(R.layout.list_view_header, null, false);
        mDrawerList.addHeaderView(listHeaderView, null, false);

        setupToolbar();

        DataModel[] drawerItem = new DataModel[6];

        drawerItem[0] = new DataModel(R.drawable.dashboard_icon, "Dashboard");
        drawerItem[1] = new DataModel(R.drawable.cal_icon, "Calender");
        drawerItem[2] = new DataModel(R.drawable.classes, "Classes");
        drawerItem[3] = new DataModel(R.drawable.message_icon_hdpi, "Message Center");
        drawerItem[4] = new DataModel(R.drawable.profile, "Profile & Setting");
        drawerItem[5] = new DataModel(R.drawable.bulletin_icon, "Bulletin Board");

        getSupportActionBar().setDisplayHomeAsUpEnabled(false);
        getSupportActionBar().setHomeButtonEnabled(true);

        DrawerItemCustomAdapter adapter = new DrawerItemCustomAdapter(this, R.layout.list_view_item_row, drawerItem);
        mDrawerList.setAdapter(adapter);
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerLayout.setDrawerListener(mDrawerToggle);
        setupDrawerToggle();


    }

    private class DrawerItemClickListener implements ListView.OnItemClickListener {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectItem(position - 1);
        }


    }

    private void selectItem(int i) {
        Fragment fragment = null;

        switch (i) {
            case 0:
                fragment = new Fragment_DashBoard();
                // toolbar.setTitle("Dashboard");
                Titletv.setText("Dashboard");
                break;
            case 1:
                fragment = new Fragment_Calender();
                // toolbar.setTitle("Calender");
                Titletv.setText("Calender");

                break;
            case 2:
                fragment = new Fragment_Classes();
                // toolbar.setTitle("Classes");
                Titletv.setText("Classes");
                break;
            case 3:
                fragment = new Fragment_MessageCenter();
                // toolbar.setTitle("Message");
                Titletv.setText("Messages");
                break;
            case 4:
                fragment = new Fragment_ProfileSetting();
                // toolbar.setTitle("Profile");
                Titletv.setText("Profile");

                break;

            case 5:
                fragment = new Fragment_BulletinBoard();
                //toolbar.setTitle("Bulletin Board");
                Titletv.setText("Bulletin Board");

                break;

            default:
                break;
        }


        if (fragment != null) {

            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction trans = fragmentManager.beginTransaction();
            fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).addToBackStack(null).commit();

            mDrawerList.setItemChecked(i, true);
            mDrawerList.getItemAtPosition(i);
            // setTitle(mNavigationDrawerItemTitles[position]);
            mDrawerLayout.closeDrawer(mDrawerList);


        } else {
            Log.e("MainActivity", "Error in creating fragment");
        }


    }

3
2018-01-04 10:07