android中ListView的用法


 

 地址:https://www.cnblogs.com/s-y-j/p/6548032.html

 

LisView介紹:

(一)、ListView 概念:

ListView是Android中最重要的組件之一,幾乎每個Android應用中都會使用ListView。它以垂直列表的方式列出所需的列表項。
java.lang.Object
   ↳ android.view.View
    ↳ android.view.ViewGroup
      ↳ android.widget.AdapterView
        ↳ android.widget.AbsListView
          ↳ android.widget.ListView

(二)、ListView的兩個職責:

  • 將數據填充到布局;
  • 處理用戶的選擇點擊等操作。

(三)、列表的顯示需要三個元素:

  • 1.ListVeiw:用來展示列表的View;
  • 2.適配器: 用來把數據映射到ListView上的中介;
  • 3.數據源: 具體的將被映射的字符串,圖片,或者基本組件。

(四)、什么是適配器?

適配器是一個連接數據和AdapterView的橋梁,通過它能有效地實現數據與AdapterView的分離設置,使AdapterView與數據的綁定更加簡便,修改更加方便。將數據源的數據適配到ListView中的常用適配器有:ArrayAdapter、SimpleAdapter 和 SimpleCursorAdapter。

  • ArrayAdapter最為簡單,只能展示一行字;
  • SimpleAdapter有最好的擴充性,可以自定義各種各樣的布局,除了文本外,還可以放ImageView(圖片)、Button(按鈕)、CheckBox(復選框)等等;
  • SimpleCursorAdapter可以認為是SimpleAdapter對數據庫的簡單結合,可以方便地把數據庫的內容以列表的形式展示出來。
  • 但是實際工作中,常用自定義適配器。即繼承於BaseAdapter的自定義適配器類。

(五)、ListView的常用UI屬性:

  • android:divider
  • android:dividerHeight
  • android:entries
  • android:footerDividersEnabled
  • android:headerDividersEnabled

創建ListView

(一)、ArrayAdapter實現單行文本ListView:

1、使用步驟。

  • 定義一個數組來存放ListView中item的內容;
  • 通過實現ArrayAdapter的構造方法創建一個ArrayAdapter對象;
  • 通過ListView的setAdapter()方法綁定ArrayAdapter。

ArrayAdapter有多個構造方法,最常用三個參數的那種。

  • 第一個參數:上下文對象;
  • 第二個參數:ListView的每一行(也就是item)的布局資源id;
  • 第三個參數:ListView的數據源。

2、使用系統自帶布局文件的不同效果:

  • A、android.R.layout.simple_list_item_1
  • B、android.R.layout.simple_list_item_checked
  • C、android.R.layout.simple_list_item_multiple_choice
  • D、android.R.layout.simple_list_item_single_choice

3、核心代碼:

String[] strArr = new String[] { "yuhongxing", "sunshengling", "chenyanzhang", "huangchao", "liupengfei" }; listView_main_userList = (ListView) findViewById(R.id.listView_main_userlist); ArrayAdapter<String> adapter = new ArrayAdapter<String>( MainActivity.this, android.R.layout.simple_list_item_1, strArr); listView_main_userList.setAdapter(adapter); 

ListView的監聽器與Spinner的監聽器的區別:

  • Spinner是:setOnItemSelectedListener
  • ListView是:setOnItemClickListener

這兩個監聽器是否可以互換使用呢?

  • 在Spinner中使用OnItemClickListener會異常。java.lang.RuntimeException: setOnItemClickListener cannot be used with a spinner。而如果在ListView中使用OnItemSelectedListener,則沒有反應,也就是說該監聽器不會被觸發執行;
  • OnItemSelectedListener 監聽器的回調方法中,parent.getSelectedItem()和parent.getItemAtPosition(position)都能返回object對象。而OnItemClickListener監聽器的回調方法中parent.getSelectedItem()只能返回null。

(二)、 SimpleAdapter 實現多行文本ListView:

1、使用步驟。

  • 定義一個集合來存放ListView中item的內容;
  • 定義一個item的布局文件;
  • 創建一個 SimpleAdapter 對象;
  • 通過ListView的setAdapter()方法綁定 SimpleAdapter  。

2、核心代碼:

public class MainActivity extends Activity { private static final String TAG = "MainActivity"; private ListView listView_main_news; private List<Map<String, String>> list = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView_main_news = (ListView) findViewById(R.id.listView_main_news); list = new ArrayList<Map<String, String>>(); for (int i = 0; i < 5; i++) { Map<String, String> map = new HashMap<String, String>(); map.put("username", "wangxiangjun_" + i); map.put("password", "123456_" + i); list.add(map); } Log.i(TAG, "==" + list.toString()); // 定義SimpleAdapter適配器。 // 使用SimpleAdapter來作為ListView的適配器,比ArrayAdapter能展現更復雜的布局效果。為了顯示較為復雜的ListView的item效果,需要寫一個xml布局文件,來設置ListView中每一個item的格式。 SimpleAdapter adapter = new SimpleAdapter(this, list, R.layout.item_listview_main, new String[] { "username", "password" }, new int[] { R.id.text_item_listview_username, R.id.text_item_listview_pwd }); listView_main_news.setAdapter(adapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } } 

(三)、SimpleAdapter實現多行文本且帶圖片ListView:

1、使用步驟。

  • 定義一個集合來存放ListView中item的內容;
  • 定義一個item的布局文件;
  • 創建一個 SimpleAdapter 對象;
  • 通過ListView的setAdapter()方法綁定 SimpleAdapter  。

2、核心代碼:

public class MainActivity extends Activity { private ListView listView_main_regmsg; private int[] imgIds = new int[] { R.drawable.pic01, R.drawable.pic02, R.drawable.pic03, R.drawable.pic04 }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView_main_regmsg = (ListView) findViewById(R.id.listView_main_regmsg); // 創建數據源 List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); for (int i = 0; i < imgIds.length; i++) { Map<String, Object> map = new HashMap<String, Object>(); map.put("username", "wanglu_" + i); map.put("pwd", "123456_" + i); map.put("imgId", imgIds[i]); list.add(map); } /** 常用的SimpleAdapter的構造方法有五個參數:  * @param context :表示上下文對象或者環境對象。  * @param data :表示數據源。往往采用List<Map<String, Object>>集合對象。  * @param resource :自定義的ListView中每個item的布局文件。用R.layout.文件名的形式來調用。  * @param from :其實是數據源中Map的key組成的一個String數組。  * @param to :表示數據源中Map的value要放置在item中的哪個控件位置上。其實就是自定義的item布局文件中每個控件的id。  * 通過R.id.id名字的形式來調用。  */ SimpleAdapter adapter = new SimpleAdapter(this, list, R.layout.item_listview_main, new String[] { "username", "pwd", "imgId" }, new int[] { R.id.text_item_listview_username, R.id.text_item_listview_pwd, R.id.imageView_item_listview_headpic }); // 給ListView設置適配器 listView_main_regmsg.setAdapter(adapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } } 

BaseAdapter自定義適配器實現ListView:

1、使用步驟

  • 定義一個集合來存放ListView中item的內容;

  • 定義一個item的布局文件;

  • 定義一個 繼承了BaseAdapter的子類MyAdapter,重寫未實現的方法;(定義ViewHolder,重寫getView()方法)

  • 創建一個內部類:MyAdapter extends BaseAdapter;

      - 實現未實現的方法:getCount() 、getItem()、 getItemId()、 getView(); - 定義內部類ViewHolder,將item布局文件中的控件都定義成屬性; - 構建一個布局填充器對象:LayoutInflater.from(context); - 調用布局填充器對象的inflate()方法填充item布局文件,將返回的view對象賦值給convertView; - 調用convertView對象的findViewById()獲取item布局中的控件,將控件對象賦值給ViewHolder中的屬性; - 給convertView對象設置標簽,也就是調用setTag()方法,將ViewHolder對象作為標簽貼在convertView對象上; - 從根據convertView的標簽,從convertView對象上取回ViewHolder對象。 
  • 通過ListView的setAdapter()方法綁定自定義的MyAdapter對象 。

2、核心代碼:

class MyAdapter extends BaseAdapter { private Context context = null; public MyAdapter(Context context) { this.context = context; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder mHolder; if (convertView == null) { mHolder = new ViewHolder(); LayoutInflater inflater = LayoutInflater.from(context); convertView = inflater.inflate(R.layout.item_listview_main_userlist, null, true); mHolder.text_item_listview_username = (TextView) convertView.findViewById(R.id.text_item_listview_username); mHolder.text_item_listview_email = (TextView) convertView.findViewById(R.id.text_item_listview_email); mHolder.imageView_item_listview_headpic = (ImageView) convertView.findViewById(R.id.imageView_item_listview_headpic); convertView.setTag(mHolder); } else { mHolder = (ViewHolder) convertView.getTag(); } String username = list.get(position).get("username").toString(); String email = list.get(position).get("email").toString(); int picId = Integer.parseInt(list.get(position).get("headpic").toString()); mHolder.text_item_listview_username.setText(username); mHolder.text_item_listview_email.setText(email); mHolder.imageView_item_listview_headpic.setImageResource(picId); return convertView; } class ViewHolder { private TextView text_item_listview_username; private TextView text_item_listview_email; private ImageView imageView_item_listview_headpic; } } 

(五)、convertView原理:

  • Adapter的作用就是ListView界面與數據之間的橋梁,當列表里的每一項顯示到頁面時,都會調用Adapter的getView方法返回一個View。

  • 如果在我們的列表有上千項時會是什么樣的?是不是會占用極大的系統資源?

  • Android中有個叫做Recycler的構件,下圖是他的工作原理:

      - 如果你有100個item,其中只有可見的項目存在內存中,其他的在Recycler中。 - ListView先請求一個type1視圖(getView),然后請求其他可見的item,convertView在getView中是空(null)的。 - 當item1滾出屏幕,並且一個新的item從屏幕底端上來時,ListView再請求一個type1視圖,convertView此時不是空值了,它的值是item1。你只需設定新的數據,然后返回convertView,不必重新創建一個視圖。 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM