在Android应用程序中保存列表视图

时间:2015-03-14 16:53:03

标签: android database sqlite android-listview

我制作了一个包含编辑文字和添加按钮的自定义列表。用户将文本输入编辑文本,点击添加按钮,然后将按钮添加到列表视图中。问题是,一旦我退出应用程序,所有添加的列表都被删除了。如何轻松保存列表视图,以便在打开应用程序时添加的项目不会被删除。

activity_main:

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<EditText
    android:id="@+id/editText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_toLeftOf="@+id/addItem"
    android:hint="Add a new item to List View" />

<Button
    android:id="@+id/addItem"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:text="Add" />

<ListView
    android:id="@+id/listView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/editText" >
</ListView>

item_row:

<RelativeLayout
android:id="@+id/relativeLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="5dip">

<ImageView
    android:layout_width="78dip"
    android:layout_height="78dip"
    android:id="@+id/imgThumbnail"
    android:scaleType="centerInside"
    android:layout_alignParentTop="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true">
</ImageView>

<TextView
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:layout_height="wrap_content"
    android:text="TextView"
    android:layout_width="wrap_content"
    android:id="@+id/txtTitle"
    android:layout_toRightOf="@+id/imgThumbnail"
    android:layout_marginTop="6dip"
    android:layout_marginLeft="6dip">
</TextView>

<TextView
    android:layout_height="wrap_content"
    android:text="TextView"
    android:layout_width="wrap_content"
    android:id="@+id/txtSubTitle"
    android:layout_toRightOf="@+id/imgThumbnail"
    android:layout_below="@+id/txtTitle"
    android:layout_marginTop="3dip"
    android:layout_marginLeft="6dip">
</TextView>

MainActivity:

public class MainActivity extends ActionBarActivity implements  
View.OnClickListener{

EditText et;

Button bt;

Button rbt;

ListView lv;

List<ListViewItem> items;

CustomListViewAdapter adapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    et = (EditText) findViewById(R.id.editText);
    bt = (Button) findViewById(R.id.addItem);
    bt.setOnClickListener(this);

    rbt = (Button) findViewById(R.id.removeItem);
    rbt.setOnClickListener(this);

    lv = (ListView) findViewById(R.id.listView);
    items = new ArrayList<ListViewItem>();
    adapter = new CustomListViewAdapter(this, items);

    lv.setOnItemLongClickListener(new ListView.OnItemLongClickListener() {
        // setting onItemLongClickListener and passing the position to the function
        @Override
        public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
                                       int position, long arg3) {
            removeItemFromList(position);

            return true;
        }
    });
}

@Override
public void onClick(View v) {
    switch(v.getId()) {

        case R.id.addItem:

            items.add(new ListViewItem() {{

                ThumbnailResource = R.mipmap.ic_launcher;
                Title = et.getText().toString();
                SubTitle = "Item2 Description";

            }});
            lv.setAdapter(adapter);
        break;
    }

}

class ListViewItem {

        public int ThumbnailResource;
        public String Title;
        public String SubTitle;
}

protected void removeItemFromList(int position) {
    final int deletePosition = position;

    AlertDialog.Builder alert = new AlertDialog.Builder(
            MainActivity.this);

    alert.setTitle("Delete");
    alert.setMessage("Do you want delete this item?");
    alert.setPositiveButton("YES", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            // TOD O Auto-generated method stub

            // main code on after clicking yes
            items.remove(deletePosition);
            adapter.notifyDataSetChanged();
            adapter.notifyDataSetInvalidated();

        }
    });
    alert.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            // TODO Auto-generated method stub
            dialog.dismiss();
        }
    });

    alert.show();

    }
}

CustomListViewAdapter:

public class CustomListViewAdapter extends BaseAdapter {

LayoutInflater inflater;
List<MainActivity.ListViewItem> items;

public CustomListViewAdapter(Activity context, List<MainActivity.ListViewItem> items) {
    super();

    this.items = items;
    this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return items.size();
}

@Override
public Object getItem(int position) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public long getItemId(int position) {
    // TODO Auto-generated method stub
    return 0;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub

    MainActivity.ListViewItem item = items.get(position);

    View vi=convertView;

    if(convertView==null)
        vi = inflater.inflate(R.layout.item_row, null);

    ImageView imgThumbnail = (ImageView) vi.findViewById(R.id.imgThumbnail);

    TextView txtTitle = (TextView) vi.findViewById(R.id.txtTitle);

    TextView txtSubTitle = (TextView) vi.findViewById(R.id.txtSubTitle);

    imgThumbnail.setImageResource(item.ThumbnailResource);

    txtTitle.setText(item.Title);

    txtSubTitle.setText(item.SubTitle);

    return vi;
   }
}

