1.先寫遇到的問題: a.ListView只顯示一個item。 listview只顯示一個item,並且做了listview的點擊事件監聽列印 Bean 對象的屬性和哈希值,發現只有顯示的那個 Bean 對象有屬性值,其他item顯示的 Bean 對象屬性值為null,但是 Bean對象有唯一哈希值 ...
1.先寫遇到的問題:
a.ListView只顯示一個item。
listview只顯示一個item,並且做了listview的點擊事件監聽列印 Bean 對象的屬性和哈希值,發現只有顯示的那個 Bean 對象有屬性值,其他item顯示的 Bean 對象屬性值為null,但是 Bean對象有唯一哈希值,說明 Bean 對象成功創建了,但是是什麼原因導致其他屬性值為空的呢?經過檢查發現。每個對象是創建出來了,創建了第二個對象時,本來用第二個對象去引用屬性值,結果用了第一個去引用屬性值。
錯誤代碼:
1 Beauty beauty = new Beauty(); 2 beauty.age = "20"; 3 beauty.name = "西施"; 4 beauty.icon = mContext.getResources().getDrawable(R.drawable.a, null); 5 arraylist.add(beauty); 6 7 Beauty beauty1 = new Beauty(); 8 beauty.age = "18"; 9 beauty.name = "貂蟬"; 10 beauty.icon = mContext.getResources().getDrawable(R.drawable.b, null); 11 arraylist.add(beauty1);
正確為:
1 Beauty beauty = new Beauty(); 2 beauty.age = "20"; 3 beauty.name = "西施"; 4 beauty.icon = mContext.getResources().getDrawable(R.drawable.a, null); 5 arraylist.add(beauty); 6 7 Beauty beauty1 = new Beauty(); 8 beauty1.age = "18"; 9 beauty1.name = "貂蟬"; 10 beauty1.icon = mContext.getResources().getDrawable(R.drawable.b, null); 11 arraylist.add(beauty1);
b.只能顯示一頁,滑動lLIstView時,出現了ViewHolder空指針問題。
優化自定義adapter的getView()裡面的FindViewById()時,從view里獲取存儲的ViewHolder對象寫成了局部對象,當滑動listview再次獲取ViewHolder時,由於是局部對象,獲取不到報空指針。
1 public View getView(int position, View convertView, ViewGroup parent) { 2 3 View view = null; 4 ViewHolder viewholder = null; 5 6 if (convertView != null) { 7 view = convertView; 8 viewholder = (ViewHolder) view.getTag();//從view里獲取存儲的ViewHolder,寫成了局部對象。 9 } else { 10 LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 11 view = layoutInflater.inflate(item, parent, false); 12 13 //每次調用getView 都會執行FindViewById所以繼續優化。 14 viewholder = new ViewHolder(); 15 viewholder.viewHolderImageview= (ImageView) view.findViewById(R.id.IV_imageview); 16 viewholder.viewHolderTextview_1 = (TextView) view.findViewById(R.id.TV_age); 17 viewholder.viewHolderTextview_2 = (TextView) view.findViewById(R.id.TV_name); 18 view.setTag(viewholder);//將viewholder存儲在view中 19 } 20 }
2.自定義ListView的使用。
a.先把Context賦值為全局變數(後面會用到),在獲取XML中的listview的ID。
b.創建ArrayList和Bean對象,並用ArrayList封裝Bean對象。
c.創建Adapter,繼承BaseAdapter。
d.listview設置顯示的adapter。
e.設置listview的監聽事件,實現 AdapterView.OnItemClickListener。
1 protected void onCreate(Bundle savedInstanceState) { 2 super.onCreate(savedInstanceState); 3 setContentView(R.layout.activity_main); 4 mContext = this; 5 6 lv_1=(ListView)findViewById(R.id.lv_1); 7 ArrayList<Beauty> arraylist= BeautyUtlis.getAllBeauty(mContext); 8 9 10 MyAdapter myadapter=new MyAdapter(mContext,R.layout.item_1,arraylist); 11 lv_1.setAdapter(myadapter); 12 13 //點擊事件 14 lv_1.setOnItemClickListener(this); 15 16 }
b.通過ArrayList封裝Bean對象。
創建Bean。
1 public class Beauty { 2 public String age; 3 public String name; 4 public Drawable icon; 5 6 public Beauty() { 7 } 8 9 public Beauty(String age, String name, Drawable icon) { 10 this.age = age; 11 this.name = name; 12 this.icon = icon; 13 } 14 15 public String getName() { 16 return name; 17 } 18 19 public void setName(String name) { 20 this.name = name; 21 } 22 23 public String getAge() { 24 return age; 25 } 26 27 public void setAge(String age) { 28 this.age = age; 29 } 30 31 public Drawable getIcon() { 32 return icon; 33 } 34 35 public void setIcon(Drawable icon) { 36 this.icon = icon; 37 } 38 }
創建ArrayList集合用於封裝Bean。迴圈是為了顯示更多條目。
1 public class BeautyUtlis { 2 public static ArrayList<Beauty> getAllBeauty(Context mContext) { 4 5 ArrayList<Beauty> arraylist = new ArrayList<>(); 6 7 for(int i=0;i<3;i++) { 8 Beauty beauty = new Beauty(); 9 beauty.age = "20"; 10 beauty.name = "西施"; 11 beauty.icon = mContext.getResources().getDrawable(R.drawable.a, null); 12 arraylist.add(beauty); 13 14 Beauty beauty1 = new Beauty(); 15 beauty1.age = "18"; 16 beauty1.name = "貂蟬"; 17 beauty1.icon = mContext.getResources().getDrawable(R.drawable.b, null); 18 arraylist.add(beauty1); 19 20 21 Beauty beauty2 = new Beauty(); 22 beauty2.age = "22"; 23 beauty2.name = "楊貴妃"; 24 beauty2.icon = mContext.getResources().getDrawable(R.drawable.c, null); 25 arraylist.add(beauty2); 26 27 28 Beauty beauty3 = new Beauty(); 29 beauty3.age = "20"; 30 beauty3.name = "阿科"; 31 beauty3.icon = mContext.getResources().getDrawable(R.drawable.d, null); 32 arraylist.add(beauty3); 33 34 } 35 return arraylist; 36 } 37 }
c.創建Adapter,繼承BaseAdapter,通過自定義的構造方法傳Context,item ID,ArrayList封裝的Bean對象。
1 public class MyAdapter extends BaseAdapter { 2 3 4 private final Context mContext; 5 private final ArrayList<Beauty> arraylist; 6 private final int item; 7 8 9 public MyAdapter(Context mContext, int item_1, ArrayList<Beauty> araylist) { 10 this.mContext = mContext; 11 this.arraylist = araylist; 12 this.item = item_1; 13 } 14 15 //listview 顯示多少個條目 16 @Override 17 public int getCount() { 18 return arraylist.size(); 19 } 20 21 22 //根據postiion獲取條目對應的Bean數據 23 @Override 24 public Object getItem(int position) { 25 return arraylist.get(position); 26 } 27 28 //獲取position條目的ID 29 @Override 30 public long getItemId(int position) { 31 return position; 32 } 33 34 35 /** 36 * getview:告訴listview條目上顯示的內容;返回一個View對象作為條目上的內容展示,該方法返回什麼樣的view,Listview的條目上就顯示什麼樣的view。38 * //屏幕上每顯示一個條目getview方法就會被調用一次;
convertView:曾經使用過的view對象,可以被重覆使用,使用前要判斷。 39 **/ 40 @Override 41 public View getView(int position, View convertView, ViewGroup parent) { 42 43 View view = null; 44 ViewHolder viewholder = null; 45
//判斷convertView是否為空,為空創建新的View,不為空則復用被推出頁面外的view 46 if (convertView != null) { 47 view = convertView; 48 viewholder = (ViewHolder) view.getTag();//從view里獲取存儲的ViewHolder 49 } else { 50 LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 51 view = layoutInflater.inflate(item, parent, false); 52 53 //每次調用getView 都會執行FindViewById所以繼續優化。 54 viewholder = new ViewHolder(); 55 viewholder.viewHolderImageview= (ImageView) view.findViewById(R.id.IV_imageview); 56 viewholder.viewHolderTextview_1 = (TextView) view.findViewById(R.id.TV_age); 57 viewholder.viewHolderTextview_2 = (TextView) view.findViewById(R.id.TV_name); 58 view.setTag(viewholder);//將viewholder存儲在view中 59 } 60 //獲取Bean對象 61 62 Beauty beauty = arraylist.get(position); 63 64 viewholder.viewHolderImageview.setImageDrawable(beauty.getIcon()); 65 viewholder.viewHolderTextview_1.setText(beauty.getAge()); 66 viewholder.viewHolderTextview_2.setText(beauty.getName()); 80 return view; 81 } 82 83 //優化FindVIewById 84 class ViewHolder { 85 ImageView viewHolderImageview; 86 TextView viewHolderTextview_1; 87 TextView viewHolderTextview_2; 88 } 89 }
d.listview設置顯示的adapter。
1 lv_1.setAdapter(myadapter);
e.設置listview的監聽事件,實現 AdapterView.OnItemClickListener。簡單列印。
1 { 2 ......... 3 lv_1.setOnItemClickListener(this); 4 5 } 6 7 @Override 8 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 9 //獲取條目對應的對象 10 Beauty beauty = (Beauty) parent.getItemAtPosition(position);
11 Toast.makeText(mContext,"點擊了第"+position+"位置,"+"姓名叫:"+beauty.name+",年齡是:"+beauty.age,Toast.LENGTH_LONG).show(); 12 13 }