android显示数据的组件是listView.listView通过adapter适配数据,这里的数据包括字符窜   图片  组件等。

   

 显示数据的机制:列表首先需要得到数据的长度,这时调用的方法是getCount(),然后开始绘制数据,调用getView()方法,列表如何显示就是在这一层体现。listView绘制每一个item,需要adpater返回一个视图,如果你的getCount()返回值是0的话,列表一行都不会显示,如果返回1,就只显示一行。返回几则显示几行。如果加载的数据很多的话,那么就考虑优化的问题。


 向上滑动出不可视区域时就会旧的布局去填充新的布局。


  1. ViewHolder   Tag 必不可少,这个不多说!

  2. 如果自定义Item中有涉及到图片等等的,一定要狠狠的处理图片,图片占的内存是ListView项中最恶心的,处理图片的方法大致有以下几种:
    2.1:不要直接拿个路径就去循环decodeFile();这是找死….用Option保存图片大小、不要加载图片到内存去;
    2.2:  拿到的图片一定要经过边界压缩
    2.3:在ListView中取图片时也不要直接拿个路径去取图片,而是以WeakReference(使用WeakReference代替强引用。比如可以使        用WeakReference<Context> mContextRef)、SoftReference、WeakHashMap等的来存储图片信息,是图片信息不是图片哦!
    2.4:在getView中做图片转换时,产生的中间变量一定及时释放,用以下形式:

  3. 尽量避免在BaseAdapter中使用static 来定义全局静态变量,我以为这个没影响 ,这个影响很大,static是Java中的一个关键字,当用它来修饰成员变量时,那么该变量就属于该类,而不是该类的实例。所以用static修饰的变量,它的生命周期是很长的,如果用它来引用一些资源耗费过多的实例(比如Context的情况最多),这时就要尽量避免使用了..

  4. 如果为了满足需求下必须使用Context的话:Context尽量使用Application Context,因为Application的Context的生命周期比较长,引用它不会出现内存泄露的问题

  5. 尽量避免在ListView适配器中使用线程,因为线程产生内存泄露的主要原因在于线程生命周期的不可控制

  6. 记下小马自己的错误:
                之前使用的自定义ListView中适配数据时使用AsyncTask自行开启线程的,这个比用Thread更危险,因为Thread只有在run函数不 结束时才出现这种内存泄露问题,然而AsyncTask内部的实现机制是运用了线程执行池(ThreadPoolExcutor,要想了解这个类的话大家加下我们的Android开发群五号,因为其它群的存储空间快满了,所以只上传到五群里了,看下小马上传的Gallery源码,你会对线程执行池、软、弱、强引用有个更深入的认识),这个类产生的Thread对象的生命周期是不确定的,是应用程序无法控制的,因此如果AsyncTask作为Activity的内部类,就更容易出现内存泄露的问题。这个问题的解决办法小马当时网上查到了记在txt里了,如下:
    6.1:将线程的内部类,改为静态内部类。
    6.2:在线程内部采用弱引用保存Context引用



1   直接定义listView.xml

2   继承listView


生成动态数据:

  1

  1. //生成动态数组,加入数据

    ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String, Object>>();  

  2. for(int i=0;i<10;i++)  

  3.        {  

  4.            HashMap<String, Object> map = new HashMap<String, Object>();  

  5.            map.put("ItemImage", R.drawable.checked);//图像资源的ID

  6.            map.put("ItemTitle", "Level "+i);  

  7.            map.put("ItemText", "Finished in 1 Min 54 Secs, 70 Moves! ");  

  8.            listItem.add(map);  

  9.        }  



  1. //下面是数据映射关系,mFrom和mTo按顺序一一对应

  2. String[] mFrom = new String[]{"img","title1","title2","time"};  

  3. int[] mTo = newint[]{R.id.img,R.id.title1,R.id.title2,R.id.time};  

  4. //获取数据,这里随便加了10条数据,实际开发中可能需要从数据库或网络读取

  5. List<Map<String,Object>> mList = new ArrayList<Map<String,Object>>();  

  6. Map<String,Object> mMap = null;  

  7. for(int i = 0;i < 10;i++){  

  8.    mMap = new HashMap<String,Object>();  

  9.    mMap.put("img", R.drawable.icon);  

  10.    mMap.put("title1", "标题");  

  11.    mMap.put("title2", "副标题");  

  12.    mMap.put("time", "2011-08-15 09:00");  

  13.    mList.add(mMap);  

  14. }  


  1. SimpleAdapter mAdapter = new SimpleAdapter(this,mList,R.layout.item,mFrom,mTo);  

  2. mListView.setAdapter(mAdapter);  




  1. //生成适配器的Item和动态数组对应的元素

    SimpleAdapter listItemAdapter = new SimpleAdapter(this,listItem,//数据源

  2.            R.layout.list_items,//ListItem的XML实现

  3. //动态数组与ImageItem对应的子项        

  4. new String[] {"ItemImage","ItemTitle", "ItemText"},  

  5. //ImageItem的XML文件里面的一个ImageView,两个TextView ID

  6. newint[] {R.id.ItemImage,R.id.ItemTitle,R.id.ItemText}  

  7.        );  


  1. //添加点击

  2.        list.setOnItemClickListener(new OnItemClickListener() {  

  3. @Override

  4. publicvoid onItemClick(AdapterView<?> arg0, View arg1, int arg2,  

  5. long arg3) {  

  6.                setTitle("点击第"+arg2+"个项目");  

  7.            }  

  8.        });  

  1. //添加长按点击

  2.        list.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {  

  3. @Override

  4. publicvoid onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {  

  5.                menu.setHeaderTitle("长按菜单-ContextMenu");    

  6.                menu.add(0, 0, 0, "弹出长按菜单0");  

  7.                menu.add(0, 1, 0, "弹出长按菜单1");    

  8.            }  

  9.        });  

  10.    }  

  1. //长按菜单响应函数

  2. @Override

  3. publicboolean onContextItemSelected(MenuItem item) {  

  4.        setTitle("点击了长按菜单里面的第"+item.getItemId()+"个项目");  

  5. returnsuper.onContextItemSelected(item);  

  6.    }  



在实际开发中基本上考虑用的是simpleAdpater

布局中常用的控件位置属性  android:layout_alignParentRight="true"   android:layout_toRightOf="@id/img"   android:paddingLeft="8dp"   android:layout_alignParentLeft="true"


改变listView显示的背景:如果你只是换背景的颜色的话,可以直接指定android:cacheColorHint为你所要的颜色,如果你是用图片做背景的话,那也只要将android:cacheColorHint指定为透明(#00000000)就可以了,然后指定属性 android:background="@drawable/bg"


自定义ListView行间的分割线:在ListView中我们使用属性 android:divider="#FF0000" 定义分隔符为红色


点击Item时无背景颜色变化:在xml文件中的ListView控件中加入如下属性:
android:listSelector="@drawable/timer_list_selector"
在drawable中定义timer_list_selector的属性值
timer_list_selector.xml中定义如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@android:color/transparent" />
</selector>
在values文件夹下的colors.xml中定义transparent如下:
<color name="transparent">#50000000</color>


设置Item之间无间隙
在xml文件中ListView控件中加入如下属性:
android:divider="#00000000"
或者在javaCode中如下定义:
listView.setDividerHeight(0);



1.、listview在拖动的时候背景图片消失变成黑色背景。等到拖动完毕我们自己的背景图片才显示出来。


2 、listview的上边和下边有黑色的阴影。


3、lsitview的每一项之间需要设置一个图片做为间隔。


针对以上问题 在listview的xml文件中设置一下语句。


问题1 有如下代码结解决 android:scrollingCache="false"


问题2 用如下代码解决:android:fadingEdge="none"
问题3 用如下代码解决: android:divider="@drawable/list_driver" 其中 @drawable/list_driver 是一个图片资源

<ListView
android:id="@+id/myListView01"
android:layout_width="fill_parent"
android:layout_height="287dip"
android:fadingEdge="none"

android:scrollingCache="false"
android:divider="@drawable/list_driver"
android:background="@drawable/list">
</ListView>



Android简单的SQLite操作及ListView展示数据

Android系统提供了一个SQLiteOpenHelper的一个辅助类,使用此类可以完成对数据库的创建及更新

  1. publicclass DBOpenHelper extends SQLiteOpenHelper{  

  2. /**数据库名称*/

  3. privatestaticfinal String DATABASE_NAME="MyAppDB";  

  4. /**数据库版本*/

  5. privatestaticfinalint DATABASE_VERSION=1;  

  6. /** 创建数据表语句*/

  7. privatestaticfinal String DDL_CREATE_TABLE_APPINFO="CREATE TABLE IF NOT EXISTS AppInfo (appId integer primary key autoincrement,appName text,appDescription text, remark text)";  

  8. /**

  9.     * 实例化数据库连接.

  10.     * @param context

  11.     */

  12. public DBOpenHelper(Context context){  

  13. super(context, DATABASE_NAME, null, DATABASE_VERSION);  

  14. /**初始化数据表*/

  15. this.getWritableDatabase().execSQL(DDL_CREATE_TABLE_APPINFO);  

  16.    }  

  17. @Override

  18. publicvoid onCreate(SQLiteDatabase db) {  

  19. // TODO Auto-generated method stub

  20.    }  

  21. @Override

  22. publicvoid onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  

  23. // TODO Auto-generated method stub

  24.    }  

  25. }  

