参考:https://www.bilibili.com/video/BV1fs411h7nF 视频做的笔记
文章目录
1、用listview和BaseAdapter实现listView的入门
- 在布局中定义listview控件
- 定义自己的适配器继承BaseAdapter
- 实现getCount和getView方法
1.1、布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
android:layout_width="match_parent" android:layout_height="match_parent"
tools:context="com.dsl.listView.MainActivity">
<ListView
android:id="@+id/lv"
android:layout_width="wrap_content"
android:fastScrollEnabled="true"
android:layout_height="wrap_content">
</ListView>
</RelativeLayout>
1.2、MainActivity类
package com.dsl.listView;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//找到相应的控件
ListView lv = (ListView) findViewById(R.id.lv);
//显示数据
lv.setAdapter(new MyListAdapter());
}
//定义listview适配器
private class MyListAdapter extends BaseAdapter{
//展示一共有多少条数据需要显示
@Override
public int getCount() {
return 100000000;
}
//返回指定position位置对应的对象
@Override
public Object getItem(int position) {
return null;
}
//返回position位置对应的id
@Override
public long getItemId(int position) {
return 0;
}
/**
* 获取一个view,用来显示listview的数据,会作为listview的一个条目出现
* convertView:历史缓存对象
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//创建新的view对象
TextView textView= new TextView(MainActivity.this);
textView.setText("嘻嘻嘻"+position);
return textView;
}
}
}
2、listview的优化
2.1、listview优化的原因:
在使用ListView控件的过程中,由于加载条目过多,在滑动时可能造成卡顿。这是因为ListView在当前屏幕有多少个条目,就会创建多少个对象,每一个条目都是一个对象。在滑动时,滑出屏幕的条目对象会被销毁,新加载到屏幕上的条目会创建新的对象,这样在ListView快速滑动时就会重复一个过程:【创建对象】–>【销毁对象】–>【创建对象】,并且每一个条目都需要加载一次布局,加载布局时会不断进行findViewById()操作初始化控件,而布局XML文件是以树形进行加载,每次加载一个条目都需要从根节点进行初始化,这样对内存消耗也比较大,并且浪费时间。为此就需要对ListView进行优化,优化的目的是在滑动时不会重复创建对象,减少内存消耗和屏幕渲染处理。
2.2、优化处理:
//将上面的getView方法可以替换为下面的代码进行优化
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView;
if (convertView==null){
//创建新的view对象
textView = new TextView(MainActivity.this);
}else{
//复用历史缓存对象
textView = (TextView) convertView;
}
textView.setText("嘻嘻嘻嘻"+position);
return textView;
}
3、listview显示复杂页面(在listview的一个item中显示图片和文字)
- 在activity_main.xml布局文件中定义listview
- 定义要显示数据的模板布局文件
- 定义自己的适配器显示数据
3.1、activity_main.xml文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
android:layout_width="match_parent" android:layout_height="match_parent"
tools:context="com.dsl.listview3.MainActivity">
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
3.2、模板item.xml文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/iv"
android:singleLine="true"
android:ellipsize="end"
android:textSize="20sp"
android:layout_marginTop="3dp"
android:textColor="#000000"
/>
<TextView
android:id="@+id/tv_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/iv"
android:layout_below="@+id/tv_title"
android:singleLine="true"
android:ellipsize="end"
android:textSize="15sp"
android:textColor="#999999" />
</RelativeLayout>
3.3、MainActivity 类
package com.dsl.listview3;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv = (ListView) findViewById(R.id.lv);
lv.setAdapter(new MyAdapter());
}
private class MyAdapter extends BaseAdapter{
@Override
public int getCount() {
return 7;
}
@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对象,可以通过打气筒把一个布局资源转换成一个view对象
* 第一个参数:上下文
* 第二个参数:定义的布局文件
*/
view = View.inflate(getApplication(), R.layout.item, null);
}else{
view = convertView;
}
return view;
}
}
}
4、获取打气筒的常用的api
4.1、第一种
/**
* 第一种:获取打气筒的事务
* 创建新的view对象,可以通过打气筒把一个布局资源转换成一个view对象
* 第一个参数:上下文
* 第二个参数:定义的布局文件
*
*/
View view = View.inflate(getApplication(), R.layout.item, null);
4.2、第二种
View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.item, null);
4.3、第三种
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.item, null);
5、ArrayAdapter的使用
- 在activity_main.xml文件定义listview控件
- 定义模板item.xml文件
- 通过适配器显示listview
5.1、activity_main.xml文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
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"
tools:context="com.dsl.ArrayAdapter.MainActivity">
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</RelativeLayout>
5.2、item.xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"/>
</LinearLayout>
5.3、MainActivity 文件
package com.dsl.ArrayAdapter;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends Activity {
String objects[] = {"一","二","三","四","五","六"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv = (ListView) findViewById(R.id.lv);
//创建一个arrayadapter
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, R.layout.item, R.id.tv, objects);
//设置数据适配器
lv.setAdapter(adapter);
}
}
6、SimpleAdapter的使用
6.1、activity_main.xml文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
android:layout_width="match_parent" android:layout_height="match_parent"
tools:context="com.dsl.simpleadapter.MainActivity">
<LinearLayout
android:id="@+id/ll"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:text="姓名"
android:textSize="20sp"
android:layout_height="wrap_content" />
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:textSize="20sp"
android:text="电话"
android:layout_height="wrap_content" />
</LinearLayout>
<ListView
android:layout_marginTop="30dp"
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</RelativeLayout>
6.2、MainActivity类
package com.dsl.simpleadapter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv = (ListView) findViewById(R.id.lv);
//准备listview要显示的数据
List<Map<String,String>> data = new ArrayList<>();
Map<String,String> map1 = new HashMap<>();
map1.put("name","鲁智深");
map1.put("phone","132546");
Map<String,String> map2 = new HashMap<>();
map2.put("name","林冲");
map2.put("phone","1478");
Map<String,String> map3 = new HashMap<>();
map3.put("name","张飞");
map3.put("phone","110");
Map<String,String> map4 = new HashMap<>();
map4.put("name","赵云");
map4.put("phone","112");
Map<String,String> map5 = new HashMap<>();
map5.put("name","关羽");
map5.put("phone","119");
//把map加入到集合中
data.add(map1);
data.add(map2);
data.add(map3);
data.add(map4);
data.add(map5);
/**
* 第一个参数:上下文
* 第二个:要添加的数据
* 第三个:布局文件
* 第四个:map集合的键
*第五个:布局文件中控件的id
*/
SimpleAdapter simpleAdapter = new SimpleAdapter(getApplicationContext(), data, R.layout.item, new String[]{"name", "phone",}, new int[]{R.id.tv_name, R.id.tv_phone});
//设置数据适配器
lv.setAdapter(simpleAdapter);
}
}
7、将数据库中查询出的数据显示到listview中
- 在布局中添加listview、查询、添加等控件
- 定义模板文件item.xml
- 自定义类继承SQLiteOpenHelper实现创建数据库
- 自定义类继承BaseAdapter实现适配器的操作
- 写sql语句实现增加和查询
7.1、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:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.dsl.SqlAndList.MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="增加"
android:onClick="add"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查询"
android:onClick="query"/>
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
7.2、item.xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_name"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv_phone"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content" />
</LinearLayout>
7.3、MyOpenHelper类(数据库文件)
package com.dsl.SqlAndList;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class MyOpenHelper extends SQLiteOpenHelper {
/**
*
* @param context
* name :数据库的名字
* context:上下文
* factory:目的创建cursor对象
* version:数据库的版本,从1开始
*/
public MyOpenHelper(Context context) {
super(context, "test.db", null, 5);
}
/**
* 当数据库第一次创建时,被调用
* 适合做表结构的初始化
* @param db
*/
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table info(_id integer primary key autoincrement,name varchar(20),phone varchar(20))");
}
/**
* 在数据库版本升级的时候调用
* 适合做表结构的更新
* @param db
* @param oldVersion
* @param newVersion
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
System.out.println("==========");
db.execSQL("alter table info add python varchar(20)");
}
}
7.4、MainActivity类
package com.dsl.SqlAndList;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
private MyOpenHelper myOpenHelper;
List<Person> lists;
ListView lv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lists= new ArrayList<>();
lv = (ListView) findViewById(R.id.lv);
myOpenHelper = new MyOpenHelper(getApplicationContext());
}
public void add(View v){
//获得数据库对象
SQLiteDatabase db = myOpenHelper.getWritableDatabase();
//执行增加语句
// db.execSQL("insert into info(name,phone) values(?,?)",new Object[]{"李四","123456"});
/**
* table:代表表名
* ContentValues,内部封装了一个map,key:对应列的名字,value:对应的值
*/
ContentValues values = new ContentValues();
values.put("name","李四");
values.put("phone","120");
//返回值代表插入新行的id
long info = db.insert("info", null, values);
//数据库用完要关闭
db.close();
if(info>0){
Toast.makeText(getApplicationContext(),"添加成功",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(),"添加失败",Toast.LENGTH_SHORT).show();
}
}
public void query(View v){
SQLiteDatabase db = myOpenHelper.getWritableDatabase();
/**
* 第二个参数:代表查询的列
* 第三个参数:条件
* 第四个参数:参数值
* 第五个参数:是否分组
* 第六个参数:筛选条件
* 第七个参数:是否排序
*/
Cursor cursor = db.query("info",new String[]{"name", "phone"},null,null, null, null, null);
if (cursor!=null&&cursor.getCount()>0){
while(cursor.moveToNext()){
String name = cursor.getString(0);
String phone = cursor.getString(1);
//把数据封装到javabean中‘
Person p = new Person();
p.setName(name);
p.setPhone(phone);
lists.add(p);
}
//设置数据适配器
lv.setAdapter(new MyAdapter());
}
}
private class MyAdapter extends BaseAdapter{
@Override
public int getCount() {
return lists.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 = View.inflate(getApplicationContext(), R.layout.item, null);
}else{
view = convertView;
}
//找到控件用来显示数据
TextView name = (TextView)view.findViewById(R.id.tv_name);
TextView phone = (TextView) view.findViewById(R.id.tv_phone);
//如何显示数据
Person person = lists.get(position);
name.setText(person.getName());
phone.setText(person.getPhone());
return view;
}
}
}
8、BaseAdapter、SimpleAdapter、ArrayAdapter三者的区别
BaseAdapter:自定义的东西很多,可以做很多复杂的界面显示,更加灵活
SimpleAdapter:SimpleAdapter的扩展性最好,可以显示比较复杂的列表,包括每行显示图片、文字等,但不能对列表进行后期加工(在java代码中加工),也是只是单纯的负责显示.
ArrayAdapter:只可以简单的显示一行文本