片段替换事务不记住变量位图的状态

时间:2018-07-08 06:01:48

标签: android android-fragments

我有一个asyncTask来获取图像(它具有动态的宽度和高度,因此不使用毕加索或壁画)。我为此使用url.OpenConnection,但我想缓存结果,因此具有相同url的下一次调用将仅检查缓存并返回结果。我如何设置它使用缓存?

 private var mBitmap: Bitmap? = null

private inner class FetchImageAsync : AsyncTask<String, Void, Bitmap>() {

        override fun doInBackground(vararg params: String): Bitmap? {
            // your background code fetch InputStream
            val imageId = params[0]
            var bmp: Bitmap? = null
            try {
                val url = URL("https://" + BASE_ENDPOINT + "/" + imageId)
                bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream())
                mBitmap = bmp
            } catch (e: Exception) {
            }
            return bmp
        }

        override fun onPostExecute(bmp: Bitmap?) {
            super.onPostExecute(bmp)
            if (bmp != null && activity != null) {
                iv.setImageBitmap(bmp)

            }
        }
    }

我试图将解码后的位图的结果保存到一个名为mBitmap的类变量中,但是当片段被“替换”并且返回片段时,它的mBitmap再次为null吗?为什么呢?我以为片段替换会记住状态。为了清楚起见,我正在寻找一种方法,在我已经做完之后不要继续在相同的URL上进行网络调用。这应该全部是本地的,而不是服务器端的。

这是我替换片段的方式:

 public void replaceFragment(Fragment f) {
        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
        transaction.addToBackStack(null);
        transaction.replace(R.id.fl_attributes_container, f, f.getClass().getName()).commit();
    }


  <FrameLayout
                android:id="@+id/fl_attributes_container"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

更新:这是我的整个片段:

 class MyFragment : Fragment() {


private var mBitmap: Bitmap? = null

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val rootView = inflater.inflate(R.layout.fragment_layout, container, false)
        return rootView
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView()
    }


    private fun initView() {
        setupImage()  
    }


    private fun setupImage() {

            //the mBitmap is always null after i come back to the fragment from a replace, why ?
                mBitmap?.let { bitmap -> iv.setImageBitmap(bitmap) }
                        ?: run { FetchImageAsync().execute(it) }
            }




    private inner class FetchImageAsync : AsyncTask<String, Void, Bitmap>() {

        override fun doInBackground(vararg params: String): Bitmap? {
            // your background code fetch InputStream
            val imageId = params[0]
            var bmp: Bitmap? = null
            try {
                val url = URL("https://" + BASE_ENDPOINT + "/" + imageId)
                bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream())
                mBitmap = bmp
            } catch (e: Exception) {
            }
            return bmp
        }

        override fun onPostExecute(bmp: Bitmap?) {
            super.onPostExecute(bmp)
            if (bmp != null && activity != null) {
                iv.setImageBitmap(bmp)
            }
        }
    }



    companion object {
        fun newInstance(b: Bundle?): MyFragment {
            val frag = MyFragment()
            frag.arguments = b ?: Bundle()
            return frag
        }
    }

1 个答案:

答案 0 :(得分:1)

您正在使用replaceFragment方法切换回以前的某些Fragment。如评论中所述,其操作如下:

replaceFragment(MyFragment.Companion.newInstance(null));

但是,这每次都需要一个新的实例参数,因此您替换的Fragment是一个全新的对象,无法知道其他Fragment的成员变量。

要解决此问题,请尝试标记您的Fragment,以便在找到后可以重新使用。因此,在调用replaceFragment之前,请执行以下操作:

var frag = getChildFragmentManager().findFragmentByTag(tag)
if (frag == null) {
    frag = MyFragment.Companion.newInstance(null)     
} 
replaceFragment(frag)