Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elements in Fragment not working after re-adding the same fragment

UPDATE: I have found the header isn't the only thing affected, but listeners and other elements in the fragment aren't being initialized. (Such as FAB's). The only things that function correctly is anything built inside the adapter (i.e. the ListView rows)

The Problem: Open Nav Drawer, click on a list item that opens up a new Fragment in the same Activity. Open the Nav Drawer again, click the same item that should simply replace the existing Fragment and while the Fragment does open, all of the elements that are set programmatically in Java (text, colors, listeners) are not changed/added to the Fragment. The view is simply the default xml layout. I have confirmed with Log.d that the code that sets these things is being ran. (If you open a different Fragment and then go back to the original one, everything works fine)

The Confirmed Cause: When changing this:

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

to

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

(if only one of these libraries is changed, it doesn't matter which one, the problem still occurs)

I have confirmed changing these two libraries is the problem (also confirmed this problem in a second app -- and changing only this code, has the exact same result)

My questions is, why is this happening and how can it be fixed?

The Code and more detailed description from original question:

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

There are about 4 options in my drawer that all open this Fragment, but before each one, I set a global variable like this:

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

Based on the PlanType value (above), that Fragment is loaded with different data (but, in the exact same xml layouts). It is simply a ListView with a header.

This Fragment, (PlannerFragment) loads fine the first time.

When I click on another item (a different PlanType) that goes to the same Fragment (same code above executed): The ListView loads fine in the actual list. But in the header in the list, none of the setText() values set the new data properly. It uses the default values from my xml layout.

Now, if I load a different Fragment in between, everything works great. It's only when I either add or replace (I've tried both) the same Fragment on top of the old one does this happen.

Here is header code at top of 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);

If I add to that code, dateOutput.setText("test"); it does not happen. I can do a Log.dand my data registers, so this code is being read, but the UI is not set.

I've even tried removing the Fragment first like this with a check:

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

This has no effect.

Again, this ONLY happened when I changed the libraries above. Is this a bug with the library or does it now respond differently?

like image 830
TheLettuceMaster Avatar asked Dec 30 '16 22:12

TheLettuceMaster


2 Answers

There is many changes and issues with Fragments on appcompat 25.1.0. The first one seems related to your issue but the two next should be read as it may be important.


FragmentTransaction replace behaviour

Replace not working properly in appCompat 25.1.0
Current status (Jan 4 2017): bug assigned
Issue link


Fragment lifecycle change on 25.1.0

onStart on new Fragment is called before onStop on previous one
Current Status : works as expected. For me it could be a breaking change from app compat 25.0.x Issue link

There is also an issue with the resume event called two times in fragment, see here.

TLDR. Maybe the best temporary solution is to not use 25.1.0 until a new version is out.

like image 53
Hugo Gresse Avatar answered Nov 16 '22 03:11

Hugo Gresse


you can add list_view_header.xml in navigationDrawer() method and change the position of selected item like 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");
        }


    }
like image 36
Arati PAtel Avatar answered Nov 16 '22 04:11

Arati PAtel