2 个答案:

答案 0 :(得分:0)

首先,您必须通过扩展sqliteOpenHelper类来创建数据库适配器和数据库帮助程序类。
这是一个实现示例:

public class DbAdapter {
    Context context;
    DbHelper dbHelper;

    DbAdapter(Context context)
    {
        dbHelper = new DbHelper(context);this.context = context;
    }


    //INSERTION OF ACTUAL DATA HANDLE HERE
    public long insertData(String course, String room,String day)
    {
        ContentValues contentValues = new ContentValues();

        contentValues.put(dbHelper.COURSE, course);
        contentValues.put(dbHelper.ROOM, room);
        contentValues.put(dbHelper.DAY, day);

        SQLiteDatabase db = dbHelper.getWritableDatabase();

        //Following just executes and insert the data for you 



        return db.insert(dbHelper.TABLE_NAME,null,contentValues);
    }


    //returns all the data from the database !
    public Cursor getData(String day)
    {
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        String column[] = {dbHelper.ID,dbHelper.COURSE, dbHelper.ROOM};


        return db.query(dbHelper.TABLE_NAME,column,dbHelper.DAY+" = '"+day+"'",null,null,null,null);

    }

    public void updateData(String subTitle, String subRoom, ,  int arg)
    {
        SQLiteDatabase db = dbHelper.getWritableDatabase();

        ContentValues contentValues = new ContentValues();
        contentValues.put(dbHelper.COURSE,subTitle);
        contentValues.put(dbHelper.ROOM,subRoom);


        try
        {
            db.update(dbHelper.TABLE_NAME,contentValues,dbHelper.ID +" = "+arg,null);
        } catch (Exception e)
        {
            Log.d("Update", e.toString());
        }
    }



    public static class DbHelper extends SQLiteOpenHelper {

        private Context context;
        //Database Schema for Weekly Course Schedule

        private static final String DATABASE_NAME = "TimeTable";
        public static final String TABLE_NAME = "Schedule";
        public static final String ID = "_id";
        public static final String COURSE = "course";
        public static final String ROOM = "room";
        public static final String DAY = "day";
        private static final int DATABASE_VERSION = 1;

        private String CREATE = "CREATE TABLE "+TABLE_NAME+ "( "+ID+" INTEGER PRIMARY KEY AUTOINCREMENT,"+COURSE+" VARCHAR(50),"+ROOM+" VARCHAR(50),  "+DAY+" VARCHAR(15));";


        public DbHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
            this.context = context;

            //Log.d("DB","DB Constructor Called 1");
        }

        @Override
        public void onCreate(SQLiteDatabase db)
        {
            try
            {
                db.execSQL(CREATE);
                Log.d("DB try","db.OnCreate() called");
                Toast.makeText(context,"DataBase Created !",Toast.LENGTH_LONG).show();

            } catch (SQLException e)
            {
                Toast.makeText(context,e.toString(),Toast.LENGTH_LONG).show();
            }
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
        {
            try {
                db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
                Toast.makeText(context,"Dropped !",Toast.LENGTH_SHORT).show();
                onCreate(db);
            } catch (SQLException e)
            {
                Toast.makeText(context,e.toString(),Toast.LENGTH_LONG).show();
            }
        }
    }


}

答案 1 :(得分:0)

我认为,为了您的目的,有三种主要方法,我将从更容易到最困难(在我看来)解释它们。

文字档案

这样做的一种方法是在一个类中创建两个方法:一个必须在存储中创建文本文件,如果它之前没有创建并读取它,另一个必须将一个String附加到一个StringBuilder并写入它在上一个文本文件中。

对于此方法,您需要具有读取和写入存储的使用权限。

此链接可以帮助您:http://developer.android.com/training/basics/data-storage/files.html

JSON(也是XML)

使用JSON文件,您可以创建包含数据的对象列表,您可以在更新列表时进行序列化,并在需要时进行反序列化。为此,您必须学习JavaScript语法,或者至少学习JSON语法。

SQLite数据库

Android SDK包含一个名为SQLiteOpenHelper的类,您可以扩展该类以在应用程序内创建数据库。

此链接可以帮助您:http://developer.android.com/training/basics/data-storage/databases.html

还有一些参考保存方法,但我认为这不适合您的目的,他们更好地保存偏好或单个数据,如上次登录信息。