离开 Android 活动后保留 ListView 数据
Retaining ListView data after leaving Android acitivity
我是 Android Studio 的新手。我正在尝试使用 ListView,用户可以在其中将项目添加到列表中。但是当用户更改或关闭 activity 时,我希望这些项目像用户最后一次看到它们时一样返回。我不太熟悉 activity LifeCycle 以及如何使用它,所以任何资源或帮助表示赞赏。谢谢。这是我的代码:
package com.example.listviewtest;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity<i> extends AppCompatActivity {
private List nameArr;
private String textToAdd;
//input textbox
private EditText stuff;
// Add player names and scores to the list
private ListView score_lv;
//Append
private ArrayAdapter<String> arrayAdapter1;
//Clear Scores button
private Button updateButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
nameArr = new ArrayList<Object>();
stuff = (EditText)findViewById(R.id.editText);
score_lv = (ListView) findViewById(R.id.theList);
arrayAdapter1 = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, nameArr);
updateButton = (Button) findViewById(R.id.addButton);
updateButton.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
nameArr.add(stuff.getText().toString());
//get data from other activity
textToAdd = getIntent().getExtras().getString("textData");
score_lv.setAdapter(arrayAdapter1);
}
});
final Button nextAct = (Button) findViewById(R.id.toNext);
nextAct.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
Intent j = new Intent(MainActivity.this, Main2Activity.class);
startActivity(j);
}
}
);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
编辑:
我能够使用 FileInputStream 和 FileOutputStream 更新列表(我正在尝试写入内部存储)。因为这个应用程序有 2 个活动,所以当我切换到另一个 activity 并返回到这个应用程序时,列表及其所有项目仍然存在。但是,当我完全关闭应用程序然后重新打开应用程序时,列表中的所有项目似乎都消失了。我如何让它保持使用 FileI/OStreams(我知道还有其他方法,如 SQLite 等,但我试图通过使用其他方法来挑战自己)。到目前为止,这是我更新的代码(再次感谢大家的帮助):
package com.example.listviewtest;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MainActivity<i> extends AppCompatActivity {
private static final List nameArr = new ArrayList<Object>();
//input textbox
private EditText stuff;
// Add player names and scores to the list
private ListView score_lv;
//Append
private ArrayAdapter<String> arrayAdapter1;
//Clear Scores button
private Button updateButton;
private static final String fileName = "scores";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
stuff = (EditText)findViewById(R.id.editText);
score_lv = (ListView) findViewById(R.id.theList);
arrayAdapter1 = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, nameArr);
score_lv.setAdapter(arrayAdapter1);
//button to update the ListView
updateButton = (Button) findViewById(R.id.addButton);
updateButton.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
//write data to the internal phone app File
try{
FileOutputStream fileOS = openFileOutput("scores", MODE_PRIVATE);
OutputStreamWriter osw = new OutputStreamWriter(fileOS);
try{
osw.write(stuff.getText().toString());
osw.flush();
osw.close();
Toast.makeText(getBaseContext(),"Scores Saved to "+getFilesDir() + "/", Toast.LENGTH_LONG).show();
}catch(IOException e){
e.printStackTrace();
}
}catch (FileNotFoundException e){
e.printStackTrace();
}
//read data from Saved File to update the ListView
nameArr.add(readFile("scores"));
score_lv.setAdapter(arrayAdapter1);
}
});
//button to go to the next Activity
final Button nextAct = (Button) findViewById(R.id.toNext);
nextAct.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
Intent j = new Intent(MainActivity.this, Main2Activity.class);
startActivity(j);
}
}
);
}
//as soon as this Activity starts, we read from the Output File
public String readFile(String file){
StringBuilder text = new StringBuilder();
try{
FileInputStream fis = openFileInput(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
String line;
while((line = reader.readLine()) != null){
text.append(line);
}
reader.close();
}catch(Exception e){
e.printStackTrace();
Toast.makeText(MainActivity.this,"Error reading file!",Toast.LENGTH_LONG).show();
}
return text.toString();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
@rodgy,将数据保存到 non-volatile memory,然后在加载应用程序时读取数据。
试试这个代码
private List<String> nameArr = new ArrayList<>();
private static SharedPreferences sharedPreferences = context.getSharedPreferences("PREFS_NAME", Context.MODE_PRIVATE);
private static SharedPreferences.Editor editor = sharedPreferences.edit();
#how to use
// save data
setToList("1", nameArr);
// get data
nameArr = getList("1");
// save to sharedPreferences
public void setList(String key, List<String> list) {
String json = new Gson().toJson(list);
editor.putString(key, json);
editor.commit();
}
// read from sharedPreferences
public List<String> getList(String key){
List<String> result = new ArrayList<>();
String serObject = sharedPreferences.getString(key, null);
if (serObject != null){
Type type = new TypeToken<List<String>>(){}.getType();
result = new Gson().fromJson(serObject, type);
}
return result;
}
所以我添加了一个清除按钮,但我能够在我保存在内部设备存储中的 "scores" 文件中保存多行。当我关闭应用程序或转到另一个 activity 并使用 ListView 返回此 MainActivity 时,信息仍然存在(因为它直接从 "scores" 文件读取)。唯一的事情是它更新了第一个也是唯一的 ListView 项目。我用了 nameArr.clear();每次清除 ListView 和 nameArr.clear();和 text.append('\n');读取和写入文件,以便用户输入的每个文本都按照我希望的方式显示 (作为列表)。所以这是我的最终代码:
public class MainActivity<i> extends AppCompatActivity {
private static final List nameArr = new ArrayList<Object>();
//input textbox
private EditText stuff;
// Add player names and scores to the list
private ListView score_lv;
//Append
private ArrayAdapter<String> arrayAdapter1;
//Clear Scores button
private Button updateButton;
private static final String fileName = "scores";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
stuff = (EditText)findViewById(R.id.editText);
score_lv = (ListView) findViewById(R.id.theList);
arrayAdapter1 = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, nameArr);
nameArr.clear();
nameArr.add(readFile(fileName));
score_lv.setAdapter(arrayAdapter1);
//button to update the ListView
updateButton = (Button) findViewById(R.id.addButton);
updateButton.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
//write data to the internal phone app File
try{
FileOutputStream fileOS = openFileOutput(fileName, MODE_APPEND);
OutputStreamWriter osw = new OutputStreamWriter(fileOS);
try{
osw.write("\n");
osw.write(stuff.getText().toString());
osw.flush();
osw.close();
Toast.makeText(getBaseContext(),"Scores Saved to "+getFilesDir() + "/", Toast.LENGTH_LONG).show();
}catch(IOException e){
e.printStackTrace();
}
}catch (FileNotFoundException e){
e.printStackTrace();
}
//read data from Saved File to update the ListView with ALL items from the file
nameArr.clear();
nameArr.add(readFile(fileName));
score_lv.setAdapter(arrayAdapter1);
}
});
//button to go to the next Activity
final Button nextAct = (Button) findViewById(R.id.toNext);
nextAct.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
Intent j = new Intent(MainActivity.this, Main2Activity.class);
startActivity(j);
}
}
);
//delete file and clear ListView button
final Button clearB = (Button) findViewById(R.id.clearButton);
clearB.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
deleteFile(fileName);
Toast.makeText(getBaseContext(), "List Cleared", Toast.LENGTH_LONG).show();
//clear list
score_lv.setAdapter(null);
}
}
);
}
//as soon as this Activity starts, we read from the Output File
public String readFile(String file){
StringBuilder text = new StringBuilder();
try{
FileInputStream fis = openFileInput(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
String line;
while((line = reader.readLine()) != null){
text.append(line);
text.append('\n');
}
reader.close();
}catch(Exception e){
e.printStackTrace();
Toast.makeText(MainActivity.this,"Error reading file!",Toast.LENGTH_LONG).show();
}
return text.toString();
}
我是 Android Studio 的新手。我正在尝试使用 ListView,用户可以在其中将项目添加到列表中。但是当用户更改或关闭 activity 时,我希望这些项目像用户最后一次看到它们时一样返回。我不太熟悉 activity LifeCycle 以及如何使用它,所以任何资源或帮助表示赞赏。谢谢。这是我的代码:
package com.example.listviewtest;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity<i> extends AppCompatActivity {
private List nameArr;
private String textToAdd;
//input textbox
private EditText stuff;
// Add player names and scores to the list
private ListView score_lv;
//Append
private ArrayAdapter<String> arrayAdapter1;
//Clear Scores button
private Button updateButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
nameArr = new ArrayList<Object>();
stuff = (EditText)findViewById(R.id.editText);
score_lv = (ListView) findViewById(R.id.theList);
arrayAdapter1 = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, nameArr);
updateButton = (Button) findViewById(R.id.addButton);
updateButton.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
nameArr.add(stuff.getText().toString());
//get data from other activity
textToAdd = getIntent().getExtras().getString("textData");
score_lv.setAdapter(arrayAdapter1);
}
});
final Button nextAct = (Button) findViewById(R.id.toNext);
nextAct.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
Intent j = new Intent(MainActivity.this, Main2Activity.class);
startActivity(j);
}
}
);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
编辑:
我能够使用 FileInputStream 和 FileOutputStream 更新列表(我正在尝试写入内部存储)。因为这个应用程序有 2 个活动,所以当我切换到另一个 activity 并返回到这个应用程序时,列表及其所有项目仍然存在。但是,当我完全关闭应用程序然后重新打开应用程序时,列表中的所有项目似乎都消失了。我如何让它保持使用 FileI/OStreams(我知道还有其他方法,如 SQLite 等,但我试图通过使用其他方法来挑战自己)。到目前为止,这是我更新的代码(再次感谢大家的帮助):
package com.example.listviewtest;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MainActivity<i> extends AppCompatActivity {
private static final List nameArr = new ArrayList<Object>();
//input textbox
private EditText stuff;
// Add player names and scores to the list
private ListView score_lv;
//Append
private ArrayAdapter<String> arrayAdapter1;
//Clear Scores button
private Button updateButton;
private static final String fileName = "scores";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
stuff = (EditText)findViewById(R.id.editText);
score_lv = (ListView) findViewById(R.id.theList);
arrayAdapter1 = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, nameArr);
score_lv.setAdapter(arrayAdapter1);
//button to update the ListView
updateButton = (Button) findViewById(R.id.addButton);
updateButton.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
//write data to the internal phone app File
try{
FileOutputStream fileOS = openFileOutput("scores", MODE_PRIVATE);
OutputStreamWriter osw = new OutputStreamWriter(fileOS);
try{
osw.write(stuff.getText().toString());
osw.flush();
osw.close();
Toast.makeText(getBaseContext(),"Scores Saved to "+getFilesDir() + "/", Toast.LENGTH_LONG).show();
}catch(IOException e){
e.printStackTrace();
}
}catch (FileNotFoundException e){
e.printStackTrace();
}
//read data from Saved File to update the ListView
nameArr.add(readFile("scores"));
score_lv.setAdapter(arrayAdapter1);
}
});
//button to go to the next Activity
final Button nextAct = (Button) findViewById(R.id.toNext);
nextAct.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
Intent j = new Intent(MainActivity.this, Main2Activity.class);
startActivity(j);
}
}
);
}
//as soon as this Activity starts, we read from the Output File
public String readFile(String file){
StringBuilder text = new StringBuilder();
try{
FileInputStream fis = openFileInput(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
String line;
while((line = reader.readLine()) != null){
text.append(line);
}
reader.close();
}catch(Exception e){
e.printStackTrace();
Toast.makeText(MainActivity.this,"Error reading file!",Toast.LENGTH_LONG).show();
}
return text.toString();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
@rodgy,将数据保存到 non-volatile memory,然后在加载应用程序时读取数据。
试试这个代码
private List<String> nameArr = new ArrayList<>();
private static SharedPreferences sharedPreferences = context.getSharedPreferences("PREFS_NAME", Context.MODE_PRIVATE);
private static SharedPreferences.Editor editor = sharedPreferences.edit();
#how to use
// save data
setToList("1", nameArr);
// get data
nameArr = getList("1");
// save to sharedPreferences
public void setList(String key, List<String> list) {
String json = new Gson().toJson(list);
editor.putString(key, json);
editor.commit();
}
// read from sharedPreferences
public List<String> getList(String key){
List<String> result = new ArrayList<>();
String serObject = sharedPreferences.getString(key, null);
if (serObject != null){
Type type = new TypeToken<List<String>>(){}.getType();
result = new Gson().fromJson(serObject, type);
}
return result;
}
所以我添加了一个清除按钮,但我能够在我保存在内部设备存储中的 "scores" 文件中保存多行。当我关闭应用程序或转到另一个 activity 并使用 ListView 返回此 MainActivity 时,信息仍然存在(因为它直接从 "scores" 文件读取)。唯一的事情是它更新了第一个也是唯一的 ListView 项目。我用了 nameArr.clear();每次清除 ListView 和 nameArr.clear();和 text.append('\n');读取和写入文件,以便用户输入的每个文本都按照我希望的方式显示 (作为列表)。所以这是我的最终代码:
public class MainActivity<i> extends AppCompatActivity {
private static final List nameArr = new ArrayList<Object>();
//input textbox
private EditText stuff;
// Add player names and scores to the list
private ListView score_lv;
//Append
private ArrayAdapter<String> arrayAdapter1;
//Clear Scores button
private Button updateButton;
private static final String fileName = "scores";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
stuff = (EditText)findViewById(R.id.editText);
score_lv = (ListView) findViewById(R.id.theList);
arrayAdapter1 = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, nameArr);
nameArr.clear();
nameArr.add(readFile(fileName));
score_lv.setAdapter(arrayAdapter1);
//button to update the ListView
updateButton = (Button) findViewById(R.id.addButton);
updateButton.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
//write data to the internal phone app File
try{
FileOutputStream fileOS = openFileOutput(fileName, MODE_APPEND);
OutputStreamWriter osw = new OutputStreamWriter(fileOS);
try{
osw.write("\n");
osw.write(stuff.getText().toString());
osw.flush();
osw.close();
Toast.makeText(getBaseContext(),"Scores Saved to "+getFilesDir() + "/", Toast.LENGTH_LONG).show();
}catch(IOException e){
e.printStackTrace();
}
}catch (FileNotFoundException e){
e.printStackTrace();
}
//read data from Saved File to update the ListView with ALL items from the file
nameArr.clear();
nameArr.add(readFile(fileName));
score_lv.setAdapter(arrayAdapter1);
}
});
//button to go to the next Activity
final Button nextAct = (Button) findViewById(R.id.toNext);
nextAct.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
Intent j = new Intent(MainActivity.this, Main2Activity.class);
startActivity(j);
}
}
);
//delete file and clear ListView button
final Button clearB = (Button) findViewById(R.id.clearButton);
clearB.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
deleteFile(fileName);
Toast.makeText(getBaseContext(), "List Cleared", Toast.LENGTH_LONG).show();
//clear list
score_lv.setAdapter(null);
}
}
);
}
//as soon as this Activity starts, we read from the Output File
public String readFile(String file){
StringBuilder text = new StringBuilder();
try{
FileInputStream fis = openFileInput(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
String line;
while((line = reader.readLine()) != null){
text.append(line);
text.append('\n');
}
reader.close();
}catch(Exception e){
e.printStackTrace();
Toast.makeText(MainActivity.this,"Error reading file!",Toast.LENGTH_LONG).show();
}
return text.toString();
}