簡體   English   中英

Android ListView.notifyDataSetChanged 導致不正確的行

[英]Android ListView.notifyDataSetChanged causing incorrect rows

我正在開發一個 android 項目,其中正在從子活動更新 ListFragment。 然而,雖然更新后元素的數量是正確的,但元素本身卻不是。 不正確的元素被放入列表並相互復制。

問題是,子activity修改了文件,調用populate()函數后,再回到Fragment所在的主activity,問題就出現了。 例如,一開始它們是這樣的: [1, 2, 3]

現在子活動中的文件操作將刪除項目“1”(不是直接調用remove,而是刪除該文件, populate()函數(如下所列)將生成一個沒有該元素的列表),它應該變成[2, 3] 但它變成了[1, 2]

並通過按鈕調用完成刷新,包括清除並重新填充MetadataManager.packMapPackListManager.onlineListPackListManager.localList ,然后重新啟動 MainActivity ,它恢復正常。

現在我們有[2, 3] 子活動中的另一個文件操作應該返回“1”,並且它應該再次變為[1, 2, 3] 但是,它變成了[2, 3, 3]

元素來自單例中的 ArrayList。 這是 ListFragment 的類:

class PackListFragment : ListFragment() {

    private lateinit var dataList: ArrayList<PackageMetadata>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val index = arguments?.getInt(ARG_SECTION_NUMBER) ?: 1
        if (index == 1){
            dataList = PackListManager.onlineList
        } else {
            dataList = PackListManager.localList
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val adapter = PackMetadataAdapter(activity as Context, dataList)
        listAdapter = adapter
        return inflater.inflate(R.layout.fragment_main, container, false)
    }

    override fun onResume() {
        (listAdapter as ArrayAdapter<PackageMetadata>).notifyDataSetChanged()
        super.onResume()
    }

我的 ListView 使用自定義適配器。 這是適配器:

class PackMetadataAdapter (context : Context, val values : List<PackageMetadata>)
    : ArrayAdapter<PackageMetadata>(context, -1, values) {

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        if (convertView == null) {
            val inflater = context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
            /*val rowView : View = inflater.inflate(android.R.layout.simple_list_item_1, parent, false)
            val text1 = rowView.findViewById(android.R.id.text1) as TextView
            text1.text = values[position].Name_LO*/
            val metadata = values[position]
            val rowView: View = inflater.inflate(R.layout.listitem_route, parent, false)
            val textTitle = rowView.findViewById<View>(R.id.textTitle) as TextView
            val textAuthor = rowView.findViewById(R.id.textAuthor) as TextView
            val textVersion = rowView.findViewById(R.id.textVersion) as TextView
            val textTimestamp = rowView.findViewById(R.id.textTimestamp) as TextView
            val imageView: ImageView = rowView.findViewById<View>(R.id.imageThumbnail) as ImageView
            textTitle.text = metadata.Name_LO
            textAuthor.text = metadata.Author.Name_LO
            textVersion.text = metadata.Version.get()
            textTimestamp.text = SimpleDateFormat("yyyy-MM-dd", Locale.US)
                .format(values[position].Timestamp)
            DownloadImageTask(imageView).execute(metadata.Thumbnail)
            return rowView
        }
        return convertView
    }

}

單例中的列表填充如下:

object PackListManager {
    const val LOGCAT_TAG = "BCSPackListMan"
    val localList : ArrayList<PackageMetadata> = ArrayList()
    var onlineList : ArrayList<PackageMetadata> = ArrayList()

    fun populate(){
        localList.clear(); onlineList.clear()
        val localPacks = HashMap(PackLocalManager.getLocalPacks().map {
            val parts = stripExtension(it.nameWithoutExtension).split("_")
            if (parts.count() > 1) {
                parts[0] to Version(parts[1])
            } else {
                it.nameWithoutExtension to Version("0.0")
            }
        }.toMap())
        for (pack in MetadataManager.packMap){
            if (localPacks.containsKey(pack.key)){
                Log.i(LOGCAT_TAG, "Pack "+pack.key+" found on local disk")
                if (localPacks[pack.key]!! < pack.value.Version){
                    Log.i(LOGCAT_TAG, "Pack "+pack.key+" can be updated")
                }
                localPacks.remove(pack.key)
                localList.add(pack.value)
            } else {
                Log.i(LOGCAT_TAG, "Pack "+pack.key+" not installed")
                onlineList.add(pack.value)
            }
        }
    }

通過查看logcat,我可以說polulate()函數生成的列表是正確的,而如果沒有調用上述手動刷新,MetadataManager.packMap shuold 保持不變。

我在谷歌上搜索過這樣的問題,但我似乎找不到一個很好的答案。 我真的很抱歉發布這么長的代碼,但我真的無法自己弄清楚。 任何幫助將不勝感激!

順便說一句,我不是母語人士,因此對於帖子中的錯誤感到抱歉。

不要使用ListView ,因為它已經過時了,而不是嘗試RecyclerView

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM