亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

ListView基本用法及適配器介紹

2019-11-09 16:31:05
字體:
來源:轉載
供稿:網友

ListView基本用法

ListView常用屬性

1.android:divider=”” 列表之間繪制的顏色或者圖片。一般開發中用于分隔表項。在實際開發過程中,如果你不想要列表之間的分割線,可以設置屬性為 @null 2. android:dividerHeight=”” 前面 divider 的高度。 3. android:stackFromBottom=”” 使它們的內容從底部開始顯示。默認是 false 從頂部開始顯示,如果設置為 true 則從底部開始顯示。 4. android:transcriptMode=”” 設置列表的 transcriptMode 模式,該模式指定列表添加新的選項的時候,是否自動滑動到底部,顯示新的選項。 共三個枚舉值: disabled:取消 transcriptMode 模式,默認的 。 normal:當接受到數據集合改變的通知,并且僅僅當最后一個選項已經完全顯示在屏幕的時候,自動滑動到底部。 alwaysScroll:無論當前列表顯示什么選項,列表將會自動滑動到底部顯示最新的選項。

ListView常用方法

setEmptyView(View)設置ListView沒有數據時展示的布局 需要注意。該方法需要的參數 View。該 View 必須和 ListView 在同一個布局容器中。

setHeaderView() 添加頭部布局,可以添加多個(需要動態加載布局)

setFooterView() 添加尾部布局,可以添加多個(需要動態加載布局)

ListView常用監聽方法

listView1.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { } });

onItemCLick 方法的參數說明: parent:指 ListView 本身。 view:當前被點擊的 Item 的 View 對象 position:當前點擊的 Item 的視圖位置下標 id:該值是 Adapter 的 getItemId() 方法所返回的值。

適配器

Android 中適配器是連接后端數據和前端顯示的接口,是數據和UI之間重要的紐帶,主要在 View 上顯示【一般是 listview】??梢钥醋魇墙缑鏀祿壎ǖ囊环N理解。它所操縱的數據一般都是一些比較復雜的數據,如數組,鏈表,數據庫,集合等。適配器就像顯示器,把復雜的東西按人可以接受的方式來展現。 高級控件:ListView、GridView[網格視圖]、Spinner[下拉列表]、Gallery[畫廊]、ViewPage 等都需要使用適配器來為其設置數據源。

常用的適配器有:ArrayAdapter,SimpleAdapter,CursorAdapter 這三個都是繼承 BaseAdapter,BaseAdapter是一個抽象類,需要子類繼承并實現其中的方法才能使用,常用于用戶自定義適配器時,顯示比較復雜的數據。

ArrayAdapter

使用簡單 例:

