简体   繁体   中英

Why is the savedInstanceState Bundle I pass to my Android Fragment empty on arrival?

In the Android app I am developing I have a list fragment that shows a RecyclerView of list items. The first time we open the fragment it retrieves the list from a url, but it's not going to change frequently enough to keep reloading it so I want to retain the data. As far as I can tell the Android way to do this is using the savedInstanceState for the fragment, like this:

class ItemListFragment() {

    private var itemCards: RecyclerView? = null;

        public val Items: ArrayList<Item> = ArrayList<Item>()

    override fun onViewStateRestored(savedInstanceState: Bundle?) {
        super.onViewStateRestored(savedInstanceState)
        if ( Items.size == 0 && savedInstanceState != null && savedInstanceState.containsKey("items")) {
            val arrayType = object: TypeToken<Array<Item>>() {}.type
            val tempItems: Array<Item> = Gson().fromJson(savedInstanceState.getString("items"), arrayType)
            Items.addAll(tempItems)
        }
    }

}

Then I manage the states in my MainActivity like this:

class MainActivity : AppCompatActivity() {

        private lateinit var restoreBundle: HashMap<String, Bundle>

        private var currentFragment = ""

    override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            restoreBundle = HashMap<String, Bundle>()
            setContentView(R.layout.activity_main)
    }

   override fun onNavigationItemSelected(item: MenuItem): Boolean {
            // Handle navigation view item clicks here.
            drawFragment(item.itemId)
   }

        private fun drawFragment(position:Int) {
            val fragMan: FragmentManager = getSupportFragmentManager()
            val fragmentName = getFragmentName(position)
            val bundle:Bundle = restoreBundle.get(fragmentName) ?: Bundle()

            var fragment: Fragment? =   fragMan.getFragment(bundle, fragmentName)

            if ( fragment == null ) {
                fragment =  ItemListFragment() as Fragment
            }

            val current = fragMan.findFragmentByTag(currentFragment)

            if (current != null) {
                    val frag = getFragmentName(current.id)
                    val recover : Bundle =  restoreBundle.get(frag) ?: Bundle()
                    current.onSaveInstanceState(recover)
                    restoreBundle.set(frag, recover);
            }


                if (fragmentSet) {
                    fragMan.beginTransaction()
                        .replace(R.id.main_content_fragment, fragment!!, fragmentName).commit()
                } else {
                    fragMan.beginTransaction()
                        .add(R.id.main_content_fragment, fragment!!, fragmentName).commit()
                }
            currentFragment = fragmentName

        }
} 

Both of these examples have been trimmed down to what seems to me the relevant parts but the code may not be the problem so much as what I am trying to do. Basically when I switch fragment a couple of times and it calls fragMan.getFragment(bundle, fragmentName) the bundle contains the correct saved instance state but when I get into ItemListFragment.onViewStateRestored ( which is the next place I can put a breakpoint as far as I can tell ) the savedInstanceState bundle is null.

Why is the bundle I am passing in not the same as the one being retrieved or what is the correct way to pass the instance state to my fragment?

I could not find a satisfactory answer to this, so I adjusted my architecture so that the models were loaded from - and stored in - their own service and made accessible as part of a companion object in my MainActivity rather than attempting to use the Fragment architecture to pass data into the fragment. It is not clear that the latter is possible, regardless of what the documentation suggests.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM