You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android:如何从外部Activity更新ListView内容?

Hey there! Let's tackle how to update your MainActivity's SimpleListView from AddingItemsActivity — I've got two solid approaches that fit right into your project setup.

This is Android's modern, recommended way to pass data back from one Activity to another, replacing the old startActivityForResult API.

Step 1: Register a Result Launcher in MainActivity

First, set up a launcher to listen for results from AddingItemsActivity:

// MainActivity.kt
private val addItemLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == RESULT_OK) {
        // Retrieve the new/updated SimpleItem from the result intent
        val modifiedItem = result.data?.getParcelableExtra<SimpleItem>("MODIFIED_ITEM")
        modifiedItem?.let { item ->
            // Assume you have a mutable list holding your data (e.g., private val items = mutableListOf<SimpleItem>())
            val existingIndex = items.indexOfFirst { it.id == item.id }
            
            if (existingIndex != -1) {
                // Update existing item
                items[existingIndex] = item
                itemAdapter.notifyItemChanged(existingIndex)
            } else {
                // Add new item
                items.add(item)
                itemAdapter.notifyItemInserted(items.size - 1)
            }
        }
    }
}

Step 2: Launch AddingItemsActivity

Trigger the Activity from your add/update button in MainActivity:

btnAddOrUpdate.setOnClickListener {
    val intent = Intent(this, AddingItemsActivity::class.java)
    // If you're updating an existing item, pass it to the Activity here:
    // intent.putExtra("EDIT_ITEM", itemToEdit)
    addItemLauncher.launch(intent)
}

Step 3: Return Data from AddingItemsActivity

Once the user finishes adding/updating an item, send the data back to MainActivity:

// AddingItemsActivity.kt
btnSave.setOnClickListener {
    val itemName = etItemName.text.toString().trim()
    if (itemName.isNotEmpty()) {
        // Create or update the SimpleItem
        val modifiedItem = intent.getParcelableExtra<SimpleItem>("EDIT_ITEM")?.copy(name = itemName)
            ?: SimpleItem(id = System.currentTimeMillis(), name = itemName)
        
        // Package the item and send it back
        val resultIntent = Intent().apply {
            putExtra("MODIFIED_ITEM", modifiedItem)
        }
        setResult(RESULT_OK, resultIntent)
        finish()
    }
}

Important: Make SimpleItem Parcelable

To pass SimpleItem via Intent, it needs to implement the Parcelable interface:

// SimpleItem.kt
data class SimpleItem(val id: Long, val name: String) : Parcelable {
    constructor(parcel: Parcel) : this(
        parcel.readLong(),
        parcel.readString() ?: ""
    )

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeLong(id)
        parcel.writeString(name)
    }

    override fun describeContents(): Int = 0

    companion object CREATOR : Parcelable.Creator<SimpleItem> {
        override fun createFromParcel(parcel: Parcel): SimpleItem = SimpleItem(parcel)
        override fun newArray(size: Int): Array<SimpleItem?> = arrayOfNulls(size)
    }
}

Approach 2: Use ViewModel + LiveData (Best for Complex/Shared Data)

If you want a more robust solution that handles configuration changes (like screen rotation) and keeps data decoupled from Activities, use Android Architecture Components.

Step 1: Create a Shared ViewModel

This ViewModel will hold your item data and handle updates:

// ItemViewModel.kt
class ItemViewModel : ViewModel() {
    private val _items = MutableLiveData<MutableList<SimpleItem>>(mutableListOf())
    val items: LiveData<MutableList<SimpleItem>> = _items

    fun addItem(item: SimpleItem) {
        val currentItems = _items.value ?: mutableListOf()
        currentItems.add(item)
        _items.postValue(currentItems)
    }

    fun updateItem(updatedItem: SimpleItem) {
        val currentItems = _items.value ?: mutableListOf()
        val index = currentItems.indexOfFirst { it.id == updatedItem.id }
        if (index != -1) {
            currentItems[index] = updatedItem
            _items.postValue(currentItems)
        }
    }
}

Step 2: Connect MainActivity to the ViewModel

Observe the LiveData to automatically refresh the ListView when data changes:

// MainActivity.kt
private lateinit var viewModel: ItemViewModel
private lateinit var itemAdapter: ItemAdapter

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

    viewModel = ViewModelProvider(this)[ItemViewModel::class.java]
    itemAdapter = ItemAdapter(viewModel.items.value ?: mutableListOf())
    SimpleListView.adapter = itemAdapter

    // Refresh adapter whenever the item list updates
    viewModel.items.observe(this) { newItems ->
        itemAdapter.updateData(newItems)
    }

    btnAddItem.setOnClickListener {
        startActivity(Intent(this, AddingItemsActivity::class.java))
    }
}

Step 3: Update Adapter to Support Data Changes

Add a method to your ItemAdapter to update the dataset efficiently:

// ItemAdapter.kt
class ItemAdapter(private var items: MutableList<SimpleItem>) : BaseAdapter() {
    override fun getCount(): Int = items.size
    override fun getItem(position: Int): SimpleItem = items[position]
    override fun getItemId(position: Int): Long = items[position].id
    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        // Implement your view inflation and binding here as usual
    }

    fun updateData(newItems: MutableList<SimpleItem>) {
        this.items = newItems
        // For better performance, use DiffUtil instead of notifyDataSetChanged
        notifyDataSetChanged()
    }
}

Step 4: Modify Data from AddingItemsActivity

Directly update the ViewModel from AddingItemsActivity — no need to pass data via Intent:

// AddingItemsActivity.kt
private lateinit var viewModel: ItemViewModel

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_adding_items)

    viewModel = ViewModelProvider(this)[ItemViewModel::class.java]
    val editItem = intent.getParcelableExtra<SimpleItem>("EDIT_ITEM")
    
    // Pre-fill the input if editing an existing item
    editItem?.let { etItemName.setText(it.name) }

    btnSave.setOnClickListener {
        val itemName = etItemName.text.toString().trim()
        if (itemName.isNotEmpty()) {
            val modifiedItem = editItem?.copy(name = itemName)
                ?: SimpleItem(id = System.currentTimeMillis(), name = itemName)
            
            if (editItem != null) viewModel.updateItem(modifiedItem)
            else viewModel.addItem(modifiedItem)
            
            finish()
        }
    }
}

Quick Tips

  • For better adapter performance, replace notifyDataSetChanged() with DiffUtil to only update changed items.
  • The ViewModel approach is ideal if you plan to expand your app (e.g., add Fragments that share the same item data).

内容的提问来源于stack exchange,提问作者Czarek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:10:01