If you're not familiar with simple methods of creating and displaying lists, as well as storing and retrieving information with an SQLite database, please have a look at the following 2-part tutorial:
Populating A ListView Using SQLite: Android
We'll go with a simple layout for entering and retrieving data...
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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
android:gravity="center_horizontal"
tools:context=".MainActivity" >
<EditText
android:id="@+id/enterTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="Enter Book Title"/>
<EditText
android:id="@+id/enterAuthor"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="Enter Book Author"/>
<Button
android:id="@+id/setBook"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Save
Book"
android:onClick="onClick"/>
<EditText
android:id="@+id/retrieveBooks"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="Author of books to retrieve"/>
<Button
android:id="@+id/getBooks"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Get
Books"
android:onClick="onClick"/>
<ListView
android:id="@+id/theList"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/exit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Exit
Application"
android:onClick="onClick"/>
</LinearLayout>
|
For our book objects, we create the Book class...
Book.java
public class Book {
private long id;
private String title;
private String author;
public Book(String title, String author) {
this.title = title;
this.author = author;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String bookTitle) {
title = bookTitle;
}
public String getAuthor() {
return author;
}
public void setAuthor(String bookAuthor) {
author = bookAuthor;
}
@Override
public String toString() {
return "Book [id=" + id + ",
title=" + title + ", author=" + author
+ "]";
}
}
|
So far, the code should seem pretty straightforward to you. If it doesn't, I encourage you to check out Stack Overflow and search the site for some simple tutorials on Android application development.
We're going to build a custom adapter to display our books-by-author list where each row of the list has the following layout...
row_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
<TextView
android:id="@+id/bookTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"/>
<TextView
android:id="@+id/bookAuthor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"/>
</LinearLayout>
</LinearLayout>
|
This brings us to our custom adapter...
BookListAdapter.java
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
public class BookListAdapter extends ArrayAdapter<Book> {
private int resource;
private LayoutInflater
inflater;
private Context context;
// our constructor takes 3
parameters; keep this in mind when you set the adapter.
// resourceId will be our row_layout resource.
Context and List should be clear.
public
BookListAdapter(Context ctx, int resourceId, List<Book> objects) {
super( ctx,
resourceId, objects );
resource =
resourceId;
inflater =
LayoutInflater.from( ctx );
context = ctx;
}
@Override
public View getView ( int
position, View convertView, ViewGroup parent ) {
/* create a new
layout view and inflate it in the row */
convertView = (
LinearLayout ) inflater.inflate( resource, null );
/* Extract a book
object to show. getItem() comes from ArrayAdapter class */
Book book =
getItem(position);
/* set book title
in title TextView. getMovie is from our Book class */
TextView txtTitle =
(TextView) convertView.findViewById(R.id.bookTitle);
txtTitle.setText(book.getTitle() + " /
");
/* set book author
in author TextView */
TextView txtAuthor =
(TextView) convertView.findViewById(R.id.bookAuthor);
txtAuthor.setText(book.getAuthor());
return convertView;
}
}
|
Now we'll make our class MySQLiteHelper, which extends SQLiteOpenHelper. You'll notice that DATABASE_VERSION = 6. I left it that way as a way of admitting that it took me six times to get this simple application right. Don't laugh...
MySQLiteHelper.java
public class MySQLiteHelper extends SQLiteOpenHelper {
public static
final String TABLE_BOOKS = "books";
public static
final String COLUMN_ID = "_id";
public static
final String COLUMN_TITLE = "title";
public static
final String COLUMN_AUTHOR = "author";
private static
final String DATABASE_NAME = "books.db";
private static
final int DATABASE_VERSION = 6;
// Database
creation sql statement
private
static final String DATABASE_CREATE = "create table "
+ TABLE_BOOKS + " (" +
COLUMN_ID
+ " integer primary key
autoincrement, " + COLUMN_TITLE
+ " text not null, " +
COLUMN_AUTHOR + " text not null);";
public
MySQLiteHelper(Context context) {
super(context, DATABASE_NAME, null,
DATABASE_VERSION);
}
@Override
public void
onCreate(SQLiteDatabase database) {
database.execSQL(DATABASE_CREATE);
}
@Override
public void
onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(MySQLiteHelper.class.getName(),
"Upgrading database from version
" + oldVersion + " to "
+ newVersion + ", which will
destroy all old data");
db.execSQL("DROP
TABLE IF EXISTS " + TABLE_BOOKS);
onCreate(db);
}
}
|
Our Data Access Object (DAO) is as follows (pay attention to the getAllBooksByAuthor method; it holds the key to retrieving specific objects)...
BooksDataSource.java
public class BooksDataSource {
// Database
fields
private SQLiteDatabase database;
private MySQLiteHelper dbHelper;
private String[] allColumns = {
MySQLiteHelper.COLUMN_ID,
MySQLiteHelper.COLUMN_TITLE,
MySQLiteHelper.COLUMN_AUTHOR };
public BooksDataSource(Context context) {
dbHelper = new MySQLiteHelper(context);
}
public void open() throws SQLException {
database = dbHelper.getWritableDatabase();
}
public void close() {
dbHelper.close();
}
public Book createBook(Book book) {
ContentValues values = new
ContentValues();
values.put(MySQLiteHelper.COLUMN_TITLE,
book.getTitle());
values.put(MySQLiteHelper.COLUMN_AUTHOR,
book.getAuthor());
long insertId =
database.insert(MySQLiteHelper.TABLE_BOOKS, null,
values);
Cursor cursor =
database.query(MySQLiteHelper.TABLE_BOOKS,
allColumns, MySQLiteHelper.COLUMN_ID
+ " = " + insertId, null,
null, null, null);
cursor.moveToFirst();
Book newBook = cursorToBook(cursor);
cursor.close();
return newBook;
}
public void deleteBook(Book book) {
long id = book.getId();
System.out.println("Book deleted
with id: " + id);
database.delete(MySQLiteHelper.TABLE_BOOKS, MySQLiteHelper.COLUMN_ID
+ " = " + id, null);
}
// THIS is the method that queries the
database for books by a specific author.
public List<Book>
getAllBooksByAuthor(String bookAuthor) {
List<Book> books = new
ArrayList<Book>();
// This query gets the books by a specific author
Cursor cursor = database.query(true,
MySQLiteHelper.TABLE_BOOKS, allColumns, MySQLiteHelper.COLUMN_AUTHOR +
"=?" , new String[]{bookAuthor},
null, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Book book = cursorToBook(cursor);
books.add(book);
cursor.moveToNext();
}
// make sure to close the cursor
cursor.close();
return books;
}
private Book cursorToBook(Cursor cursor) {
Book book = new Book(cursor.getString(1),
cursor.getString(2));
book.setId(cursor.getLong(0));
book.setTitle(cursor.getString(1));
book.setAuthor(cursor.getString(2));
return book;
}
}
|
I'll leave it as an exercise for you to add a method that returns all the books in the database.
And now for the MainActivity...
MainActivity.java
public class MainActivity extends Activity {
private BooksDataSource
datasource;
@Override
protected void
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List
myList = new ArrayList();
ListView bookList = (ListView)
findViewById(R.id.theList);
bookList.setAdapter(new
BookListAdapter(this, R.layout.row_view, myList));
}
public void
onClick(View view) {
@SuppressWarnings("unchecked")
EditText title = (EditText)
findViewById(R.id.enterTitle);
EditText author = (EditText)
findViewById(R.id.enterAuthor);
EditText booksView = (EditText)
findViewById(R.id.retrieveBooks);
Button saveBook = (Button)
findViewById(R.id.setBook);
Button showBooks = (Button)
findViewById(R.id.getBooks);
ListView bookList = (ListView)
findViewById(R.id.theList);
BookListAdapter bookadapter =
(BookListAdapter) bookList.getAdapter();
datasource = new BooksDataSource(this);
datasource.open();
Book newBook = null;
switch (view.getId()) {
case R.id.setBook:
List
myList = new ArrayList();
String bookTitle =
title.getText().toString();
String bookAuthor =
author.getText().toString();
Book book = new Book(bookTitle,
bookAuthor);
myList.add(book);
// save the new book to the database
newBook = datasource.createBook(book);
bookadapter.add(newBook);
title.setText("");
author.setText("");
break;
case R.id.getBooks:
booksView.getText().toString();
List<Book>
books = datasource.getAllBooksByAuthor(booksView.getText().toString());
bookList.setAdapter(new
BookListAdapter(this, R.layout.row_view, books));
booksView.setText("");
break;
case R.id.exit:
finish();
break;
}
bookadapter.notifyDataSetChanged();
}
@Override
protected void onPause() {
datasource.close();
super.onPause();
}
@Override
public boolean
onCreateOptionsMenu(Menu menu) {
//
Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main,
menu);
return
true;
}
}
|
Now, we're ready to run the application. Upon start-up, we have...
Enter some books (Enter title and author, then click "Save Book") to get...
Exit the application and restart it. Once it starts up, enter a books-by-author search query...
So, now we have a list of all books in our library by the author in question (Two of which we entered, and two of which were entered previously).
So, what we set out to do has been done; we've saved books by several authors and retrieved all books by a specific author. The key to this exercise is how we coded our database query to get the specific books. I encourage you to investigate SQL queries if this new to you and, as always, please let me know if you have any questions or concerns about this tutorial. Cheers, and thanks for following!
Note:
This tutorial is based on a tutorial at Vogella.com.
Note:
This tutorial is based on a tutorial at Vogella.com.
how can i edit book title or author on clicking item from listview?
ReplyDelete