Android中ListView动态加载数据
- 格式:doc
- 大小:32.00 KB
- 文档页数:4
加载按钮procedure Tfrmmain.lv1UpdateObjects(const Sender: TObject; const AItem: TListViewItem);varLImage: TListItemImage;LTEXT1: TListItemText;LTEXT2: TListItemText;LTEXT3: TListItemText;Lbutton: TListItemTextButton;begin//LImage := AItem.Objects.FindObject('image1') as TListItemImage; if LImage = nil thenbeginLImage := TListItemImage.Create(AItem); := 'image1';LImage.Align := TListItemAlign.Trailing;LImage.PlaceOffset.Y := 5;LImage.PlaceOffset.X := -30;LImage.Width := 20;LImage.Height := 20;end;LTEXT1 := AItem.Objects.FindObject('text1') as TListItemText;if LTEXT1 = nil thenbeginLTEXT1 := TListItemT ext.Create(AItem); := 'text1';LTEXT1.Align := TListItemAlign.Leading;LTEXT1.VertAlign := TListItemAlign.T railing;LTEXT1.PlaceOffset.X := 75;LTEXT1.TextAlign := TTextAlign.taLeading;LTEXT1.Trimming := TTextTrimming.ttCharacter;LTEXT1.IsDetailText := True;LTEXT1.Width := 0;LTEXT1.Height := 62;end;LTEXT2 := AItem.Objects.FindObject('text2') as TListItemText;if LTEXT2 = nil thenbeginLTEXT2 := TListItemT ext.Create(AItem); := 'text2';LTEXT2.Align := TListItemAlign.Leading;LTEXT2.VertAlign := TListItemAlign.T railing;LTEXT2.PlaceOffset.X := 75;LTEXT2.TextAlign := TTextAlign.taLeading;LTEXT2.Trimming := TTextTrimming.ttCharacter;LTEXT2.IsDetailText := True;LTEXT2.Width := 0;LTEXT2.Height := 50;end;LTEXT3 := AItem.Objects.FindObject('text3') as TListItemText; if LTEXT3 = nil thenbeginLTEXT3 := TListItemT ext.Create(AItem); := 'text3';LTEXT3.Align := TListItemAlign.Leading;LTEXT3.VertAlign := TListItemAlign.T railing;LTEXT3.PlaceOffset.X := 75;LTEXT3.TextAlign := TTextAlign.taLeading;LTEXT3.Trimming := TTextTrimming.ttCharacter;LTEXT3.IsDetailText := True;LTEXT3.Width := 0;LTEXT3.Height := 38;end;end;调用procedure Tfrmmain.Button2Click(Sender: TObject);vardm : TServerMethods1Client;strSQL:string;LItem: TListViewItem;i: Integer;begintry//连接指定IP和Port的应用服务器DataModule1.SQLConnection1.Close;DataModule1.SQLConnection1.Params.Values['HostName'] := frmmain.IP;DataModule1.SQLConnection1.Params.Values['Port'] := frmmain.DK;tryDataModule1.SQLConnection1.Open;try//创建应用服务器上的Sample Methods在客户端的实现类dm := TServerMethods1Client.Create(DataModule1.SQLConnection1.DBXConnection);//执行服务器上的方法//ShowMessage(strSQL);DataModule1.ClientDataSet2.Close;DataModule1.ClientDataSet2.Open;finallydm.Free;end;excepton E: Exception doShowMessage(E.Message);end;finallyDataModule1.SQLConnection1.Close;end;lv1.Items.Clear;lv1.BeginUpdate;tryi := 1;DataModule1.ClientDataSet2.First;while not DataModule1.ClientDataSet2.Eof dobeginLItem := lv1.Items.Add;LItem.Text := '住院号:'+DataModule1.ClientDataSet2.FieldByName('no_anamn').AsString;LItem.Detail := Format('Detail %d', [I]);LItem.BitmapRef := Image1.Bitmap;(LItem.Objects.FindObject('text1') as TListItemText).Text := DataModule1.ClientDataSet2.FieldByName('name').AsString;(LItem.Objects.FindObject('text2') as TListItemText).T ext := '护理等级:' +'1';(LItem.Objects.FindObject('text3') as TListItemText).T ext := '新添加的';if DataModule1.ClientDataSet2.FieldByName('sex').AsString='1' thenbegin(LItem.Objects.FindObject('image1') as TListItemImage).OwnsBitmap := False;(LItem.Objects.FindObject('image1') as TListItemImage).Bitmap := Image1.MultiResBitmap.Items[0].Bitmap;endelsebegin(LItem.Objects.FindObject('image1') as TListItemImage).OwnsBitmap := False;(LItem.Objects.FindObject('image1') as TListItemImage).Bitmap := Image1.MultiResBitmap.Items[1].Bitmap;end;Inc(i);DataModule1.ClientDataSet2.Next;end;finallylv1.EndUpdate;end;end;。
动态绑定ASPxGridView或ASPxTreeList数据源的刷新问题ASPxGridView或ASPxTreeList在官方Demo中都是利用数据源控件绑定的数据源,这样基本上就可以确定了一个ASPxGridView只能固定的显示一些数据,然而在实际应用中经常有这样的需求,一些表结构类似的数据源想在一个页面展示,根据用户选择来呈现。
例如根据ComboBox的item来选择数据源时,如果把数据源绑定事件写在SelectIndexChanged事件里面,用户点击ComboBox选择不同item会先执行Page_Load事件,然后执行SelectIndexChanged事件,将会显示数据,然后用户点击ASPxGridView内的按钮比如排序、下一页等时,将会只执行Page_Load事件,而Page_Load事件里面没有绑定ASPxGridView,将会导致ASPxGridView没有数据显示。
这是一个比较矛盾的事情,如果绑定事件不在Page_Load里面将会导致点击按钮没有数据,如果放在page_load里面将会使用户选择失效。
当然,还有一个事件是比较可行的,ASPxGridView1_AfterPerformCallback,在页面回发的时候执行。
也就是说在点击ASPxGridView上的按钮后先执行Page_Load事件,然后执行ASPxGridView1_AfterPerformCallback事件,绑定在这个事件里执行,可以保证用户的操作有效。
这时还存在一个问题,就是DataTable的值怎么保存。
执行SelectIndexChanged事件时并不能(也许是我不知道)给AfterPerformCallback传参数,而且ASPxGridView回发的时候并不执行SelectIndexChanged事件,这样DataTable的值就无法更新到ASPxGridView的DataSous中。
考虑用ViewState来进行这个操作。
kotlin 的listviewKotlin 的ListView:简化Android 开发中的列表显示在Android 开发中,列表显示是非常常见和重要的功能之一。
ListView 是用于在Android 应用程序中显示可滚动列表的常用控件之一。
而Kotlin 是一种旨在简化Android 开发的现代编程语言。
本文将以Kotlin 的ListView 为主题,介绍如何使用Kotlin 在Android 应用程序中实现列表显示功能,并逐步回答各个相关问题。
一、什么是ListView?ListView 是Android 中用于显示可滚动列表的基本控件之一。
它可以在屏幕上垂直显示一系列项目,并可以根据需要滚动。
每个项目都由一个视图表示,且列表项目可以自定义以满足各种需求。
在Android 开发中,ListView 通常用于显示类似联系人、消息列表、音乐播放列表等的各种数据。
二、如何在Kotlin 中创建一个ListView?在Kotlin 中,我们可以使用Android Studio 的布局编辑器来创建ListView。
下面是一步一步的操作说明:1. 打开Android Studio,并创建一个新的Kotlin 项目。
2. 打开res/layout 目录,并找到activity_main.xml 布局文件。
3. 在activity_main.xml 文件中,将以下代码添加到布局文件中以创建一个ListView:xml<ListViewandroid:id="@+id/listView"android:layout_width="match_parent"android:layout_height="match_parent"/>4. 保存并关闭布局文件。
三、如何在Kotlin 中绑定ListView?在Kotlin 中,我们可以使用findViewById() 函数来绑定ListView。
listview使用方法listview是android开发中最常用的控件之一,它可以以列表形式展示数据,并且可以支持用户的滑动和点击操作。
在本篇文章中,我们将介绍listview的使用方法以及常用属性和方法。
1. 布局文件中添加listview在布局文件中添加以下代码,即可创建一个简单的listview。
```<ListViewandroid:id='@+id/list_view'android:layout_width='match_parent'android:layout_height='match_parent' />```2. 创建适配器适配器是listview展示数据的关键。
我们需要创建一个适配器,并在适配器中实现数据的绑定和显示。
```public class MyAdapter extends BaseAdapter {private List<String> mData;public MyAdapter(List<String> data) {mData = data;}@Overridepublic int getCount() {return mData.size();}@Overridepublic Object getItem(int position) {return mData.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder viewHolder;if (convertView == null) {convertView =LayoutInflater.from(parent.getContext()).inflate(yout.i tem_layout, parent, false);viewHolder = new ViewHolder();viewHolder.mTextView =convertView.findViewById(R.id.text_view);convertView.setTag(viewHolder);} else {viewHolder = (ViewHolder) convertView.getTag();}viewHolder.mTextView.setText(mData.get(position));return convertView;}private static class ViewHolder {private TextView mTextView;}}```在适配器中,我们通过实现BaseAdapter类的方法来为listview 绑定数据。
ListView加载网络数据和图片如,从服务器端获得商品名称、价格、简介和图片,加载到Android ListView中。
又如加载微博内容。
需了解熟悉:1、ListView行布局,排版,getView方法这个案例可以说是实现ListView图文混排的网络版。
关于在ListView中实现排版的方法,参考:2、异步任务的实现,Handler+Thread , AsyncTask3、JSON解析方式实现思路:1、异步加载服务器访问商品数据(json格式)封装网络访问的方法2、json数据转为Adapter数据(List<Map<String,Object>>)封装数据转换的方法3、Adapter先加载文本内容信息使用AsyncTask加载网络访问的集合数据加载ListView中的文本信息4、json数据中有图片信息(路径),异步读取加载图片采用接口回调的方法,加载图片信息(Handler+Thread)public class HttpUtil {public static final String BASE_URL = "http://10.0.2.2:8080/jsontest/servlet/ProductServlet"; public static final String IMG_URL = "http://10.0.2.2:8080/jsontest/upload/";public static HttpClient httpClient = new DefaultHttpClient();// post方法访问服务器,返回json字符串public static String getRequest(String url){String result = null;HttpGet httpGet = new HttpGet(url);try {HttpResponse httpResponse = httpClient.execute(httpGet);if (httpResponse.getStatusLine().getStatusCode() == 200) {result = EntityUtils.toString(httpResponse.getEntity(),"utf-8");}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return result;}// 字符串转成集合数据public static void resultString2List(List<Map<String ,Object>> list, String str,String title) { try {JSONObject jsonObject = new JSONObject(str);JSONArray jsonArray = jsonObject.getJSONArray(title);for (int i = 0; i < jsonArray.length(); i++) {JSONObject jsonObject2 = jsonArray.getJSONObject(i);Map<String ,Object> map = new HashMap<String, Object>();Iterator<String> iterator = jsonObject2.keys();while (iterator.hasNext()) {String key = iterator.next();Object value = jsonObject2.get(key);map.put(key, value);}list.add(map);}} catch (JSONException e) {// TODO Auto-generated catch blocke.printStackTrace();}}// post方法访问服务器,返回集合数据public static List<Map<String,Object>> getRequest2List(String url,String title){List<Map<String,Object>> list = new ArrayList<Map<String ,Object>>();resultString2List(list, url, title);return list;}// get方法访问服务器,返回json字符串public static String postRequest(String url, Map<String,String> rawParams) throws Exception{HttpPost post = new HttpPost(url);List<NameValuePair> params = new ArrayList<NameValuePair>();for (String key:rawParams.keySet()) {params.add(new BasicNameValuePair(key, rawParams.get(key)));}post.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));HttpResponse httpResponse = httpClient.execute(post);if(httpResponse.getStatusLine().getStatusCode() == 200){String result = EntityUtils.toString(httpResponse.getEntity());return result;}return null;}//post访问的方法,还可继续封装,略。
Android操作SQLite数据库(增、删、改、查、分页等)及ListView显⽰数据的⽅法详解本⽂实例讲述了Android操作SQLite数据库(增、删、改、查、分页等)及ListView显⽰数据的⽅法。
分享给⼤家供⼤家参考,具体如下:由于刚接触android开发,故此想把学到的基础知识记录⼀下,以备查询,故此写的⽐较啰嗦:步骤如下:⼀、介绍:此⽂主要是介绍怎么使⽤android⾃带的数据库SQLite,以及把后台的数据⽤ListView控件显⽰⼆、新建⼀个android⼯程——DBSQLiteOperate⼯程⽬录:三、清单列表AndroidManifest.xml的配置为:<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="/apk/res/android"package="com.example.dboperate"android:versionCode="1"android:versionName="1.0" ><uses-sdk android:minSdkVersion="8" /><applicationandroid:icon="@drawable/ic_launcher"android:label="@string/app_name" ><!--单元测试加这句--><uses-library android:name="android.test.runner" /><activityandroid:name=".DBSQLiteOperateActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="UNCHER" /></intent-filter></activity></application><instrumentation android:name="android.test.InstrumentationTestRunner"android:targetPackage="com.example.dboperate"android:label="Test for my app"/></manifest>四、main.xml配置清单:<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><LinearLayout android:layout_width="fill_parent"android:layout_height="wrap_content"android:orientation="horizontal" ><TextViewandroid:id="@+id/name"android:layout_width="100dip"android:layout_height="wrap_content"android:text="@string/name"android:gravity="center"/><TextViewandroid:id="@+id/phone"android:layout_width="100dip"android:layout_height="wrap_content"android:text="@string/phone"android:gravity="center"/><TextViewandroid:id="@+id/amount"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="@string/amount"android:gravity="center"/></LinearLayout><ListViewandroid:id="@+id/listView"android:layout_width="fill_parent"android:layout_height="fill_parent" ></ListView></LinearLayout>五、item.xml配置清单:<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="horizontal" ><TextViewandroid:id="@+id/name"android:layout_width="100dip"android:layout_height="wrap_content"android:text="@string/name"android:gravity="center"/><TextViewandroid:id="@+id/phone"android:layout_width="100dip"android:layout_height="wrap_content"android:text="@string/phone"android:gravity="center"/><TextViewandroid:id="@+id/amount"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="@string/amount"android:gravity="center"/></LinearLayout>六、string.xml配置清单:<?xml version="1.0" encoding="utf-8"?><resources><string name="hello">Hello World, DBSQLiteOperateActivity!</string><string name="app_name">ExampleDBSQLiteOperate8</string><string name="name">姓名</string><string name="phone">电话</string><string name="amount">存款</string></resources>七、DBSQLiteOperateActivity.java Activity类的源码:package com.example.dboperate;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import com.example.adapter.PersonAdapter;import com.example.domain.Person;import com.example.service.PersonService;import android.app.Activity;import android.database.Cursor;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.ListView;import android.widget.SimpleAdapter;import android.widget.SimpleCursorAdapter;import android.widget.Toast;public class DBSQLiteOperateActivity extends Activity {ListView listView;PersonService personService;OnItemClickListener listViewListener;/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.main);listViewListener = new OnItemClickListener(){@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {//得到listView控件ListView listView = (ListView)parent;//1、如果使⽤⾃定义适配器,返回的是Person对象//得到该条⽬数据// Person person = (Person)listView.getItemAtPosition(position);// //⼴播出去// Toast.makeText(getApplicationContext(), person.toString(), Toast.LENGTH_LONG).show(); //2、如果使⽤showList2()⽅法中的适配器时,则取得的值是不⼀样的,返回的是cursor// Cursor cursor = (Cursor)listView.getItemAtPosition(position);// int personid = cursor.getInt(cursor.getColumnIndex("_id"));// Toast.makeText(getApplicationContext(), personid+"", Toast.LENGTH_LONG).show();//3、如果使⽤showList()⽅法中的适配器时,则取得的值是不⼀样的,返回的是map@SuppressWarnings("unchecked")Map<String,Object> map = (Map)listView.getItemAtPosition(position);String name = map.get("name").toString();String personid = map.get("personid").toString();Toast.makeText(getApplicationContext(), personid +"-"+ name, Toast.LENGTH_LONG).show(); }};listView = (ListView) this.findViewById(R.id.listView);listView.setOnItemClickListener(listViewListener);personService = new PersonService(this);showList();}private void showList() {List<Person> persons = personService.getScrollData(0, 50);List<HashMap<String,Object>> data = new ArrayList<HashMap<String,Object>>();for(Person person : persons){HashMap<String,Object> item = new HashMap<String,Object>();item.put("name", person.getName());item.put("phone", person.getPhone());item.put("amount", person.getAmount());item.put("personid", person.getId());data.add(item);}SimpleAdapter adapter = new SimpleAdapter(this,data,yout.item, new String[]{"name","phone","amount"}, new int[]{,R.id.phone,R.id.amount});listView.setAdapter(adapter);}public void showList2(){Cursor cursor = personService.getCursorScrollData(0, 50);//该适配器要求返回的结果集cursor必须包含_id字段,所以需要对取得结果集进⾏处理SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,yout.item,cursor,new String[]{"name","phone","amount"}, new int[]{,R.id.phone,R.id.amount} ); listView.setAdapter(adapter);}/*** ⾃定义适配器*/public void showList3(){List<Person> persons = personService.getScrollData(0, 50);/*** 第⼀个参数:上下⽂context,第⼆个参数:要显⽰的数据,第三个参数:绑定的条⽬界⾯*/PersonAdapter adapter = new PersonAdapter(this, persons, yout.item);listView.setAdapter(adapter);}}⼋、person.java 实体类源码:package com.example.domain;public class Person {private Integer id;private String name;private String phone;private Integer amount;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) { = name;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}public Person(String name, String phone) { = name;this.phone = phone;}public Person(Integer id, String name, String phone,Integer amount) {super();this.id = id; = name;this.phone = phone;this.amount = amount;}public Person() {super();}public Integer getAmount() {return amount;}public void setAmount(Integer amount) {this.amount = amount;}@Overridepublic String toString() {return "Person [id=" + id + ", name=" + name + ", phone=" + phone+ ", amount=" + amount + "]";}}九、DBOperateHelper.java 业务类源码:package com.example.service;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;public class DBOperateHelper extends SQLiteOpenHelper {public DBOperateHelper(Context context) {//默认创建的数据库⽂件保存在<包名>/database///第⼀个参数是上下⽂,第⼆个参数是数据库名称,第三个是游标⼯⼚为null时使⽤数据库默认的游标⼯⼚,第四个是数据库版本号但是不能为0,⼀般⼤于0super(context, "smallpig", null, 4);}/*** 数据库每⼀次被创建时被调⽤*/@Overridepublic void onCreate(SQLiteDatabase sqldb) {sqldb.execSQL("create table person(personid integer primary key autoincrement,name varchar(20),phone varchar(12) null)");}/*** 每⼀次数据库版本号发⽣变动时触发此⽅法* ⽐如如果想往数据库中再插⼊⼀些表、字段或者其他信息时通过修改数据库版本号来触发此⽅法*/@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {//db.execSQL("alter table person add phone varchar(12) null");\db.execSQL("alter table person add amount Integer null");}}⼗、PersonService.java 业务类源码:package com.example.service;import java.util.ArrayList;import java.util.List;import android.content.Context;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import com.example.domain.Person;public class PersonService {private DBOperateHelper dbOperateHelper;public PersonService(Context context) {this.dbOperateHelper = new DBOperateHelper(context);}/*** 保存记录* @param person*/public void save(Person person){//得到数据库实例,⾥⾯封装了数据库操作⽅法SQLiteDatabase sqldb = dbOperateHelper.getWritableDatabase();//sqldb.execSQL("insert into person(name,phone) values('"+person.getName()+"','"+person.getPhone()+"')");//利⽤占位符可以避免注⼊,但是注意数组参与与占位符对应的字段要⼀⼀对应sqldb.execSQL("insert into person(name,phone,amount) values(?,?,?)",new Object[]{person.getName(),person.getPhone(),person.getAmount()});//关闭数据库sqldb.close();}/*** 删除记录* @param id*/public void delete(Integer id){SQLiteDatabase sqldb = dbOperateHelper.getWritableDatabase();sqldb.execSQL("delete from person where personid=?",new Object[]{id});sqldb.close();}/*** 更新记录* @param person*/public void update(Person person){SQLiteDatabase sqldb = dbOperateHelper.getWritableDatabase();sqldb.execSQL("update person set name=?,phone=?,amount=? where personid=?",new Object[]{person.getName(),person.getPhone(),person.getAmount(),person.getId()}); sqldb.close();}/*** 通过ID查询记录* @param id* @return*/public Person find(Integer id){/*** getWritableDatabase 与 getReadableDatabase 的区别:* getReadableDatabase会先返回getWritableDatabase(可写),如果调⽤getWritableDatabase失败* 则才会调⽤getReadableDatabase后续⽅法,使数据库只读* 当写⼊的数据超过数据库⼤⼩则调⽤getWritableDatabase会失败* 所以只读时则可以使⽤此⽅法,其它情况(只要不是超过数据库⼤⼩)也可以使⽤此⽅法*/SQLiteDatabase sqldb = dbOperateHelper.getReadableDatabase();Cursor cursor = sqldb.rawQuery("select * from person where personid=?", new String[]{String.valueOf(id)});int personid;String name;String phone;int amount;Person person = null;if(cursor.moveToFirst()){personid = cursor.getInt(cursor.getColumnIndex("personid"));name = cursor.getString(cursor.getColumnIndex("name"));phone = cursor.getString(cursor.getColumnIndex("phone"));amount = cursor.getInt(cursor.getColumnIndex("amount"));person = new Person(personid,name,phone,amount);}cursor.close();return person;}/*** 返回指定长度记录,limit 3,5,适⽤于分页* @param offset 起始* @param maxResult 长度* @return*/public List<Person> getScrollData(int offset,int maxResult){SQLiteDatabase sqldb = dbOperateHelper.getReadableDatabase();Cursor cursor = sqldb.rawQuery("select * from person order by personid asc limit ?,?", new String[]{String.valueOf(offset),String.valueOf(maxResult)});int personid;String name;String phone;int amount;Person person = null;List<Person> persons = new ArrayList<Person>();while(cursor.moveToNext()){personid = cursor.getInt(cursor.getColumnIndex("personid"));name = cursor.getString(cursor.getColumnIndex("name"));phone = cursor.getString(cursor.getColumnIndex("phone"));amount = cursor.getInt(cursor.getColumnIndex("amount"));person = new Person(personid,name,phone,amount);persons.add(person);}cursor.close();return persons;}/*** 返回cursor* @param offset 起始* @param maxResult 长度* @return*/public Cursor getCursorScrollData(int offset,int maxResult){SQLiteDatabase sqldb = dbOperateHelper.getReadableDatabase();Cursor cursor = sqldb.rawQuery("select personid as _id,name,phone,amount from person order by personid asc limit ?,?", new String[]{String.valueOf(offset),String.valueOf(maxResult)}); return cursor;}/*** 返回总记录数* @return*/public long getCount(){SQLiteDatabase sqldb = dbOperateHelper.getReadableDatabase();Cursor cursor = sqldb.rawQuery("select count(*) from person", null);//该查询语句值返回⼀条语句cursor.moveToFirst();long result = cursor.getLong(0);cursor.close();return result;}public void payment(){SQLiteDatabase sqldb = dbOperateHelper.getWritableDatabase();sqldb.beginTransaction();//开启事务try{sqldb.execSQL("update person set amount = amount -10 where personid=1");sqldb.execSQL("update person set amount = amount + 10 where personid=2");sqldb.setTransactionSuccessful();//设置事务标志位true} finally {//结束事务:有两种情况:commit\rollback,事务提交或者回滚是由事务的标识决定的//事务为ture则提交,事务为flase则回滚,默认为falsesqldb.endTransaction();}}}⼗⼀、OtherPersonService.java 业务类源码:package com.example.service;import java.util.ArrayList;import java.util.List;import com.example.domain.Person;import android.content.ContentValues;import android.content.Context;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;public class OtherPersonService {private DBOperateHelper dbOperateHelper;public OtherPersonService(Context context) {this.dbOperateHelper = new DBOperateHelper(context);}/*** 保存记录* @param person*/public void save(Person person){//得到数据库实例,⾥⾯封装了数据库操作⽅法SQLiteDatabase sqldb = dbOperateHelper.getWritableDatabase();//sqldb.execSQL("insert into person(name,phone) values('"+person.getName()+"','"+person.getPhone()+"')");//利⽤占位符可以避免注⼊,但是注意数组参与与占位符对应的字段要⼀⼀对应//sqldb.execSQL("insert into person(name,phone) values(?,?)",new Object[]{person.getName(),person.getPhone()});ContentValues values = new ContentValues();values.put("name", person.getName());values.put("phone", person.getPhone());values.put("amount", person.getAmount());//第⼀个参数是表名,第三个为字段值集合,第⼆个参数是空值字段,当第三个字段值集合为空时,系统会⾃动插⼊⼀条第⼆个参数为空的sql语句//否则当第三个参数为空时,如果第⼆个参数也为空,那么插⼊表就会找不到插⼊的字段信息,会报错sqldb.insert("person", "name", values );//关闭数据库sqldb.close();}/*** 删除记录* @param id*/public void delete(Integer id){SQLiteDatabase sqldb = dbOperateHelper.getWritableDatabase();//sqldb.execSQL("delete from person where personid=?",new Object[]{id});//第⼀个参数是表名,第⼆个是where后⾯的条件⽤占位符表⽰,第三个对应占位符为参数值sqldb.delete("person", "personid=?", new String[]{Integer.toString(id)});sqldb.close();}/*** 更新记录* @param person*/public void update(Person person){SQLiteDatabase sqldb = dbOperateHelper.getWritableDatabase();//sqldb.execSQL("update person set name=?,phone=? where personid=?",new Object[]{person.getName(),person.getPhone(),person.getId()});//第⼀个参数为表名,第⼆个是⼀个更新值集合,采⽤键值对的形式,每个更新的字段对应更新值//第三个参数是where后⾯条件字段⽤占位符标识,第四个参数是对应where占位符的值ContentValues values = new ContentValues();values.put("name", person.getName());values.put("phone", person.getPhone());values.put("amount", person.getAmount());sqldb.update("person", values , "personid=?", new String[]{person.getId().toString()});sqldb.close();}/*** 通过ID查询记录* @param id* @return*/public Person find(Integer id){/*** getWritableDatabase 与 getReadableDatabase 的区别:* getReadableDatabase会先返回getWritableDatabase(可写),如果调⽤getWritableDatabase失败* 则才会调⽤getReadableDatabase后续⽅法,使数据库只读* 当写⼊的数据超过数据库⼤⼩则调⽤getWritableDatabase会失败* 所以只读时则可以使⽤此⽅法,其它情况(只要不是超过数据库⼤⼩)也可以使⽤此⽅法*/SQLiteDatabase sqldb = dbOperateHelper.getReadableDatabase();//Cursor cursor = sqldb.rawQuery("select * from person where personid=?", new String[]{String.valueOf(id)});//第⼀个参数是表名;第⼆个参数是查询显⽰的字段,null时默认查询显⽰所有字段;//第三个参数是where查询条件占位符;第四个是占位符对应的值;//第五个参数是group by条件;第六个是having条件;第七个是order by条件Cursor cursor = sqldb.query("person", null, "personid=?", new String[]{id.toString()}, null, null, null);int personid;String name;String phone;int amount;Person person = null;if(cursor.moveToFirst()){personid = cursor.getInt(cursor.getColumnIndex("personid"));name = cursor.getString(cursor.getColumnIndex("name"));phone = cursor.getString(cursor.getColumnIndex("phone"));amount = cursor.getInt(cursor.getColumnIndex("amount"));person = new Person(personid,name,phone,amount);}cursor.close();return person;}/*** 返回指定长度记录,limit 3,5,适⽤于分页* @param offset 起始* @param maxResult 长度* @return*/public List<Person> getScrollData(int offset,int maxResult){SQLiteDatabase sqldb = dbOperateHelper.getReadableDatabase();//Cursor cursor = sqldb.rawQuery("select * from person order by personid asc limit ?,?", new String[]{String.valueOf(offset),String.valueOf(maxResult)}); //第⼀个参数是表名;第⼆个参数是查询显⽰的字段,null时默认查询显⽰所有字段;//第三个参数是where查询条件占位符;第四个是占位符对应的值;//第五个参数是group by条件;第六个是having条件;第七个是order by条件//第⼋个参数是limit ?,? 条件Cursor cursor = sqldb.query("person", null, null, null, null, null, "personid",offset+","+maxResult); int personid;String name;String phone;int amount;Person person = null;List<Person> persons = new ArrayList<Person>();while(cursor.moveToNext()){personid = cursor.getInt(cursor.getColumnIndex("personid"));name = cursor.getString(cursor.getColumnIndex("name"));phone = cursor.getString(cursor.getColumnIndex("phone"));amount = cursor.getInt(cursor.getColumnIndex("amount"));person = new Person(personid,name,phone,amount);persons.add(person);}cursor.close();return persons;}/*** 返回总记录数* @return*/public long getCount(){SQLiteDatabase sqldb = dbOperateHelper.getReadableDatabase();//Cursor cursor = sqldb.rawQuery("select count(*) from person", null);//第⼀个参数是表名;第⼆个参数是查询显⽰的字段,null时默认查询显⽰所有字段;//第三个参数是where查询条件占位符;第四个是占位符对应的值;//第五个参数是group by条件;第六个是having条件;第七个是order by条件Cursor cursor = sqldb.query("person", new String[]{"count(*)"}, null, null, null, null, null);//该查询语句值返回⼀条语句cursor.moveToFirst();long result = cursor.getLong(0);cursor.close();return result;}}⼗⼆、PersonServiceTest.java 单元测试类源码:package com.example.test;import java.util.List;import com.example.domain.Person;import com.example.service.DBOperateHelper;import com.example.service.PersonService;import android.test.AndroidTestCase;import android.util.Log;public class PersonServiceTest extends AndroidTestCase {public void testCreateDB() throws Exception{DBOperateHelper dbHelper = new DBOperateHelper(getContext());dbHelper.getWritableDatabase();}public void testSave() throws Exception{PersonService ps = new PersonService(getContext());for(int i=1;i<=100;i++){Person person = new Person();person.setName("我是"+i);person.setPhone(String.valueOf(Long.parseLong("188********")+i));ps.save(person);Log.i("PersonService",person.toString());}}public void testDelete() throws Exception{PersonService ps = new PersonService(getContext());ps.delete(10);}public void testUpdate() throws Exception{PersonService ps = new PersonService(getContext());ps.update(new Person(1,"xiaopang","188********",0));}public void testFind() throws Exception{PersonService ps = new PersonService(getContext());Person person = ps.find(1);Log.i("PersonService", person.toString());}public void testGetScrollData() throws Exception{PersonService ps = new PersonService(getContext());List<Person> persons = ps.getScrollData(3, 5);for(Person person:persons){Log.i("PersonService",person.toString());}}public void testGetCount() throws Exception{PersonService ps = new PersonService(getContext());Long count = ps.getCount();Log.i("PersonService",count.toString());}public void testUpdateAmount() throws Exception{PersonService ps = new PersonService(getContext());Person person1 = ps.find(1);Person person2 = ps.find(2);person1.setAmount(100);person2.setAmount(100);ps.update(person1);ps.update(person2);}public void testPayment() throws Exception{PersonService ps = new PersonService(getContext());ps.payment();}}⼗三、OtherPersonServiceTest 单元测试类源码:package com.example.test;import java.util.List;import com.example.domain.Person;import com.example.service.DBOperateHelper;import com.example.service.OtherPersonService;import android.test.AndroidTestCase;import android.util.Log;public class OtherPersonServiceTest extends AndroidTestCase {public void testCreateDB() throws Exception{DBOperateHelper dbHelper = new DBOperateHelper(getContext());dbHelper.getWritableDatabase();}public void testSave() throws Exception{OtherPersonService ps = new OtherPersonService(getContext());for(int i=1;i<=100;i++){Person person = new Person();person.setName("我是"+i);person.setPhone(String.valueOf(Long.parseLong("188********")+i));ps.save(person);Log.i("PersonService",person.toString());}}public void testDelete() throws Exception{OtherPersonService ps = new OtherPersonService(getContext());ps.delete(10);}public void testUpdate() throws Exception{OtherPersonService ps = new OtherPersonService(getContext());ps.update(new Person(1,"xiaopang","188********",0));}public void testFind() throws Exception{OtherPersonService ps = new OtherPersonService(getContext());Person person = ps.find(1);Log.i("PersonService", person.toString());}public void testGetScrollData() throws Exception{OtherPersonService ps = new OtherPersonService(getContext());List<Person> persons = ps.getScrollData(3, 5);for(Person person:persons){Log.i("PersonService",person.toString());}}public void testGetCount() throws Exception{OtherPersonService ps = new OtherPersonService(getContext());Long count = ps.getCount();Log.i("PersonService",count.toString());}}⼗四、注意事项以及相关知识点:1、掌握SQLite数据库如何创建数据库、建⽴表、维护字段等操作继承SQLiteOpenHelper类,构造函数调⽤⽗类构造函数创建数据库,利⽤onCreate创建表,利⽤onUpgrade更新表字段信息2、掌握SQLite数据库如何增、删、改、查以及分页取得SQLiteDatabase的实例,然后调⽤该实例的⽅法可以完成上述操作SQLiteDataBase提供两种操作上述功能的⽅式:⼀是直接调⽤execSQL书写sql语句,另⼀种是通过insert、update、delete、query等⽅法来传值来拼接sql,前⼀种适合熟练掌握sql 语句的3、对需要数据同步的处理请添加事务处理,熟悉事务的处理⽅式4、了解各个⽅法参数的意义以及传值5、掌握ListView显⽰后台数据的使⽤⽅法SimpleAdapter、SimpleCursorAdapter以及⾃定义适配器的使⽤,以及OnItemClickListener取值时各个适配器返回值的区别以及取值⽅法6、多学、多记、多练、多思,加油!更多关于Android相关内容感兴趣的读者可查看本站专题:《》、《》、《》、《》、《》及《》希望本⽂所述对⼤家Android程序设计有所帮助。
花了一天时间写出了这个类来实现下拉刷新。
首先这是一个自定义的listView控件类,我在许多项目中都用到了它,效果很稳定。
实现也很简单。
用的时候其他功能都和系统提供的ListView一样,就只是多了一个下拉刷新监听。
用这个类替代系统提供的ListView,下拉刷新再也不会烦恼了。
\(^o^)/~希望对大家有用。
我写的自定义ListView的代码:import java.util.Date;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import youtInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.animation.LinearInterpolator;import android.view.animation.RotateAnimation;import android.widget.AbsListView;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.AbsListView.OnScrollListener;import android.widget.ProgressBar;import android.widget.TextView;public class MyListView extends ListView implements OnScrollListener {private static final String TAG = "listview";private final static int RELEASE_To_REFRESH = 0;private final static int PULL_To_REFRESH = 1;private final static int REFRESHING = 2;private final static int DONE = 3;private final static int LOADING = 4;// 实际的padding的距离与界面上偏移距离的比例private final static int RATIO = 3;private LayoutInflater inflater;private LinearLayout headView;private TextView tipsTextview;private TextView lastUpdatedTextView;private ImageView arrowImageView;private ProgressBar progressBar;private RotateAnimation animation;private RotateAnimation reverseAnimation;// 用于保证startY的值在一个完整的touch事件中只被记录一次private boolean isRecored;private int headContentWidth;private int headContentHeight;private int startY;private int firstItemIndex;private int state;private boolean isBack;private OnRefreshListener refreshListener;private boolean isRefreshable;public MyListView(Context context) {super(context);init(context);}public MyListView(Context context, AttributeSet attrs) { super(context, attrs);init(context);}private void init(Context context) {setCacheColorHint(context.getResources().getColor(R.color.tran sparent));inflater = LayoutInflater.from(context);headView= (LinearLayout) inflater.inflate(yout.head, null);arrowImageView = (ImageView) headView.findViewById(R.id.head_arrowImageView);arrowImageView.setMinimumWidth(70);arrowImageView.setMinimumHeight(50);progressBar = (ProgressBar) headView.findViewById(R.id.head_progressBar);tipsTextview = (TextView)headView.findViewById(R.id.head_tipsTextView);lastUpdatedTextView = (TextView) headView.findViewById(R.id.head_lastUpdatedTextView);measureView(headView);headContentHeight = headView.getMeasuredHeight();headContentWidth = headView.getMeasuredWidth();headView.setPadding(0, -1 * headContentHeight, 0, 0);headView.invalidate();Log.v("size", "width:" + headContentWidth + " height:"+ headContentHeight);addHeaderView(headView, null, false);setOnScrollListener(this);animation = new RotateAnimation(0, -180,RotateAnimation.RELATIVE_TO_SELF, 0.5f,RotateAnimation.RELATIVE_TO_SELF, 0.5f);animation.setInterpolator(new LinearInterpolator());animation.setDuration(250);animation.setFillAfter(true);reverseAnimation = new RotateAnimation(-180, 0,RotateAnimation.RELATIVE_TO_SELF, 0.5f,RotateAnimation.RELATIVE_TO_SELF, 0.5f);reverseAnimation.setInterpolator(new LinearInterpolator());reverseAnimation.setDuration(200);reverseAnimation.setFillAfter(true);state = DONE;isRefreshable = false;}public void onScroll(AbsListView arg0, int firstVisiableItem, int arg2,int arg3) {firstItemIndex = firstVisiableItem;}public void onScrollStateChanged(AbsListView arg0, int arg1) { }public boolean onTouchEvent(MotionEvent event) {if (isRefreshable) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:if (firstItemIndex == 0 && !isRecored) {isRecored = true;startY = (int) event.getY();Log.v(TAG, "在down时候记录当前位置‘");}break;case MotionEvent.ACTION_UP:if (state != REFRESHING && state != LOADING) { if (state == DONE) {// 什么都不做}if (state == PULL_To_REFRESH) {state = DONE;changeHeaderViewByState();Log.v(TAG, "由下拉刷新状态,到done状态");}if (state == RELEASE_To_REFRESH) {state = REFRESHING;changeHeaderViewByState();onRefresh();Log.v(TAG, "由松开刷新状态,到done状态");}}isRecored = false;isBack = false;break;case MotionEvent.ACTION_MOVE:int tempY = (int) event.getY();if (!isRecored && firstItemIndex == 0) {Log.v(TAG, "在move时候记录下位置");isRecored = true;startY = tempY;}if(state!= REFRESHING&& isRecored&& state!= LOADING) {// 保证在设置padding的过程中,当前的位置一直是在head,否则如果当列表超出屏幕的话,当在上推的时候,列表会同时进行滚动// 可以松手去刷新了if (state == RELEASE_To_REFRESH) {setSelection(0);// 往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步if(((tempY - startY) / RATIO< headContentHeight)&& (tempY - startY) > 0) {state = PULL_To_REFRESH;changeHeaderViewByState();Log.v(TAG, "由松开刷新状态转变到下拉刷新状态");}// 一下子推到顶了else if (tempY - startY <= 0) {state = DONE;changeHeaderViewByState();Log.v(TAG, "由松开刷新状态转变到done状态");}// 往下拉了,或者还没有上推到屏幕顶部掩盖head的地步else {// 不用进行特别的操作,只用更新paddingTop的值就行了}}// 还没有到达显示松开刷新的时候,DONE或者是PULL_To_REFRESH状态if (state == PULL_To_REFRESH) {setSelection(0);// 下拉到可以进入RELEASE_TO_REFRESH的状态if((tempY - startY) / RATIO>= headContentHeight) {state = RELEASE_To_REFRESH;isBack = true;changeHeaderViewByState();Log.v(TAG, "由done或者下拉刷新状态转变到松开刷新");}// 上推到顶了else if (tempY - startY <= 0) {state = DONE;changeHeaderViewByState();Log.v(TAG, "由DOne或者下拉刷新状态转变到done状态");}}// done状态下if (state == DONE) {if (tempY - startY > 0) {state = PULL_To_REFRESH;changeHeaderViewByState();}}// 更新headView的sizeif (state == PULL_To_REFRESH) {headView.setPadding(0, -1 * headContentHeight+ (tempY - startY) / RATIO, 0, 0);}// 更新headView的paddingTopif (state == RELEASE_To_REFRESH) {headView.setPadding(0, (tempY - startY) / RATIO- headContentHeight, 0, 0);}}break;}}return super.onTouchEvent(event);}// 当状态改变时候,调用该方法,以更新界面private void changeHeaderViewByState() {switch (state) {case RELEASE_To_REFRESH:arrowImageView.setVisibility(View.VISIBLE);progressBar.setVisibility(View.GONE);tipsTextview.setVisibility(View.VISIBLE);lastUpdatedTextView.setVisibility(View.VISIBLE);arrowImageView.clearAnimation();arrowImageView.startAnimation(animation);tipsTextview.setText("松开刷新");Log.v(TAG, "当前状态,松开刷新");break;case PULL_To_REFRESH:progressBar.setVisibility(View.GONE);tipsTextview.setVisibility(View.VISIBLE);lastUpdatedTextView.setVisibility(View.VISIBLE);arrowImageView.clearAnimation();arrowImageView.setVisibility(View.VISIBLE);// 是由RELEASE_To_REFRESH状态转变来的if (isBack) {isBack = false;arrowImageView.clearAnimation();arrowImageView.startAnimation(reverseAnimation);tipsTextview.setText("下拉刷新");} else {tipsTextview.setText("下拉刷新");}Log.v(TAG, "当前状态,下拉刷新");break;case REFRESHING:headView.setPadding(0, 0, 0, 0);progressBar.setVisibility(View.VISIBLE);arrowImageView.clearAnimation();arrowImageView.setVisibility(View.GONE);tipsTextview.setText("正在刷新...");lastUpdatedTextView.setVisibility(View.VISIBLE);Log.v(TAG, "当前状态,正在刷新...");break;case DONE:headView.setPadding(0, -1 * headContentHeight, 0, 0);progressBar.setVisibility(View.GONE);arrowImageView.clearAnimation();arrowImageView.setImageResource(R.drawable.arrow);tipsTextview.setText("下拉刷新");lastUpdatedTextView.setVisibility(View.VISIBLE);Log.v(TAG, "当前状态,done");break;}}public void setonRefreshListener(OnRefreshListener refreshListener) {this.refreshListener = refreshListener;isRefreshable = true;}public interface OnRefreshListener {public void onRefresh();}public void onRefreshComplete() {state = DONE;lastUpdatedTextView.setText("最近更新:"+ new Date().toLocaleString());changeHeaderViewByState();}private void onRefresh() {if (refreshListener != null) {refreshListener.onRefresh();}}// 此方法直接照搬自网络上的一个下拉刷新的demo,此处是“估计”headView的width以及heightprivate void measureView(View child) {youtParams p = child.getLayoutParams();if (p == null) {p = new youtParams(youtParams.FILL_PARENT,youtParams.WRAP_CONTENT);}int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);int lpHeight = p.height;int childHeightSpec;if (lpHeight > 0) {childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,MeasureSpec.EXACTLY);} else {childHeightSpec = MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED);}child.measure(childWidthSpec, childHeightSpec);}public void setAdapter(BaseAdapter adapter) {lastUpdatedTextView.setText("最近更新:"+ new Date().toLocaleString());super.setAdapter(adapter);}}这个类到此结束了,你可以在项目中建一个类把此类拷贝进去,作为你自定义的listView 使用就可以了。
AndroidStudio如何获取SQLite数据并显⽰到ListView上我们在使⽤ListView的时候需要和数据进⾏绑定,那么问题来了,如何获取SQLite数据库中的数据并动态的显⽰到ListView当中呢?其实过程很简单:⾸先要获取SQLite数据(当然⾸先你要创建⼀个SQLite数据库并填写了⼀些数据),然后引⼊ListView控件,最后将数据和ListView绑定就好了。
⼀获取SQLite数据库中的数据SQLite是⼀个轻量级的数据库,它能将数据保存到你的⼿机,但缺点是⼀旦软件卸载所有数据将⼀同被销毁。
所以要根据⾃⼰的项⽬需要选择性的使⽤。
下⾯要演⽰将SQLite中的数据提取出来。
⾸先定义⼀个类⽤来实例化数据库public class initdate {public Bitmap bitmap;public String content;public String data;public initdate (Bitmap bitmap ,String context,String time){this.bitmap =bitmap;this.content =context;this.data =time;}}创建⼀个List对象⽤来存储数据List<initdate> list = new ArrayList<>();获取SQLite中对应表的数据DBOpenHelper helper = new DBOpenHelper(getActivity(), "数据库的名称", null, 1);//创建对象SQLiteDatabase db = helper.getWritableDatabase();Cursor c = db.query("表名", null, null, null, null, null, null);if (c != null && c.getCount() >= 1) {while (c.moveToNext()) {list.add(new initdate(base64ToBitmap(c.getString(c.getColumnIndex("字段名1"))), c.getString(c.getColumnIndex("字段名2")),c.getString(c.getColumnIndex("字段名3"))));}c.close();db.close();//关闭数据库}base64ToBitmap⽅法⽤于将String类型转换成Bitmappublic static Bitmap base64ToBitmap(String base64info) {byte[] bytes = Base64.decode(base64info, Base64.DEFAULT);return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);}⼆引⼊ListView控件ListView的引⼊是⽐较简单的,我们可以直接将ListView控件拖拽到xml⽂件中即可。
列表详解列表的显示需要三个元素:1.ListV eiw,用来展示列表的View。
2.适配器,用来把数据映射到ListView 上的中介。
3.数据,具体的将被映射的字符串、图片、或者基本组件。
知识点:1.ListView,是Android中比较常用的组件,它以列表的形式展示具体内容,并且能够根据数据的长度自适应显示。
2.Adapter:Android中的Adapter可以这样理解,它是数据List和视图ListView之间的桥梁,数据在Adapter中做处理,然后显示到视图上面来。
Adapter有很多种。
列表的适配器分为三种类型:ArrayAdapter,SimpleAdapter和SimpleCursorAdapter。
●ArrayAdapter最为简单,只能展示一行字。
●SimpleCursorAdapter可以认为是SimpleAdapter对数据库的简单结合,可以方便地把数据库的内容以列表的形式展示出来。
●SimpleAdapter有最好的扩充性,可以自定义出各种效果。
3.List:●所有的List中只能容纳单个不同类型的对象组成的表,而不是Key-V alue键值对。
例如:[ tom,1,c ],List中取出的都是Object对象。
●所有的List中可以有相同的元素,例如V ector中可以有[ tom,koo,too,koo ]。
●所有的List中可以有null元素,例如[ tom,null,1 ]。
●基于Array的List(V ector,ArrayList)适合查询。
●List基本上都是以Array为基础。
ListView使用的例子如下图:一、最简单的ListView1.package com.demo;2.import java.util.ArrayList;3.import java.util.List;4.import android.app.Activity;5.import android.os.Bundle;6.import android.widget.ArrayAdapter;7.import android.widget.ListView;8.public class MyListView extends Activity {9.private ListView listView;10.@Override11.public void onCreate(Bundle savedInstanceState){12.super.onCreate(savedInstanceState);13.listView = new ListView(this);14.listView.setAdapter(new ArrayAdapter<String>(this,yout.simple_expandable_list_item_1,getData()));15.setContentView(listView);16.}17.private List<String> getData(){18.List<String> data = new ArrayList<String>();19.data.add("测试数据1");20.data.add("测试数据2");21.data.add("测试数据3");22.data.add("测试数据4");23.return data;24.}25.}上面代码第14行,使用了ArrayAdapter()来装配数据,要装配这些数据就需要连接ListView 视图对象和数组的适配器来适配工作。
androidListView和ProgressBar(进度条控件)的使⽤⽅法ListView控件⾥⾯装的是⼀⾏⼀⾏的数据,⼀⾏中可能有多列,选中⼀⾏,则该⾏的⼏列都被选中,同时可以触发⼀个事件,这种控件在平时还是⽤得很多的。
使⽤ListView时主要是要设置⼀个适配器,适配器主要是⽤来放置⼀些数据。
使⽤起来稍微有些复杂,这⾥⽤的是android⾃带的SimpleAdapter,形式如下:android.widget.SimpleAdapter.SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)由此可以看出函数的第2个参数为⼀个list,该list⾥⾯存放的是⼀些hashmap,hashmap是⼀些映射,⾥⾯放的是键值对;第3个参数为1个布局⽂件,即适配器输出的布局;第4个参数为字符数组,数组的内容为参数list中map每列的列名;第5个参数为整型数组,其意思为第4个参数对应显⽰的值的格式,⼀般为控件。
因为第3个参数为1个布局⽂件,所以我们该⼯程中我们需要再单独添加⼀个xml⽂件。
同时我们要知道设置ListView的监听器是⽤onListItemClick()函数。
另外还需注意的是在java中定义数组类型并初始化时中间不需要等号,例如new String[]{"user_name", "user_birthday"}。
这次实验的参考的是mars⽼师的资料.ListView使⽤的显⽰效果如下:每次选中⼀⾏时在后台会相应的输出该⾏的位置和id,依次选中这三⾏.后台输出为:实验代码如下:MainActivity.java:复制代码代码如下:package com.example.control3;import java.util.ArrayList;import java.util.HashMap;import android.app.ListActivity;import android.os.Bundle;import android.view.View;import android.widget.ListView;import android.widget.SimpleAdapter;public class MainActivity extends ListActivity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.activity_main);//建⽴⼀个ArrayList,ArrayList⾥⾯放的是Hash表ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String,String>>();HashMap<String, String>map1 = new HashMap<String, String>();HashMap<String, String>map2 = new HashMap<String, String>();HashMap<String, String>map3 = new HashMap<String, String>();//给Hash表中填⼊键值对map1.put("user_name", "⼩红");map1.put("user_birthday", "2012_07_30");map2.put("user_name", "⼩明");map2.put("user_birthday", "2012_07_31");map3.put("user_name", "⼩冬");map3.put("user_birthday", "2012_08_01");list.add(map1);list.add(map2);list.add(map3);//在该activity中创建⼀个简单的适配器SimpleAdapter listAdapter = new SimpleAdapter(this, list,yout.activity_user, new String[]{"user_name", "user_birthday"}, new int[]{er_name, er_birthday});//载⼊简单适配器setListAdapter(listAdapter);}//ListView监听器响应函数@Overrideprotected void onListItemClick(ListView l, View v, int position, long id) { // TODO Auto-generated method stubsuper.onListItemClick(l, v, position, id);System.out.println("id--------------------" +id);System.out.println("Position-------------" + position);}}activity_main.xml:复制代码代码如下:<LinearLayout xmlns:android="/apk/res/android" xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><LinearLayoutandroid:id="@+id/listLinearLayout"android:layout_width="fill_parent"android:layout_height="wrap_content"android:orientation="vertical"><ListViewandroid:id="@id/android:list"android:layout_width="fill_parent"android:layout_height="wrap_content"android:drawSelectorOnTop="false"android:scrollbars="vertical"/></LinearLayout></LinearLayout>activity_user.xml:复制代码代码如下:<LinearLayout xmlns:android="/apk/res/android" xmlns:tools="/tools"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="horizontal"android:padding="10dip"><!--该布局⽂件时⽔平⽅向上2个TextView控件,并设置了其相应的属性--><TextViewandroid:id="@+id/user_name"android:layout_width="180dip"android:layout_height="30dip"android:textSize="10pt"android:singleLine="true"/><TextViewandroid:id="@+id/user_birthday"android:layout_width="fill_parent"android:layout_height="fill_parent"android:textSize="10pt"android:gravity="right"/></LinearLayout>:ProgressBar控件的使⽤⽐较简单,在android开发中,其默认的形式是1个圆周型的进度条,也就是代表⼀直在等待,这时候是看不到实际上完成的进度的。
Android中ListView动态加载数据
2011-11-05 19:02
1. 引言:
为了提高ListView的效率和应用程序的性能,在Android应用程序中不应该一次性加载ListView所要显示的全部信息,而是采所需的数据,并渲染到ListView组件中,这样可以极大的改善应用程序的性能和用户体验。
2. 交互:
进入ListView组件,首先预加载N条记录,当用户滑动到最后一条记录显示加载提示信息,并从后台加载N条数据,接着渲染
3. 效果图:
4. 程序实现:
package com.focus.loading;
import android.app.ListActivity;
import android.os.Bundle;
import android.os.Handler;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.AbsListView.OnScrollListener;
import youtParams;
public class ListViewLoadingActivity extends ListActivity implements
OnScrollListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* "加载项"布局,此布局被添加到ListView的Footer中。
*/
mLoadLayout = new LinearLayout(this);
mLoadLayout.setMinimumHeight(60);
mLoadLayout.setGravity(Gravity.CENTER);
mLoadLayout.setOrientation(LinearLayout.HORIZONTAL);
/**
* 向"加载项"布局中添加一个圆型进度条。
*/
ProgressBar mProgressBar = new ProgressBar(this);
mProgressBar.setPadding(0, 0, 15, 0);
mLoadLayout.addView(mProgressBar, mProgressBarLayoutParams);
/**
* 向"加载项"布局中添加提示信息。
*/
TextView mTipContent = new TextView(this);
mTipContent.setText("加载中...");
mLoadLayout.addView(mTipContent, mTipContentLayoutParams);
/**
* 获取ListView组件,并将"加载项"布局添加到ListView组件的Footer中。
*/
mListView = getListView();
mListView.addFooterView(mLoadLayout);
/**
* 组ListView组件设置Adapter,并设置滑动监听事件。
*/
setListAdapter(mListViewAdapter);
mListView.setOnScrollListener(this);
}
public void onScroll(AbsListView view, int mFirstVisibleItem,
int mVisibleItemCount, int mTotalItemCount) {
mLastItem = mFirstVisibleItem + mVisibleItemCount - 1;
if (mListViewAdapter.count > mCount) {
mListView.removeFooterView(mLoadLayout);
}
}
public void onScrollStateChanged(AbsListView view, int mScrollState) {
/**
* 当ListView滑动到最后一条记录时这时,我们会看到已经被添加到ListView的"加载项"布局,这时应该加载剩余数据*/
if (mLastItem == mListViewAdapter.count
&& mScrollState == OnScrollListener.SCROLL_STATE_IDLE) {
if (mListViewAdapter.count <= mCount) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mListViewAdapter.count += 10;
mListViewAdapter.notifyDataSetChanged();
mListView.setSelection(mLastItem);
}
}, 1000);
}
}
}
class ListViewAdapter extends BaseAdapter {
int count = 10;
public int getCount() {
return count;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View view, ViewGroup parent) {
TextView mTextView;
if (view == null) {
mTextView = new TextView(ListViewLoadingActivity.this);
} else {
mTextView = (TextView) view;
}
mTextView.setText("Item " + position);
mTextView.setTextSize(20f);
mTextView.setGravity(Gravity.CENTER);
mTextView.setHeight(60);
return mTextView;
}
}
private LinearLayout mLoadLayout;
private ListView mListView;
private ListViewAdapter mListViewAdapter = new ListViewAdapter();
private int mLastItem = 0;
private int mCount = 41;
private final Handler mHandler = new Handler();
private final LayoutParams mProgressBarLayoutParams = new youtParams( youtParams.WRAP_CONTENT,
youtParams.WRAP_CONTENT);
private final LayoutParams mTipContentLayoutParams = new youtParams(。