public class MainActivity extends AppCompatActivity { PRivate ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //動態加載布局... View main = getLayoutInflater().inflate(R.layout.activity_main, new FrameLayout(this), false); setContentView(main);// setContentView(R.layout.activity_main); ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, getData()); listView = (ListView) main.findViewById(R.id.listView); //動態加載布局.... //第一步:得到布局加載器// LayoutInflater inflater= getLayoutInflater();//在Activity中// LayoutInflater inflater= LayoutInflater.from(this);//在有Context 的地方// LayoutInflater inflater= (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);//在有Context 的地方 LayoutInflater inflater = LayoutInflater.from(this); //第二步:使用布局加載器 加載布局 View view1 = inflater.inflate(R.layout.view_list_header, listView, false); View view2 = inflater.inflate(R.layout.view_list_header, listView, false); View view3 = inflater.inflate(R.layout.view_list_header, listView, false); //添加頭部布局// listView.addHeaderView(view1);// listView.addHeaderView(view2); //添加尾部布局 // listView.addFooterView(view3); //添加空的視圖(當ListView 沒有數據的時候顯示) listView.setEmptyView(findViewById(R.id.lv_emptyView));//要求該視圖 必須在 ListView 所在的容器里 view1.findViewById(R.id.btn_sss).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "呵呵", Toast.LENGTH_SHORT).show(); } }); //綁定適配器到ListView listView.setAdapter(arrayAdapter); } //初始化數據 public List<String> getData() { ArrayList<String> data = new ArrayList<>(); for (int i = 0; i < 50; i++) { data.add("我和你吻別,在無人的街道..." + i); } return data; }}

SimpleAdapter

new SimpleAdapter(context, data, resource, from, to)

參數說明: context : 上下文 data:數據源 格式 List

SimpleAdapter與ViewBinder結合使用(因為SimpleAdapter是系統寫好的,可以使用ViewBinder來自己綁定視圖)

simpleAdapter.setViewBinder(new ViewBinder() { @Override public boolean setViewValue(View view, Object data, String textRepresentation) { return false; } });

setViewValue 方法的參數說明: view 當前需要綁定的視圖控件(不是整個布局,而是布局里面具體某一個ImageView 或 TextView 等); data:當前 view 所對應的 數據 textRepresentation:該參數是由 data 經過處理的,內部做了非空判斷,所以該參數永遠不為 null

例:

public class MainActivity extends AppCompatActivity { private ListView lv_show; //初始化數據 ArrayList<HashMap<String, Object>> list = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv_show = (ListView) findViewById(R.id.lv_show); HashMap<String, Object> map1 = new HashMap<>(); map1.put("icon", R.mipmap.icon0); map1.put("title", "訂閱號"); map1.put("msg", "iphone7發布了,激動我買note7"); map1.put("time", 17567898762L); list.add(map1); /******************/ HashMap<String, Object> map2 = new HashMap<>(); map2.put("icon", R.mipmap.icon1); map2.put("title", "QQ郵箱提醒"); map2.put("msg", "阿斯頓飛開了家"); map2.put("time", 17567898762L); list.add(map2); /******************/ HashMap<String, Object> map3 = new HashMap<>(); map3.put("icon", R.mipmap.icon2); map3.put("title", "微信活動"); map3.put("msg", "日體育偶朋友"); map3.put("time", 17567898762L); list.add(map3); /******************/ HashMap<String, Object> map4 = new HashMap<>(); map4.put("icon", R.mipmap.icon3); map4.put("title", "美團外賣"); map4.put("msg", "飛規劃局快樂空間和高峰過后"); map4.put("time", 17567898762L); list.add(map4); /******************/ String from[] = {"title", "icon", "msg", "time"}; int to[] = {R.id.tv_title, R.id.imageView, R.id.tv_lastMsg, R.id.tv_time}; //創建SimpleAdapter /** * @params 參數一:Context * @params 參數二:數據源,List<? extends Map<String,?>> * @params 參數三:布局 Layout ID * @params 參數四:由參數二 的 每一個Map 的 key 所組成的 String[] * @params 參數五:由參數三 布局 里面的子控件的 View 的 ID 組成的 int[] * * 注意:參數四與參數五,一個數據對應一個view。數組的數據和控件下標位置要對齊 * */ SimpleAdapter adapter = new SimpleAdapter(this, list, R.layout.view_list_item_wechat, from, to); //ViewBind adapter.setViewBinder(new SimpleAdapter.ViewBinder() { @Override public boolean setViewValue(View view, Object data, String textRepresentation) { if (view.getId() == R.id.tv_time && data instanceof Long) { //如果是時間,我們自己綁定 TextView t = (TextView) view; Long time = Long.parseLong(data + ""); t.setText(new SimpleDateFormat("HH:mm", Locale.CHINA).format(new Date(time))); return true;//返回true 自己綁定數據 } if (view instanceof ImageView) { //如果是ImageView 添加一個點擊事件 view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "點擊了頭像", Toast.LENGTH_SHORT).show(); } }); } return false;//交給系統綁定 } }); lv_show.setAdapter(adapter); //設置ListView 的 Item的點擊事件 lv_show.setOnItemClickListener(new AdapterView.OnItemClickListener() { /** * * @param parent 設置該點擊事件的 AdapterView 本身(ListView) * @param view 點擊的Item的視圖對象 * @param position 視圖在 Adapter 中的位置 * @param id 視圖在ListView 中的行的下標 */ @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Log.d(TAG, "parent=" + parent); Log.d(TAG, "view=" + view); Log.d(TAG, "position=" + position); Log.d(TAG, "id=" + id); HashMap<String, Object> map = list.get(position); Object title = map.get("title"); Toast.makeText(MainActivity.this, "" + title, Toast.LENGTH_SHORT).show(); } }); }}

BaseAdapter

BaseAdapter中的四個方法的說明

class MyAdapter extends BaseAdapter { @Override public int getCount() { return 0;//返回適配器的長度 } @Override public Object getItem(int position) { //position 當前視圖的下標 return null;//系統不會主動調用該方法,由開發者自己實現 } @Override public long getItemId(int position) { //position 當前視圖的下標 return 0;//ListView Item 點擊事件中第四個參數的返回值 } /** * position 當前視圖的下標 * convertView 布局的復用(當有布局滑出 ListView 顯示的范圍,convertView 就指向 剛滑出的布局) * parent ListView 本身 */ @Override public View getView(int position, View convertView, ViewGroup parent) { return null;//最主要的方法,返回當前 Item 展示的布局 } }

ListView的ConvertView復用

1.重用了convertView,很大程度上的減少了內存的消耗。通過判斷convertView是否為null,是的話就需要產生一個View出來,然后給這個視圖數據,最后將這個視圖返回給底層,呈獻給用戶。

2.ViewHolder 為static,也就是靜態的,靜態類只會在第一次加載時 會耗費比較長時間,但是后面就可以很好幫助加載,同時保證了內存中只有一個ViewHolder,節省了內存的開銷

3.給contentView設置tag(setTag()),傳入一個viewHolder對象,用于緩存要顯示的數據

4.圖片采用異步加載方式

5.如果listview需要顯示的item很多,就要考慮分頁加載。比如一共要顯示100條或者更多的時候,我們可以考慮先加載20條,等用戶拉到列表底部的時候再去 加載接下來的20條

6.盡量避免在ListView適配器中使用線程,因為線程是產生內存泄露的主要原因在于線程生命周期的不可控制

7.ListView布局的layout_height盡量使用march_parent防止用戶誤操作屏幕導致重復調用getview方法

@Override public View getView(int position, View convertView, ViewGroup parent) { View layout = null; if (convertView == null) { layout = getLayoutInflater().inflate(R.layout.activity_main, parent, false); //在這里去 findViewById 以及更新UI }else{//如果 convertView 不等于 null 了。則不需要再去加載一次布局 layout = convertView; //在這里去 findViewById 以及更新UI } return layout; }

例: MainActivity

public class MainActivity extends AppCompatActivity { private ListView lv_show; private ArrayList<Student> data; private int images[] = {R.mipmap.icon0, R.mipmap.icon1, R.mipmap.icon2, R.mipmap.icon3, R.mipmap.icon4, R.mipmap.icon5, R.mipmap.icon6, R.mipmap.icon7, R.mipmap.icon8, R.mipmap.icon9, R.mipmap.icon10, R.mipmap.icon11}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv_show = (ListView) findViewById(R.id.lv_show); initData(); MyAdapter myAdapter = new MyAdapter(this, data); lv_show.setAdapter(myAdapter); lv_show.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(MainActivity.this,"id="+id,Toast.LENGTH_SHORT).show(); } }); } //初始化數據 private void initData() { data = new ArrayList<>(); for (int i = 0; i < images.length; i++) { long l = System.currentTimeMillis(); data.add(new Student(images[i], "標題" + i, "最后一條消息" + i, l - i * 10000)); } }}

MyAdapter

public class MyAdapter extends BaseAdapter { private Context mContext; private List<Student> mData; public MyAdapter(Context context, List<Student> data) { this.mData = data; this.mContext = context; } //適配器的Item的長度 @Override public int getCount() { return mData == null ? 0 : mData.size(); } //每個Item將要顯示的視圖(View) @Override public View getView(int position, View convertView, ViewGroup parent) { Student student = getItem(position); String title = student.getTitle(); if ("標題5".equals(title)) { View view = LayoutInflater.from(mContext).inflate(R.layout.view_list_item_news, parent, false); return view; } View view = LayoutInflater.from(mContext).inflate(R.layout.view_list_item_wechat, parent, false); ImageView imageView = (ImageView) view.findViewById(R.id.imageView); TextView tv_title = (TextView) view.findViewById(R.id.tv_title); TextView tv_lastMsg = (TextView) view.findViewById(R.id.tv_lastMsg); TextView tv_time = (TextView) view.findViewById(R.id.tv_time); imageView.setImageResource(student.getImageResId()); tv_title.setText(title); tv_lastMsg.setText(student.getLastMsg()); //格式化時間 String dataStr = new SimpleDateFormat("HH:mm", Locale.CHINA).format(new Date(student.getTime())); tv_time.setText(dataStr); return view; } //開發者自己實現,一般用來得到當前 position位置的 數據 @Override public Student getItem(int position) { return mData.get(position); } //當用戶設置了 ListView的Item的點擊事件的時候,講此值 作為第四個參數傳遞 @Override public long getItemId(int position) { return 0; }}

Student

public class Student { private int imageResId; private String title; private String lastMsg; private long time; @Override public String toString() { return "Student{" + "imageResId=" + imageResId + ", title='" + title + '/'' + ", lastMsg='" + lastMsg + '/'' + ", time=" + time + '}'; } public Student() { } public Student(int imageResId, String title, String lastMsg, long time) { this.imageResId = imageResId; this.title = title; this.lastMsg = lastMsg; this.time = time; } public int getImageResId() { return imageResId; } public void setImageResId(int imageResId) { this.imageResId = imageResId; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getLastMsg() { return lastMsg; } public void setLastMsg(String lastMsg) { this.lastMsg = lastMsg; } public long getTime() { return time; } public void setTime(long time) { this.time = time; }}

上面寫法沒有布局復用

ConvertView復用寫法(使用RecycleBin機制 復用Item布局,防止OOM)

public class MainActivity extends AppCompatActivity { private Integer[] imageResId = {R.mipmap.a, R.mipmap.b, R.mipmap.c, R.mipmap.e , R.mipmap.f, R.mipmap.g, R.mipmap.h, R.mipmap.i}; private ListView lv_show; private List<Integer> list = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv_show = (ListView) findViewById(R.id.lv_show); for (int i = 0; i < 60; i++) { list.addAll(Arrays.asList(imageResId)); } lv_show.setAdapter(new MyAdapter()); } class MyAdapter extends BaseAdapter { class ViewHolder { TextView tv_title; ImageView iv_icon; } @Override public int getCount() { return list == null ? 0 : list.size(); } @Override public Integer getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { Integer data = getItem(position);//當前行的數據 View layout; ViewHolder viewHolder; if (convertView == null) { layout = getLayoutInflater().inflate(R.layout.view_list_item_wechat, parent, false); viewHolder = new ViewHolder();// 當前Item 的布局的子控件的引用的集合 viewHolder.tv_title = (TextView) layout.findViewById(R.id.tv_title); viewHolder.iv_icon = (ImageView) layout.findViewById(R.id.imageView); layout.setTag(viewHolder);//把該布局的 子控件的引用 綁定到該布局上 } else { viewHolder = (ViewHolder) convertView.getTag(); layout = convertView; } viewHolder.tv_title.setText("Item " + position); viewHolder.iv_icon.setImageResource(data); return layout; } }}

Listview卡頓的解決思路

1、使用Adapter提供的convertView 進行復用ItemView 2、使用ViewHolder 減少 findviewbyid 調用次數 3、 Listview 被多層嵌套,多次的onMessure導致卡頓,需要減少嵌套的層數 4、如果多層嵌套無法避免,建議把Listview的高和寬設置為 match_parent 5、使用分頁,減少每次ListView加載的數據 6、如果顯示圖片,可以對圖片進行緩存,減少加載的 7、減少不必要的視圖更新


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲女成人图区| 久久精品国产欧美亚洲人人爽| 国产成人在线视频| 成人福利免费观看| 九九热在线精品视频| 成人两性免费视频| 国产日韩在线精品av| 中文字幕日韩综合av| 日韩电影中文字幕在线观看| 亚洲第一精品久久忘忧草社区| 国产精品美女久久久久久免费| 亚洲人成网站999久久久综合| 亚洲黄色成人网| 国产成人精品久久二区二区91| 久久久久国产精品www| 91sao在线观看国产| 丁香五六月婷婷久久激情| 91精品国产高清自在线看超| 亚洲国产精品人久久电影| 亚洲国产精彩中文乱码av在线播放| 亚洲一区美女视频在线观看免费| 国产精品入口夜色视频大尺度| 欧美精品精品精品精品免费| 国产欧美日韩精品专区| 亚洲天堂免费视频| 国产69精品久久久| 久久免费视频观看| 精品中文字幕视频| 国产精品欧美激情在线播放| 亚洲欧美国产一区二区三区| 欧美午夜宅男影院在线观看| 高清在线视频日韩欧美| 国产精品一区二区av影院萌芽| 欧美人在线视频| 日韩女优在线播放| 国产亚洲免费的视频看| 久久亚洲一区二区三区四区五区高| 亚洲黄色av网站| 国产成+人+综合+亚洲欧美丁香花| 久久激情五月丁香伊人| 亚洲奶大毛多的老太婆| 91国内免费在线视频| 色偷偷av亚洲男人的天堂| 欧美另类99xxxxx| 中日韩美女免费视频网站在线观看| 国产精品成人品| 日韩视频免费观看| 国产精品成人久久久久| 欧美性jizz18性欧美| 5252色成人免费视频| 日韩视频免费中文字幕| 亚洲黄色有码视频| 97人人模人人爽人人喊中文字| 国产精品午夜一区二区欲梦| 欧美激情综合色综合啪啪五月| 欧美成aaa人片在线观看蜜臀| 久久综合免费视频| 日韩av网站在线| 在线午夜精品自拍| www.久久草.com| 91牛牛免费视频| 亚洲国产欧美一区二区三区久久| 欧美美女操人视频| 欧美成人黑人xx视频免费观看| 欧美尤物巨大精品爽| 91在线观看欧美日韩| 91精品国产91久久久久福利| 亚洲黄色成人网| 亚洲毛片在线免费观看| 久久久精品在线| 欧美成人合集magnet| 日韩亚洲精品电影| 欧美精品制服第一页| 亚洲一区二区三区在线免费观看| 国产精品久久久久久久9999| 不卡在线观看电视剧完整版| 欧美大片欧美激情性色a∨久久| 日韩av在线影院| 91免费版网站入口| 日韩免费看的电影电视剧大全| 久久成人精品一区二区三区| 成人春色激情网| 国产一区二区三区高清在线观看| 中文字幕亚洲综合久久| 成人免费网站在线观看| 久久视频免费在线播放| 久久九九全国免费精品观看| 日韩激情av在线播放| 亚洲国产一区二区三区四区| 国产精品久久久精品| 久久人人看视频| 青草青草久热精品视频在线观看| 欧美性猛交xxxx乱大交极品| 91九色视频在线| 日韩亚洲欧美中文高清在线| 久久久999精品| 91免费的视频在线播放| 日本精品一区二区三区在线| 欧美视频一区二区三区…| 成人性生交大片免费看小说| 国产精品综合不卡av| 777国产偷窥盗摄精品视频| 国产v综合v亚洲欧美久久| 欧美电影在线观看完整版| 国产亚洲精品成人av久久ww| 中文字幕国产亚洲| 亚洲精品影视在线观看| 日韩欧美亚洲范冰冰与中字| 91免费电影网站| 欧美成人三级视频网站| 欧美一级成年大片在线观看| 91精品久久久久久久久久久| 亚洲欧美另类自拍| 日本欧美精品在线| 成人免费午夜电影| 日韩福利在线播放| 91爱视频在线| 欧美性高潮床叫视频| 精品激情国产视频| 91在线视频九色| 成人黄色生活片| 国产精品视频久| 欧美人交a欧美精品| 国产美女直播视频一区| 18性欧美xxxⅹ性满足| 久久精品国产亚洲精品2020| 亚洲色图狂野欧美| 国产精品极品美女在线观看免费| 国产99久久精品一区二区永久免费| 成人免费看片视频| 成人激情综合网| 亚洲精品久久久久久久久久久久久| 中文字幕久精品免费视频| 性欧美暴力猛交69hd| 国产精品亚洲片夜色在线| 欧美极度另类性三渗透| 欧美午夜www高清视频| 92看片淫黄大片欧美看国产片| 欧美成人免费视频| 成人免费激情视频| 欧美国产中文字幕| 亚洲成色777777在线观看影院| 91久久精品美女高潮| 日本成人在线视频网址| 伊人伊成久久人综合网站| 中文字幕av一区中文字幕天堂| 日韩电影免费观看在线观看| 日韩电影免费观看在线| 日本精品一区二区三区在线| 亚州欧美日韩中文视频| 成人在线视频网| 国内精久久久久久久久久人| 国产又爽又黄的激情精品视频| 国产精品成人免费电影| 97精品欧美一区二区三区| 色噜噜狠狠狠综合曰曰曰88av| 正在播放国产一区| 上原亚衣av一区二区三区| 久久精品这里热有精品| 中文字幕日韩在线视频| 日韩在线视频中文字幕| 欧美中文在线视频| 久久久久五月天| 国产精品久久91|