Продолжение статьи Основы использования SQLite в Android. Часть 1: cоздание и использование базы данных.

После всего вышеописанного можно сказать что создание инфраструктуры для работы с базой данных делится на два этапа:

  1. Описание наследника SQLiteOpenHelper
  2. Описания методов для выполнения запросов к базе и работы с курсором. Это может быть адаптер, но не обязательно.

Шаг 3: привязка к виду, создание интерфейса

Напомню, как выглядит наше приложение:

Опишем два файла с разметкой, для главной активности и элемента списка:


<?xml version="1.0" encoding="utf-8"?>
<linearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:background="@android:color/white">
<imageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello"
android:src="@drawable/baby"
android:background="#9999CC"
android:padding="5dp"/>
<textView
android:id="@+id/name_view"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Как назвать малыша?"
android:textSize="24dp"/>
<listView
android:id="@android:id/list"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_weight="1"
android:divider="@android:color/white"
android:dividerHeight="2dp"
android:smoothScrollbar="true">
</listView>
<textView
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:id="@android:id/empty"
android:text="вы еще не ввели имен"
android:gravity="center"
android:layout_weight="1"/>
<tableLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:stretchColumns="0">
<tableRow >
<editText
android:id="@+id/name_edit"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_weight="1"
android:hint="введите желаемое имя"
android:singleLine="true"
android:inputType="textCapWords"/>
<button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_weight="1"
android:text="Добавить"
android:onClick="addName"/>
</tableRow>
<tableRow>
<button
android:id="@+id/random_button"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="Случайное имя из списка"
android:onClick="getRandomName"/>
<button
android:id="@+id/remove_button"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="Удалить"
android:onClick="removeEntry"/>
</tableRow>
</tableLayout>
</linearLayout>

И элемент списка в файле list_item.xml:


<?xml version="1.0" encoding="utf-8"?>
<textView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#9999CC"
android:textColor="@android:color/black"
android:gravity="center"
android:textSize="24dp"
android:padding="5dp">
</textView>

Помимо этого мы внесем изменения в манифест, для того чтобы:

  1. Приложение все время сохраняло портретную ориентацию
  2. Всплывающая клавиатура не заслоняла элементы интерфейса, а «сдвигала» активность вверх

Для это приведите элемент манифиста к виду:


<activity android:name=".IdevBabysNameSQLActivity"
android:label="@string/app_name"
android:configChanges="orientation"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan">

Далее приведу код активности, после чего мы традиционно разберем его интересные части:


package by.idev.android.babyssql;
import java.util.Random;
import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class IdevBabysNameSQLActivity extends ListActivity {
SqlAdapter adapter;
EditText nameEdit;
ListView listView;
TextView currentName;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setUpView();
}
private void setUpView() {
listView = getListView();
currentName = (TextView) findViewById(R.id.name_view);
nameEdit = (EditText) findViewById(R.id.name_edit);
adapter = new SqlAdapter(this);
setListAdapter(adapter);
}
public void addName(View view) {
String name = nameEdit.getText().toString().trim();
if (!"".equals(name)) {
Name newName = new Name(name);
adapter.addItem(newName);
}
finishInput();
}
// метод очищает поле ввода и прячет экранную клавиатуру
private void finishInput() {
nameEdit.getText().clear();
InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(nameEdit.getWindowToken(), 0);
}
public void removeEntry(View view) {
String name = currentName.getText().toString();
Name nameToRemove = new Name(name);
adapter.removeItem(nameToRemove);
currentName.setText("Как назвать малыша?");
}
public void getRandomName(View view) {
int count = adapter.getCount();
if (count < 2) {
Toast.makeText(this, "Сначал введите хотя два имени", Toast.LENGTH_SHORT).show();
return;
}
int position = (new Random()).nextInt(count);
currentName.setText(adapter.getItem(position).getName());
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Name selectedName = adapter.getItem(position);
currentName.setText(selectedName.getName());
}
@Override
public void onDestroy() {
super.onDestroy();
adapter.onDestroy();
}
}

Как видите, нигде нет непосредственного обращения к базе данных, все делается через адаптер. This is хорошо.  Пробежимся по методам:


// метод очищает поле ввода и прячет экранную клавиатуру
private void finishInput() {
nameEdit.getText().clear();
InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(nameEdit.getWindowToken(), 0);
}

С его помощью мы завершаем ввод имени: очищаем поле ввода и прячем экранную клавиатуру.


@Override
public void onDestroy() {
super.onDestroy();
adapter.onDestroy();
}

Если вспомнить метод onDestroy() нашего адаптера:


public void onDestroy() {
dbOpenHelper.close();
}

То мы ясно видим, что он всего лишь закрывает базу данных. Стоп! Не «всего лишь» — закрывать базу данных обязательно, так как потери памяти плохи на любой платформе, а на мобильной просто недопустимы.

И на этом наш проект готов!

Резюме:

 Прочит статьи цикла мы научились:

  1. Выполнять базовые операции с базой данных
  2. Правильно строить архитектуру приложения с базой данных
  3. Определять адаптер для ListView работающий в базой данных
  4. Некоторым приемам с экранной клавиатурой
  5. Принудительно задавать ориентацию экрана

Если вас интересует как сделать свою базу на пк и потом добавить ее в дистрибутив, то вам сюда

Исходники лежат где-то тут.

Happy Coding! ;-)

Похожие статьи

  • Вышла новая версия Android NDK r8e.

  • Вызов Java-методов из C/C++ кода при помощи JNI на Android.

  • Учимся возбуждать…. Java-исключений из нативного кода на C/C++ через JNI в Android.

  • SQL-скрипты, SimpleCursorAdapter и ViewBinder — полезные приемы работы с Sqlite в Android.

  • Java Gym: абстрактный класс и интерфейс. Или о чем могут спросить на собеседовании.