如何在listView中保存数据

时间:2016-06-15 16:58:05

标签: java android listview

我创建了一个基于用户输入的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>

谢谢。

4 个答案:

答案 0 :(得分:1)

Listview,顾名思义是一个可以显示数据的View。它实际上并不保存数据。要保存数据,您必须使用数据库或SharedPreferences。通常,共享首选项用于保存应用程序的快速设置 要保存数据,您需要使用每个Android设备中存在的SQLite数据库。这是使用android中的SQLiteDatabaseSQLiteOpenHelper类完成的 要将数据绑定到像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上运行此代码