編輯:關於Android編程
1.定制實體類,加入要填入list的變量,設置好set,get方法。
2.自定義item布局,根據要填入的數據。
3.自定義適配器類,繼承ArrayAdapter。
4.MainActivity中給listview綁定adapter並·添加數據
實體類:
public class Wanwan { private String name; private int imgid; public Wanwan(String name,int imgid){ this.name=name; this.imgid=imgid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getImgid() { return imgid; } public void setImgid(int imgid) { this.imgid = imgid; } }
自定義adpater類
public class WanwanAdapter extends ArrayAdapter{ private int resourceID; public WanwanAdapter(Context context, int textviewresourceid, List object){ super(context,textviewresourceid,object); resourceID=textviewresourceid; } @Override public View getView(int position, View convertView, ViewGroup parent) { Wanwan wanwan=getItem(position);//獲取當前項的wanwan實例 View view= LayoutInflater.from(getContext()).inflate(resourceID,null);//獲取view實例 ImageView imgview=(ImageView) view.findViewById(R.id.img_wanwan); TextView textView=(TextView) view.findViewById(R.id.text_wanwan); imgview.setImageResource(wanwan.getImgid()); textView.setText(wanwan.getName()); return view; } }
布局文件:item_xml
MainActivity
public class MainActivity extends AppCompatActivity { private Listwananlist=new ArrayList (); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iniWanwan();//列表添加數據 WanwanAdapter wanwanAdapter=new WanwanAdapter(MainActivity.this,R.layout.wanwan_item,wananlist); ListView listView=(ListView) findViewById(R.id.listview); listView.setAdapter(wanwanAdapter); } private void iniWanwan(){ for(int i=0;i<100;i++){ wananlist.add(new Wanwan("wanwan", R.mipmap.ic_launcher)); } } }
運行:
自定義的adapter,會要重寫getView方法,在getView方法產生給用戶item的視圖以及數據。
這裡有一個優化的地方,就是重用view,這樣減少內存消耗,同時加快item加載速度。
convert參數用於將之前加載好的緩存,重用了,很大程度上的減少了內存的消耗。通過判斷convertView是否為null,是的話就需要產生一個視圖出來,然後給這個視圖數據,最後將這個視圖返回給底層,呈獻給用戶。
特點:如果當前的convertView為null,則通過LayoutInflat產生一個view。
修改adpater代碼:
@Override public View getView(int position, View convertView, ViewGroup parent) { Wanwan wanwan = getItem(position);//獲取當前項的wanwan實例 View view; if (convertView == null) { view = LayoutInflater.from(getContext()).inflate(resourceID, null);//獲取view實例 } else { view = convertView; } ImageView imgview = (ImageView) view.findViewById(R.id.img_wanwan); TextView textView = (TextView) view.findViewById(R.id.text_wanwan); imgview.setImageResource(wanwan.getImgid()); textView.setText(wanwan.getName()); return view; }
上面的寫法會有一個缺點,就是每次在getVIew的時候,都需要重新的findViewById,重新找到控件,然後進行控件的賦值以及事件相應設置。這樣其實在做重復的事情,因為的geiview中,其實包含有這些控件,而且這些控件的id還都是一樣的,也就是其實只要在view中findViewById一次,後面無需要每次都要findViewById了。
所以我們要自定義一個類 ViewHolder
代碼修改:
@Override public View getView(int position, View convertView, ViewGroup parent) { Wanwan wanwan = getItem(position);//獲取當前項的wanwan實例 View view; ViewHolder viewHolder; if (convertView == null) { view = LayoutInflater.from(getContext()).inflate(resourceID, null);//獲取view實例 viewHolder=new ViewHolder(); viewHolder.imageView=(ImageView) view.findViewById(R.id.img_wanwan);//實例化變量 viewHolder.textView=(TextView) view.findViewById(R.id.text_wanwan); view.setTag(viewHolder);//將Viewholder存儲在view中 } else { view = convertView; viewHolder=(ViewHolder) view.getTag();//重新獲取viewholder } //ImageView imgview = (ImageView) view.findViewById(R.id.img_wanwan); //TextView textView = (TextView) view.findViewById(R.id.text_wanwan); viewHolder.imageView.setImageResource(wanwan.getImgid()); viewHolder.textView.setText(wanwan.getName()); return view; } class ViewHolder{ ImageView imageView; TextView textView; }
PS:以上兩種優化方式參考《第一行代碼》
1.設置ViewHolder為static,也就是靜態的,靜態類只會在第一次加載時會耗費比較長時間,但是後面就可以很好幫助加載,同時保證了內存中只有一個ViewHolder,節省了內存的開銷。
static class ViewHolder{ ImageView imageView; TextView textView; }
如果有很多item並且需要從網絡下載數據的話。一次性全加載不僅浪費時間而且消耗用戶流量。
其一:假如網絡情況很好,我們使用的手機也許能夠一下子加載完所有新聞數據,然後顯示在ListView中,用戶可能感覺還好,假如說在網絡不太順暢的情況下,用戶加載完所有網絡的數據,可能這個list是1000條新聞,那麼用戶可能需要面對一個空白的Activity好幾分鐘,這個顯然是不合適的
其二:我們知道Android虛擬機給每個應用分配的運行時內存是一定的,一般性能不太好的機器只有16M,好一點的可能也就是64M的樣子,假如說我們現在要浏覽的新聞總數為一萬條,即便是網絡很好的情況下,我們可以很快的加載完畢,但是多數情況下也會出現內存溢出從而導致應用崩潰的情況。
為此搜索了一下:
原理就是
listview.setOnScrollListener(new scrollListener());
判斷滑動的item個數,到一定時候就繼續加載。
實現代碼:
footer.xml
網絡服務類:
public class DataService { /** * * @param startposition * :從第startposition條數據開始加載 * @param pagesize * :每頁顯示數量 * @return:服務器返回數組 */ public static List<string> getData(int startposition, int pagesize) { List<string> list = new ArrayList<string>(); for (int i = startposition; i <startposition+ i="" return="" pre="">
主要代碼;
public class MainActivity extends AppCompatActivity { // private Listwananlist=new ArrayList (); private ListView listview; private List data = new ArrayList (); private ArrayAdapter adapter; private LayoutInflater inflater; private View footer;// 頁腳-正在加載中..... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // iniWanwan();//列表添加數據 // WanwanAdapter wanwanAdapter=new WanwanAdapter(MainActivity.this,R.layout.wanwan_item,wananlist); // ListView listView=(ListView) findViewById(R.id.listview); // listView.setAdapter(wanwanAdapter); inflater = getLayoutInflater(); footer = inflater.inflate(R.layout.footer, null); listview = (ListView) findViewById(R.id.listview); listview.setOnScrollListener(new scrollListener()); data.addAll(DataService.getData(0, 20)); adapter = new ArrayAdapter (this, android.R.layout.simple_list_item_1, data); /* 在適配器之前加頁腳,這樣適配器會重新被封裝成 '有頁腳的適配器' */ listview.addFooterView(footer); listview.setAdapter(adapter); listview.removeFooterView(footer); } /** * listview滾動監聽類 * */ public class scrollListener implements AbsListView.OnScrollListener { int pagesize = 20;// 每頁顯示條目 int maxpage = 5;// 最多頁數 int currentpage;// 當前頁 int nextpage; boolean finish_load = true;// 加載是否完成,默認完成 /** * 監聽滾動狀態改變:1-手指正在滑動 2-手指停止滑動 3-組件停止滾動 */ public void onScrollStateChanged(AbsListView view, int scrollState) { } /** * firstVisibleItem:第一個可見item visibleItemCount:可見item數量 * totalItemCount:總條目數量 */ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { final int total = totalItemCount; /* 如果滾動到最後一條 */ if (listview.getLastVisiblePosition() + 1 == totalItemCount) { if (totalItemCount > 0) { /* 獲取當前頁 */ currentpage = totalItemCount % pagesize == 0 ? totalItemCount / pagesize : totalItemCount / pagesize + 1; nextpage = currentpage + 1; /* * 如果當前頁小於規定的最大頁數,並且加載完成(不斷滾動就會不斷執行onScroll方法, * 所以用finish_load鎖定翻頁) */ if (nextpage <= maxpage && finish_load) { finish_load = false; /* 每次翻頁前添加頁腳 */ listview.addFooterView(footer); /* 創建子線程,執行翻頁 */ new Thread(new Runnable() { public void run() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } List l = DataService.getData(total, pagesize); handle.sendMessage(handle.obtainMessage(123, l)); } }).start(); } } } } /* 通過handle和主線程通訊,主線程接收消息更新UI */ Handler handle = new Handler() { public void handleMessage(Message msg) { data.addAll((List ) msg.obj); adapter.notifyDataSetChanged(); /* 頁腳顯示完就刪掉 */ if (listview.getFooterViewsCount() > 0) listview.removeFooterView(footer); finish_load = true; } }; } // private void iniWanwan(){ // for(int i=0;i<100;i++){ // wananlist.add(new Wanwan("wanwan", R.mipmap.ic_launcher)); // } // } }
實現效果;
DEMO下載:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD48cD48YSBkYXRhLWNrZS1zYXZlZC1ocmVmPQ=="https://github.com/HuRuWo/android/tree/master/listview-youhua" href="https://github.com/HuRuWo/android/tree/master/listview-youhua">ListView優化 AandroidStudio2.1.2打開
本文實例講述了Android實現學生管理系統,分享給大家供大家參考。具體如下:(1)管理系統實現的功能主要是:學生、教師的注冊登錄,和選課,以及修改學生的成績等基本簡單的
大家都知道listview的格式是一定的 而數據源確是多重多樣的 這時候 就需要一種適配器來把數據源轉換成listview要顯示的格式baseAdapter就誕生了。li
假設我們現在有這麼一個需求,就是自定義一個組件,該組件由一個小圖標和圖標的文字說明組成,並且帶有背景色,背景色可設置,寬度高度可設置。如下圖所示正是兩個這樣的組件所組成。
最近因為項目中用到類似一個LinearLayout中水平布局中,有一個TextView和Button,然後對該LinearLayout布局設置點擊事件,點擊TextVie