iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 19
1
Mobile Development

程式初學:Android與Kotlin系列 第 19

Day 19--天氣app(五) argument,bundle

  • 分享至 

  • xImage
  •  

把資料拿出來,layout稍微整理下
呈現如下,看似正常...

但當我加入明天的資訊後,就閃退了

錯誤訊息

原來我把First,Second fragment layout上的view都寫在MainActivity的search中,如下...一大陀

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    menuInflater.inflate(R.menu.menu, menu)
    val searchItem = menu?.findItem(R.id.action_search)
    if (searchItem != null) {
        val searchView = searchItem.actionView as SearchView
        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(query: String?): Boolean {
                return true
            }

            override fun onQueryTextChange(newText: String?): Boolean {
                if (newText!!.isNotEmpty()) {
                    weatherList.forEach { location ->
                        if (location.locationName.contains(newText)) {
                            //當日
                            tv_startTime1.text = location.weatherElement[0].time[0].startTime
                            tv_endTime1.text =
                                location.weatherElement[0].time[0].endTime//.split(" ")[1]
                            tv_status1.text =
                                location.weatherElement[0].time[0].parameter.parameterName
                            tv_rainProbability1.text =
                                "降雨機率 ${location.weatherElement[1].time[0].parameter.parameterName} %"

                            tv_startTime2.text = location.weatherElement[0].time[1].startTime
                            tv_endTime2.text =
                                location.weatherElement[0].time[1].endTime//.split(" ")[1]
                            tv_status2.text =
                                location.weatherElement[0].time[1].parameter.parameterName
                            tv_rainProbability2.text =
                                "降雨機率 ${location.weatherElement[1].time[1].parameter.parameterName} %"

                            //隔日
                            tv_startTime3.text = location.weatherElement[0].time[2].startTime
                            tv_endTime3.text =
                                location.weatherElement[0].time[2].endTime//.split(" ")[1]
                            tv_status3.text =
                                location.weatherElement[0].time[2].parameter.parameterName
                            tv_rainProbability3.text =
                                "降雨機率 ${location.weatherElement[1].time[2].parameter.parameterName} %"
                        }
                    }
                }
                return true
            }
        })
    }
    return super.onCreateOptionsMenu(menu)
}

包含tv_startTime3等的TextView
在明天這個Second Fragment還未被載入之前,當一有資料要給值時
就會出錯了

而First Fragment沒出錯應該是因爲app一開啓後就載入了
所以搜尋後的畫面上那些View都有更新到

初步查到比較正確的做法是屬於fragment的view不應該寫在activity
在MainActivity的SearchView查詢完之後的資料
用bundle包起來,再呼叫fragment的argument取出
類似

class MainActivity : AppCompatActivity() {
       
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        btn.setOnClickListener {
            val bundle = Bundle()
            bundle.putString("city",location.locationName)

            val fragment = SecondFragment()
            fragment.arguments = bundle
            supportFragmentManager.beginTransaction()
                .replace(R.id.container,fragment)
                .addToBackStack("fragment")
                .commit()

        }
    }
}
class SecondFragment : Fragment() {
   
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        rootView = inflater.inflate(R.layout.fragment_blank, container, false)
        return rootView
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        //接收資料
        val bundle = arguments
        if(bundle!=null){
             tv_city.text = bundle?.getString("city")
        }
    }


}

但是,這個方法似乎不適用目前這個專案
因爲我是用viewpager2管理fragment,在之前建立的adapter中

class PageAdapter(fragmentManager: FragmentManager, lifecycle: Lifecycle) :
    FragmentStateAdapter(fragmentManager, lifecycle) {

    var fragments: ArrayList<Fragment> = arrayListOf(
        FirstFragment(),
        SecondFragment(),
        ThirdFragment()
    )

    override fun getItemCount(): Int {
        return fragments.size
    }

    override fun createFragment(position: Int): Fragment {
        return fragments[position]
    }
}

adapter已經將fragment實例化了,滑動各個fragment時應該都是取得同一個實例
所以新建fragment在把資料bundle給值進去好像不那麼適合
就算不新建,將資料給原有的fragment,也是有先後問題,畫面沒法更新

請教各大前輩後,得到二種做法
準備做個調整吧


上一篇
Day 18--天氣app(四) SimpleDateFormat,Action bar search(SearchView)
下一篇
Day 20--天氣app(六)類型檢測與類型轉換,在fragment建立更新的方法
系列文
程式初學:Android與Kotlin30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言