Android:从Data Activity的Spinner传数据至History Activity的ListView且不跳转页面
Got it, let's break down how to solve this problem. The core requirement here is saving the selected values from your Spinners in Data Activity without launching History Activity right away, then displaying those saved entries whenever the user opens History Activity later. Here are two practical approaches based on your data needs:
方案1:使用SharedPreferences(适合少量、无严格顺序要求的历史数据)
This is the simplest option if you're dealing with a small number of entries and don't need to track the order they were added.
Step 1: Save Spinner data from Data Activity
When the user selects a value in the Spinner (or triggers an action like a button click that should save the data), grab the selected value and store it in SharedPreferences. We'll use a Set<String> to automatically avoid duplicate entries:
// Inside Data Activity - get the selected Spinner value Spinner yourSpinner = findViewById(R.id.your_spinner_id); String selectedValue = yourSpinner.getSelectedItem().toString(); // Save to SharedPreferences SharedPreferences historyPrefs = getSharedPreferences("HistoryStorage", MODE_PRIVATE); SharedPreferences.Editor editor = historyPrefs.edit(); // Retrieve existing history (or create an empty set if none exists) Set<String> historySet = historyPrefs.getStringSet("saved_history", new HashSet<>()); historySet.add(selectedValue); editor.putStringSet("saved_history", historySet); editor.apply(); // Use apply() for async save, commit() for sync
Step 2: Load and display data in History Activity
When History Activity is opened later, read the saved data from SharedPreferences and populate your ListView:
First, your History Layout should have a ListView (like you mentioned):
<!-- History Layout snippet --> <ListView android:id="@+id/history_listview" android:layout_width="match_parent" android:layout_height="match_parent"/>
Then in History Activity's code:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_history_layout); ListView historyListView = findViewById(R.id.history_listview); // Load saved history from SharedPreferences SharedPreferences historyPrefs = getSharedPreferences("HistoryStorage", MODE_PRIVATE); Set<String> historySet = historyPrefs.getStringSet("saved_history", new HashSet<>()); List<String> historyList = new ArrayList<>(historySet); // Use an ArrayAdapter to display the data ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, historyList); historyListView.setAdapter(adapter); }
方案2:使用Room数据库(适合大量、需按时间排序的历史数据)
If you need to track the order entries were added, or expect a large number of history items, Room (Android's recommended local database library) is a better choice.
Step 1: Add Room dependencies
Add these to your app-level build.gradle (Module level):
dependencies { def room_version = "2.5.0" implementation "androidx.room:room-runtime:$room_version" annotationProcessor "androidx.room:room-compiler:$room_version" }
Step 2: Create Room components
First, define an Entity class to represent each history entry (with a timestamp for sorting):
@Entity(tableName = "history_entries") public class HistoryEntry { @PrimaryKey(autoGenerate = true) public int id; @ColumnInfo(name = "spinner_value") public String value; @ColumnInfo(name = "created_at") public long timestamp; public HistoryEntry(String value, long timestamp) { this.value = value; this.timestamp = timestamp; } }
Next, create a DAO (Data Access Object) to handle database operations:
@Dao public interface HistoryDao { @Insert void insertEntry(HistoryEntry entry); @Query("SELECT * FROM history_entries ORDER BY created_at DESC") List<HistoryEntry> getAllEntries(); // Gets entries in reverse chronological order }
Then create the Room Database class:
@Database(entities = {HistoryEntry.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract HistoryDao historyDao(); private static volatile AppDatabase INSTANCE; public static AppDatabase getInstance(Context context) { if (INSTANCE == null) { synchronized (AppDatabase.class) { if (INSTANCE == null) { INSTANCE = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, "history_database") .build(); } } } return INSTANCE; } }
Step 3: Save data from Data Activity
Insert the selected Spinner value into the database (remember to run database operations on a background thread):
// Inside Data Activity Spinner yourSpinner = findViewById(R.id.your_spinner_id); String selectedValue = yourSpinner.getSelectedItem().toString(); long currentTime = System.currentTimeMillis(); // Insert into Room (run on background thread) new Thread(() -> { AppDatabase db = AppDatabase.getInstance(DataActivity.this); db.historyDao().insertEntry(new HistoryEntry(selectedValue, currentTime)); }).start();
Step 4: Load and display data in History Activity
Read the sorted entries from the database and update the ListView on the main thread:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_history_layout); ListView historyListView = findViewById(R.id.history_listview); List<String> historyItems = new ArrayList<>(); // Load data from Room (background thread) new Thread(() -> { AppDatabase db = AppDatabase.getInstance(HistoryActivity.this); List<HistoryEntry> entries = db.historyDao().getAllEntries(); for (HistoryEntry entry : entries) { historyItems.add(entry.value); } // Update UI on main thread runOnUiThread(() -> { ArrayAdapter<String> adapter = new ArrayAdapter<>(HistoryActivity.this, android.R.layout.simple_list_item_1, historyItems); historyListView.setAdapter(adapter); }); }).start(); }
Key Notes
- Why not direct intent passing? Because you don't want to launch History Activity immediately, there's no active instance of the Activity to send data to. Persistent storage (like SharedPreferences or Room) is the only way to save data for later use.
- If you need to update History Activity's ListView in real-time (e.g., if it's already open while saving data from Data Activity), you could use a
ContentObserveror LiveData with Room to observe changes automatically.
内容的提问来源于stack exchange,提问作者Kostas Mirzaev