main.xml,只添加了一个ListView用于显示数据

  1. <?xmlversion="1.0"encoding="utf-8"?>

  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

  3. android:layout_width="fill_parent"

  4. android:layout_height="fill_parent"

  5. android:orientation="vertical">

  6. <ListView

  7. android:id="@+id/listView_appList"

  8. android:layout_width="match_parent"

  9. android:layout_height="wrap_content">

  10. </ListView>

  11. </LinearLayout>


数据列表的项实现:list_item.xml

  1. <?xmlversion="1.0"encoding="utf-8"?>

  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

  3. android:layout_width="match_parent"

  4. android:layout_height="match_parent"

  5. android:orientation="vertical">

  6. <TextView

  7. android:id="@+id/textView_appName"

  8. android:layout_width="wrap_content"

  9. android:layout_height="wrap_content"

  10. android:textAppearance="?android:attr/textAppearanceMedium"/>

  11. <TextView

  12. android:id="@+id/textView_appDescription"

  13. android:layout_width="wrap_content"

  14. android:layout_height="wrap_content"

  15. android:textAppearance="?android:attr/textAppearanceSmall"/>

  16. </LinearLayout>


SQLiteDemoActivity 代码:

  1. publicclass SQLiteDemoActivity extends Activity {  

  2. @Override

  3. publicvoid onCreate(Bundle savedInstanceState) {  

  4. super.onCreate(savedInstanceState);  

  5.        setContentView(R.layout.main);  

  6. //initData(); //这个方法只是用来临时加载一下数据以备显示

  7.        ListView listView=(ListView)findViewById(R.id.listView_appList);  

  8. //获取查询结果

  9.        ArrayList<HashMap<String, Object>> listData=fillList();  

  10. //获取适配器

  11.        SimpleAdapter adapter=fillAdapter(listData);  

  12. //添加并且显示  

  13.        listView.setAdapter(adapter);    

  14.    }  

  15. /**

  16.     * 插入数据操作

  17.     */

  18. publicvoid initData(){  

  19.        DBOpenHelper helper=new DBOpenHelper(this);  

  20.        ContentValues values=new ContentValues();  

  21.        values.put("appName", "手机QQ2212");  

  22.        values.put("appDescription", "手机QQ2012是腾讯公司基于移动终端开发的一款应用软件。");  

  23.        values.put("remark", "手机QQ2012是腾讯公司基于移动终端开发的一款应用软件。");  

  24.        helper.getWritableDatabase().insert("AppInfo", null, values);  

  25.    }  

  26. /**

  27.     * 查询AppInfo返回Map集合

  28.     * @return

  29.     */

  30. public  ArrayList<HashMap<String, Object>> fillList(){  

  31. //生成动态数组,并且转载数据  

  32.        ArrayList<HashMap<String, Object>> dataList = new ArrayList<HashMap<String, Object>>();    

  33.        DBOpenHelper helper=new DBOpenHelper(this);  

  34.        SQLiteDatabase db=helper.getReadableDatabase();  

  35. try{  

  36.            Cursor cursor=db.rawQuery("SELECT * FROM AppInfo", null);  

  37.            cursor.moveToFirst();  

  38. if(cursor.moveToFirst()) {    

  39.                    Integer appId = cursor.getInt(cursor.getColumnIndex("appId"));    

  40.                    String appName = cursor.getString(cursor.getColumnIndex("appName"));  

  41.                    String appDescription = cursor.getString(cursor.getColumnIndex("appDescription"));  

  42.                    HashMap<String, Object> map = new HashMap<String, Object>();    

  43.                    map.put("appId",appId);    

  44.                    map.put("appName", appName);    

  45.                    map.put("appDescription", appDescription);    

  46.                    dataList.add(map);    

  47.            }    

  48.        }catch(Exception ex){  

  49.            ex.printStackTrace();  

  50.        }finally{  

  51. if(db.isOpen()){  

  52.                db.close();  

  53.            }  

  54.        }  

  55. return dataList;  

  56.    }  

  57. /**

  58.     * 填充数据,取得数据适配器.

  59.     * @param listData

  60.     * @return

  61.     */

  62. public SimpleAdapter fillAdapter(ArrayList<HashMap<String, Object>> listData){  

  63. //生成适配器,数组===》ListItem  

  64.        SimpleAdapter adapter = new SimpleAdapter(this,  

  65.                                                    listData,//数据来源  

  66.                                                    R.layout.list_item,//ListItem的XML实现  

  67. //动态数组与ListItem对应的子项          

  68. new String[] {"appName", "appDescription"},    

  69. //ListItem的XML文件里面的两个TextView ID  

  70. newint[] {R.id.textView_appName,R.id.textView_appDescription});    

  71. return adapter;  

  72.    }  

  73. }  




自定义listview高亮效果(item带立体背景效果)

  1. <?xmlversion="1.0"encoding="utf-8"?>

  2. <selectorxmlns:android="http://www.norkoo.com">

  3. <itemandroid:state_pressed="true">

  4. <shape>

  5. <gradientandroid:startcolor="#ff8c00"android:endcolor="#ffffff"

  6. android:angle="270"/>

  7. <strokeandroid:width="2dp"android:color="#dcdcdc"/>

  8. <cornersandroid:radius="2dp"/>

  9. <paddingandroid:left="10dp"android:top="10dp"

  10. android:right="10dp"android:bottom="10dp"/>

  11. </shape>

  12. </item>

  13. <itemandroid:state_focused="true">

  14. <shape>

  15. <gradientandroid:startcolor="#ffc2b7"android:endcolor="#ffc2b7"

  16. android:angle="270"/>

  17. <strokeandroid:width="2dp"android:color="#dcdcdc"/>

  18. <cornersandroid:radius="2dp"/>

  19. <paddingandroid:left="10dp"android:top="10dp"

  20. android:right="10dp"android:bottom="10dp"/>

  21. </shape>

  22. </item>

  23. <item>

  24. <shape>

  25. <gradientandroid:startcolor="#ff9d77"android:endcolor="#ff9d77"

  26. android:angle="270"/>

  27. <strokeandroid:width="2dp"android:color="#fad3cf"/>

  28. <cornersandroid:radius="2dp"/>

  29. <paddingandroid:left="10dp"android:top="10dp"

  30. android:right="10dp"android:bottom="10dp"/>

  31. </shape>

  32. </item>

  33. </selector>

listview_item_bg.xml

  1. <?xmlversion="1.0"encoding="utf-8"?>

  2. <selectorxmlns:android="http://schemas.android.com/apk/res/android">

  3. <!-- focused -->

  4. <itemandroid:drawable="@color/white"android:state_focused="true"/>

  5. <!-- focused and pressed -->

  6. <itemandroid:drawable="@color/white"android:state_focused="true"

  7. android:state_pressed="true"/>

  8. <!-- pressed -->

  9. <itemandroid:drawable="@color/tab_blue"android:state_pressed="true"/>

  10. <!-- default -->

  11. <!-- <item android:drawable="@color/white" /> -->

  12. <item>

  13. <shape

  14. android:shape="rectangle">

  15. <gradientandroid:startColor="#ffffff"android:endColor="#EDEDED"

  16. android:angle="-90"/>

  17. </shape>

  18. </item>

  19. </selector>

使用:在listview里面的item的layout中:android:background="@xml/listview_item_bg"