我创建了一个基于用户输入的listView。用户必须在editText中输入文本,然后将其添加到列表中。它很棒。我的问题是,如何保存这些数据,即使他们关闭应用程序,然后再次打开它,listView仍然有上次的项目?这是我的代码:
MainActivity.java
package com.kass.planner2;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import java.util.ArrayList;
public class MainActivity extends Activity implements View.OnClickListener {
private Button btn;
private EditText et;
private ListView lv;
ArrayList<String> list = new ArrayList<String>();
ArrayAdapter<String> adapter;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button)findViewById(R.id.button);
btn.setOnClickListener(this);
et = (EditText)findViewById(R.id.editText);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, list);
// set the lv variable to your list in the xml
lv=(ListView)findViewById(R.id.listView);
lv.setAdapter(adapter);
}
public void onClick(View v)
{
String input = et.getText().toString();
if(input.length() > 0)
{
// add string to the adapter, not the listview
adapter.add(input);
// no need to call adapter.notifyDataSetChanged(); as it is done by the adapter.add() method
}
}
}
activity_main.xml中
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.kass.planner2.MainActivity"
android:weightSum="1">
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_weight="1.12">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/editText"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_marginTop="60dp"
android:layout_alignEnd="@+id/button" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="@+id/button"
android:layout_centerVertical="true"
android:layout_alignParentStart="true"
android:onClick="saveEvent"/>
<ListView
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/listView"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:layout_toEndOf="@+id/editText" />
</RelativeLayout>
</LinearLayout>
谢谢。
答案 0 :(得分:1)
Listview,顾名思义是一个可以显示数据的View
。它实际上并不保存数据。要保存数据,您必须使用数据库或SharedPreferences
。通常,共享首选项用于保存应用程序的快速设置
要保存数据,您需要使用每个Android设备中存在的SQLite数据库。这是使用android中的SQLiteDatabase
和SQLiteOpenHelper
类完成的
要将数据绑定到像ListView一样显示多个数据行的视图,您需要使用适配器。 SimpleCursorAdapter
课程很容易完成这项工作
您可以在此处找到将数据绑定到TextView
here等控件的教程。它将让您了解如何在您的设备上设置数据库
完成后,您可以阅读SimpleCursorAdapter
here。
答案 1 :(得分:1)
考虑到你还在学习,我建议你先从使用SQLite方法开始。 http://www.tutorialspoint.com/android/android_sqlite_database.htm
为了更快更清洁地实施,您可以使用像SugarORM这样的ORM:http://satyan.github.io/sugar/
他们可以使用简单的命令来轻松构建数据库并从中提取数据。
答案 2 :(得分:0)
您可以使用PreferenceManager或内部SQL数据库来完成任务。
以下是如何使用内部SQL数据库的示例:
Android附带嵌入式SQLite数据库。数据库需要一个表才能存储任何输入,称为“InputTable”。在与MainActivity.java相同的位置创建一个新的db文件夹。然后创建一个名为InputContract的新类,文件名为InputContract.java:
package com.example.db;
import android.provider.BaseColumns;
public class InputContract {
public static final String DB_NAME = "com.example.db";
public static final int DB_VERSION = 1;
public class TaskEntry implements BaseColumns {
public static final String TABLE = "tasks";
public static final String COL_TASK_TITLE = "title";
}
}
InputContract类定义用于访问数据库中数据的常量。您还需要一个名为InputDbHelper的帮助程序类来打开数据库。在db包中创建此类并添加以下代码:
package com.example.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class InputDbHelper extends SQLiteOpenHelper {
public InputDbHelper(Context context) {
super(context, InputContract.DB_NAME, null, InputContract.DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + InputContract.TaskEntry.TABLE + " ( " +
InputContract.TaskEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
InputContract.TaskEntry.COL_TASK_TITLE + " TEXT NOT NULL);";
db.execSQL(createTable);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + InputContract.TaskEntry.TABLE);
onCreate(db);
}
}
现在您需要调整MainActivity以将数据存储在数据库中。
在MainActivity类中添加InputDbHelper的私有实例:
private InputDbHelper mHelper;
现在您需要从数据库中获取所有数据并在主视图中显示它。
将onCreate替换为:
btn = (Button)findViewById(R.id.button);
btn.setOnClickListener(this);
et = (EditText)findViewById(R.id.editText);
lv=(ListView)findViewById(R.id.listView);
mHelper = new InputDbHelper(this);
updateUI();
在点击方法中,添加以下代码:
String input = et.getText().toString();
SQLiteDatabase db = mHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(InputContract.TaskEntry.COL_TASK_TITLE, input);
db.insertWithOnConflict(InputContract.TaskEntry.TABLE, null, values, SQLiteDatabase.CONFICT_REPLACE);
db.close();
updateUI();
然后将以下方法添加到MainActivity以更新UI:
private void updateUI() {
ArrayList<String> taskList = new ArrayList<>();
SQLiteDatabase db = mHelper.getReadableDatabase();
Cursor cursor = db.query(InputContract.TaskEntry.TABLE,
new String[]{InputContract.TaskEntry._ID, InputContract.TaskEntry.COL_TASK_TITLE},
null, null, null, null, null);
while (cursor.moveToNext()) {
int idx = cursor.getColumnIndex(InputContract.TaskEntry.COL_TASK_TITLE);
taskList.add(cursor.getString(idx));
}
if (adapter== null) {
adapter= new ArrayAdapter<>(this, android.R.layout.simple_expandable_list_item_1,
taskList);
lv.setAdapter(adapter);
} else {
adapter.clear();
adapter.addAll(taskList);
adapter.notifyDataSetChanged();
}
cursor.close();
db.close();
}
现在,即使手机完全重启,列表视图中的信息仍会保留。
<强>此外:强>
如果您想删除数据库中的任何内容,请添加以下方法:
public void deleteTask() {
SQLiteDatabase db = mHelper.getWritableDatabase();
db.delete(InputContract.TaskEntry.TABLE,
InputContract.TaskEntry.COL_TASK_TITLE + " = ?",
new String[]{"Name of entry you want deleted"});
db.close();
updateUI();
}
答案 3 :(得分:0)
如果您不想使用数据库,这里有一个技巧可以帮助您使用一点点逻辑来处理文件
public void writeData(String data) // to writeData to file
{
String fileName="listData.txt";
try {
FileOutputStream fileout=openFileOutput(fileName, MODE_APPEND);
OutputStreamWriter outputWriter=new OutputStreamWriter(fileout);
outputWriter.write(data);
outputWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public String readFile()
{
String fileName="listData.txt";
String line,data="";
try {
FileInputStream fIn = openFileInput ( fileName ) ;
InputStreamReader isr = new InputStreamReader ( fIn ) ;
BufferedReader br = new BufferedReader ( isr ) ;
while((line=br.readLine())!=null)
{
data=data+line;
}
isr.close ( ) ;
} catch ( IOException ioe ) {
ioe.printStackTrace ( ) ;
}
return data;
}
以下是必须调用的方法
public void storeData() // call this in the onclick
{
String res="";
res= res + editText().getText().toString() + "\n"; // used \n as delimiter
writeData(res);
}
现在就是诀窍。在oncreate中,在创建arrayadapter
之前调用splitIntoList()方法public void splitIntoList()
{
String result=readFile();
//Here is a little logic
StringTokenizer st=new StringTokenizer(result,"\n");
while(st.hasMoreTokens())
{
list.add(st.nextToken());
}
}
请检查错误,因为我还没有在IDE上运行此代码