做一个"Hello World!"入门:
<RelativeLayout 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" tools:context=".MainActivity" > <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent" ></ListView> </RelativeLayout>
package org.dreamtech.listview; import android.os.Bundle; import android.app.Activity; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ListView; import android.widget.TextView; public class MainActivity extends Activity { @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 6; } @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) { TextView tv = new TextView(MainActivity.this); tv.setText("haha" + position); return tv; } } }
即可显示一个最基本的listview
不过存在一个问题:如果总条目过多的时候,快速滑动滚动条,那么会内存溢出,奔溃
优化写法(实际开发中采用):
@Override public View getView(int position, View convertView, ViewGroup parent) { TextView tv; if (convertView == null) { tv = new TextView(MainActivity.this); } else { tv = (TextView) convertView; } tv.setText("HELLO"+position); return tv; }
ListView显示数据原理:MVC
布局方面注意一个细节:避免将高写成wrap
比如:
<ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="wrap_content" ></ListView>
正确写法:
<ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent" ></ListView>
原因:"高"如果是包裹内容(wrap),无法计算出要显示多少条目,所以每次显示一个新的条目都需要尝试取校验,是否可以显示出来
接下来做复杂的页面:复杂页面通常需要"打气筒"
package org.dreamtech.listview; import android.os.Bundle; import android.app.Activity; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ListView; public class MainActivity extends Activity { @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.inflate(getApplicationContext(), R.layout.item, null); } else { view = convertView; } return view; } } }
新写一个布局(layout)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="@drawable/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:textColor="#000000" android:textSize="20sp" android:layout_marginTop="3dp" android:text="安卓开发示例(title)" /> <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:textColor="#999999" android:textSize="15sp" android:text="安卓开发示例(message)" /> </RelativeLayout>
好的看下效果:
获取打气筒的方式:上边是第一种(通常)
第二种:
LayoutInflater.from(getApplicationContext()).inflate(resource, root)
第三种:
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
inflater.inflate(resource, root);
还有方法,常用的只有这三种
数组适配器:
一个简单的布局:item.xml:
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" android:textAppearance="?android:attr/textAppearanceLarge" />
package org.dreamtech.arrayadapter; import android.os.Bundle; import android.app.Activity; import android.widget.ArrayAdapter; import android.widget.ListView; public class MainActivity extends Activity { String objects[] = { "a", "b", "c", "d", "e", "f" }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ListView lv = (ListView) findViewById(R.id.lv); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.item, objects); lv.setAdapter(adapter); } }
效果:
simpleadapter:
package org.dreamtech.simpleadapter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.os.Bundle; import android.app.Activity; import android.widget.ListView; import android.widget.SimpleAdapter; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ListView lv = (ListView) findViewById(R.id.lv); // [1.1]准备listview 要显示的数据 List<Map<String, String>> data = new ArrayList<Map<String, String>>(); Map<String, String> map1 = new HashMap<String, String>(); map1.put("name", "张飞"); map1.put("tel", "1388888"); Map<String, String> map2 = new HashMap<String, String>(); map2.put("name", "赵云"); map2.put("tel", "110"); Map<String, String> map3 = new HashMap<String, String>(); map3.put("name", "貂蝉"); map3.put("tel", "13882223"); Map<String, String> map4 = new HashMap<String, String>(); map4.put("name", "关羽"); map4.put("tel", "119"); // [1.1]把map加入到集合中 data.add(map1); data.add(map2); data.add(map3); data.add(map4); // [2]设置数据适配器 resource 我们定义的布局文件 // from map集合的键 SimpleAdapter adapter = new SimpleAdapter(getApplicationContext(), data, R.layout.item, new String[] { "name", "tel" }, new int[] { R.id.tv_name, R.id.tv_tel }); // [3]设置数据适配器 lv.setAdapter(adapter); } }
布局:
<?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="horizontal" > <TextView android:id="@+id/tv_name" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:textSize="20sp" /> <TextView android:id="@+id/tv_tel" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:textColor="#ff0000" android:textSize="20sp" /> </LinearLayout>
最后:把数据库里面的数据展示在ListView上:
这里创建了数据库:http://www.cnblogs.com/xuyiqing/p/8868681.html
代码:
package org.dreamtech.sqlite; import java.util.ArrayList; import java.util.List; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.BaseAdapter; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import android.app.Activity; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; public class MainActivity extends Activity { private MyOpenHelper myOpenHelper; private List<Person> lists; private ListView lv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv = (ListView) findViewById(R.id.lv); lists = new ArrayList<Person>(); myOpenHelper = new MyOpenHelper(getApplicationContext()); } // 增 public void click1(View v) { SQLiteDatabase db = myOpenHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("name", "zhangsan"); values.put("tel", "110"); // 返回新行的id long insert = db.insert("info", null, values); db.close(); if (insert > 0) { Toast.makeText(getApplicationContext(), "add 成功", Toast.LENGTH_LONG) .show(); } else { Toast.makeText(getApplicationContext(), "add 失败", Toast.LENGTH_LONG) .show(); } } // 删 public void click2(View v) { SQLiteDatabase db = myOpenHelper.getWritableDatabase(); // 返回值:影响的行数 int delete = db.delete("info", "name=?", new String[] { "zhangsan" }); db.close(); Toast.makeText(getApplicationContext(), "删除了" + delete + "行", Toast.LENGTH_LONG).show(); } // 改 public void click3(View v) { SQLiteDatabase db = myOpenHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("tel", "666"); // 返回值:更新了多少行 int update = db.update("info", values, "name=?", new String[] { "zhangsan" }); db.close(); Toast.makeText(getApplicationContext(), "更新了" + update + "行", Toast.LENGTH_LONG).show(); } // 查 public void click4(View v) { SQLiteDatabase db = myOpenHelper.getWritableDatabase(); Cursor cursor = db.query("info", null, null, null, null, null, null); if (cursor != null && cursor.getCount() > 0) { while (cursor.moveToNext()) { String name = cursor.getString(1); String phone = cursor.getString(2); // 封装到javabean Person person = new Person(); person.setName(name); person.setPhone(phone); lists.add(person); } lv.setAdapter(new MyAdapter()); } } private class MyAdapter extends BaseAdapter { @Override public int getCount() { return 10; } @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 tv_name = (TextView) view.findViewById(R.id.tv_name); TextView tv_phone = (TextView) view.findViewById(R.id.tv_name); Person person = lists.get(position); tv_name.setText(person.getName()); tv_phone.setText(person.getPhone()); return view; } } }
<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="vertical" tools:context=".MainActivity" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="click1" android:text="add" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="click2" android:text="delete" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="click3" android:text="update" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="click4" android:text="find" /> <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent" ></ListView> </LinearLayout>
package org.dreamtech.sqlite; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class MyOpenHelper extends SQLiteOpenHelper { public MyOpenHelper(Context context) { super(context, "dreamtech.db", null, 1); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table info(_id integer primary key autoincrement,name varchar(20),tel varchar(20))"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
<?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="horizontal" > <TextView android:id="@+id/tv_name" android:layout_width="0dp" android:layout_height="wrap_content" android:text="agagag" android:textSize="20sp" android:layout_weight="1" /> <TextView android:id="@+id/tv_phone" android:layout_width="0dp" android:layout_height="wrap_content" android:text="agagag" android:textSize="20sp" android:textColor="#ff0000" android:layout_weight="1" /> </LinearLayout>