編輯:關於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 List wananlist=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 List wananlist=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學生管理系統(附源碼)
本文實例講述了Android實現學生管理系統,分享給大家供大家參考。具體如下:(1)管理系統實現的功能主要是:學生、教師的注冊登錄,和選課,以及修改學生的成績等基本簡單的
android:ListView緩存機制及BaseAdapter的三重境界(逗比式,普通式,文藝式)
大家都知道listview的格式是一定的 而數據源確是多重多樣的 這時候 就需要一種適配器來把數據源轉換成listview要顯示的格式baseAdapter就誕生了。li
Android React Native自定義組件的流程
假設我們現在有這麼一個需求,就是自定義一個組件,該組件由一個小圖標和圖標的文字說明組成,並且帶有背景色,背景色可設置,寬度高度可設置。如下圖所示正是兩個這樣的組件所組成。
談談對Android View事件分發機制的理解
最近因為項目中用到類似一個LinearLayout中水平布局中,有一個TextView和Button,然後對該LinearLayout布局設置點擊事件,點擊TextVie