创建一个PersonOpenHelperTest 类,用于测试上面的代码:
public class PersonOpenHelperTest extends AndroidTestCase { public SQLiteDatabase getDataBase() { PersonOpenHelper helper = new PersonOpenHelper(getContext(), "person.db", null, 1); SQLiteDatabase writableDatabase = helper.getWritableDatabase(); return writableDatabase; } }执行完上面代码,通过DDMS查看 /data/data/包名/databases目录产生了两个文件 person.db:数据库文件 person.db-journal:临时的日志文件,用于事务回滚
数据库并不是初始化MyHelper 时创建 调用getWritableDatabase() 或者getReadableDatabase()时: - 如果数据库不存在,创建数据库文件,执行onCreate()方法,并获取数据库对象 - 如果数据库存在,版本号没有发生改变,直接获取数据库对象 - 如果数据库存在,版本号提升,先执行onUpgrade()方法,再获取数据库对象
TIPS: 在批量修改数据的时候, 由于事务是在进行事务提交时将要执行的SQL 操作一次性打开数据库连接执行, 其执行速度比逐条执行SQL 语句的速度快了很多倍。 因此当我们开发中遇到对数据库的批量操作那么,使用事务是提高效率的重要原则。
在DDMS 视图中打开/data/data/包名/中,导出数据库文件 然后打开SQLite Expert 软件,将person 数据拖拽到如下图的左侧区域即可
ListView 是我们Android 中最重要的控件之一,是用于对数据进行列表展示的件。
屏幕上可以展示几个控件, ListView 就初始化几个,节省内存,防止内存溢出。通过使用convertView 对创建的视图对象进行复用ListView 始终保持创建的对象个数为: 屏幕显示的条目的个数+ 1。ListView 自带ScrollView 的功能,可以实现界面滚动。ListView 控件的设计遵循MVC 设计模式: mode 数据模型(数据) :要被显示到ListView 上的数据集合 view 视图(展示数据) : ListView controller 控制层(把数据展示到空间上) : 适配器Adapter使用listview显示数据列表的步骤: 1、在布局文件中添加一个listview控件 2、在代码中找到这个listview控件 3、创建一个数据适配器为listview填充数据
ps:布局文件的名字必须全部都是小写字母! 1. 创建ListView 展示样式布局文件,文件名为listview_item.xml
<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:orientation="horizontal" > <ImageView android:layout_width="60dp" android:layout_height="60dp" android:src="@drawable/ic_launcher" /> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:orientation="vertical" > <TextView android:id="@+id/tv_username" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="用户名" /> <TextView android:id="@+id/tv_age" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="年龄" /> <TextView android:id="@+id/tv_phone" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout>使用并修改该工程默认的Activity 类,MainActivity。该类的主要业务功能有: (1)调用Dao 获取数据库的全部数据 (2)获取ListView 控件的实例 (3)自定义适配器,继承BaseAdapter,重写getCount 以及getView 方法 int getCount():用于获取要展示的数据的总条数,即ListView 的总长度view getView(int position,View convertView,ViewGroup parent) 参数: 第一个:position:当前要显示的项在ListView 的索引 第二个:convertView:就是被拖出去的View 对象,getView 的返回值,可以利用这个对象使得拖出去即将销毁的条目重用,即缓存对象。ListView 中创建对象的个数=屏幕显示的条目数+1,当滑动屏幕时,被隐藏的项会作为缓存对象,作为getView的参数传递进来。只需修改此缓存对象的内容,直接使用即可,而不需要再重新new一个新的对象出来,节省了内存,防止内存溢出 View view =convertView==null?View.inflate(MainActivity.this,R.layout.item,null):convertView;
public class MainActivity extends Activity { private ListView lv; private List<Person> persons; private PersonDao dao; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv = (ListView) findViewById(R.id.lv); dao = new PersonDao(this); persons = dao.queryAll(); lv.setAdapter(new MyAdapter()); } private class MyAdapter extends BaseAdapter { @Override public int getCount() { return persons.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view; if (convertView != null) { view = convertView; } else { view = View.inflate(MainActivity.this, R.layout.listview_item, null); } TextView tv_username = (TextView) view .findViewById(R.id.tv_username); TextView tv_age = (TextView) view.findViewById(R.id.tv_age); TextView tv_phone = (TextView) view.findViewById(R.id.tv_phone); Person person = persons.get(position); tv_age.setText("年龄:" + person.getAge() + ""); tv_phone.setText("电话:" + person.getPhone()); tv_username.setText("姓名:" + person.getName()); return view; } } }1.复用旧的convertView 2.利用ViewHolder 减少findviewByid 的时间 3.如果只涉及到一个Item 的某一个控件的更改, 不应该去刷新整个ListView(notifyDataSetChanged())而是给这个控件使用setTag(Position)的方式设置不同的tag,然后使用ListView.findViewByTag,找到这个对应的控件进行更改(什么时候需要使用notifyDataSetChanged,当有一个条目添加或者删除,这个时候就必须刷新)
