這是總體實現效果。java
(1)實現一個簡單的自定義ListView;(2)給這個ListView添加一個底部進度提示;(3)實現ListView滾動監聽。android
(1)項目結構app
其中ApkInfo.java是ListView Item的一個實體類,描述了Item裏相關的信息。這個就很少說了,主要是get和set相關方法;ide
(2)看下MyAdapter.java的實現:佈局
package com.example.listviewdemo; import java.util.ArrayList; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; /** * listView適配器 * * */ public class MyAdapter extends BaseAdapter { ArrayList<ApkInfo> apkInfos_list; LayoutInflater inflater; public MyAdapter(ArrayList<ApkInfo> apkInfos_list, Context context) { this.apkInfos_list = apkInfos_list; this.inflater = LayoutInflater.from(context); } public void onDataChange(ArrayList<ApkInfo> apkInfos_list) { this.apkInfos_list = apkInfos_list; this.notifyDataSetChanged(); } @Override public int getCount() { return apkInfos_list.size(); } @Override public Object getItem(int position) { return apkInfos_list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ApkInfo apkInfo = apkInfos_list.get(position); ViewHolder holder; if (convertView == null) { holder = new ViewHolder(); convertView = inflater.inflate(R.layout.item_layout, null); holder.name_tv = (TextView) convertView.findViewById(R.id.item3_apkname); holder.des_tv = (TextView) convertView.findViewById(R.id.item3_apkdes); holder.info_tv = (TextView) convertView.findViewById(R.id.item3_apkinfo); holder.item_iv = (ImageView) convertView.findViewById(R.id.item3_apkiv); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.name_tv.setText(apkInfo.getName()); holder.des_tv.setText(apkInfo.getDes()); holder.info_tv.setText(apkInfo.getInfo()); holder.item_iv.setImageResource(apkInfo.getImage()); return convertView; } class ViewHolder { TextView name_tv; TextView des_tv; TextView info_tv; ImageView item_iv; } }
這個Adapter是AdapterView視圖與數據之間的橋樑,Adapter提供對數據的訪問,也負責爲每一項數據產生一個對應的View。 post
看看,其中ListView裏的Item實現效果:學習
配置文件item_layout.xml的實現:測試
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="60dip" android:background="@drawable/app_item_bg" android:gravity="center_vertical" android:orientation="horizontal" > <ImageView android:id="@+id/item3_apkiv" android:layout_width="50dip" android:layout_height="50dip" android:layout_marginLeft="10dip" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dip" android:layout_weight="1" android:orientation="vertical" > <TextView android:id="@+id/item3_apkname" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="應用程序名字" android:textColor="@color/black" android:textSize="18dip" /> <TextView android:id="@+id/item3_apkinfo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dip" android:text="應用程序信息" android:textSize="14dip" /> </LinearLayout> <Button android:id="@+id/item3_dlbtn" android:layout_width="60dip" android:layout_height="30dip" android:layout_marginRight="10dip" android:background="@drawable/dlbtn_selector" android:text="卸載" /> </LinearLayout> <TextView android:id="@+id/item3_apkdes" android:layout_width="fill_parent" android:layout_height="30dip" android:layout_marginLeft="5dip" android:layout_marginRight="5dip" android:gravity="center_vertical" android:text="應用程序描述" android:textSize="14dip" /> </LinearLayout>
(3)自定義ListView實現this
package com.example.listviewdemo; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ListView; public class LoadListView extends ListView implements OnScrollListener { View footer;// 底部佈局 int totalItemCount;// ListView加載數據總量 int lastVisibaleItem;// 底部顯示的數據下標 boolean isLoading;// 是否在加載 OnLoaderListener loaderListener;// 加載監聽 public LoadListView(Context context) { super(context); initView(context); } public LoadListView(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } public LoadListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initView(context); } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { /** * scrollState = SCROLL_STATE_TOUCH_SCROLL(1) 正在滾動 ; scrollState = * SCROLL_STATE_FLING(2) 手指作了拋的動做(手指離開屏幕前,用力滑了一下); scrollState = * SCROLL_STATE_IDLE(0) 中止滾動 ; 當滾動到最後一行,且中止滾動,加載數據; */ if (totalItemCount == lastVisibaleItem && scrollState == SCROLL_STATE_IDLE) { if (!isLoading) { isLoading = true; footer.findViewById(R.id.load_layout).setVisibility(View.VISIBLE); loaderListener.onLoad();// 加載更多 } } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { /** * 滾動一直回調直到中止滾動時才中止回調,單擊時回調一次; 列表到達結尾以前,咱們要加載數據模塊; * firstVisibleItem表示當前屏幕顯示的第一個listItem在整個listView裏的位置(下標從0開始); * visibleItemCount表示當前屏幕可見的listItem(部分顯示的listItem也算)總數; * totalItemCount表示listView裏listItem總數。 */ this.lastVisibaleItem = firstVisibleItem + visibleItemCount; this.totalItemCount = totalItemCount; } /** * 底部進度調加載到listview * * @param context */ private void initView(Context context) { LayoutInflater inflater = LayoutInflater.from(context); footer = inflater.inflate(R.layout.footer_layout, null); footer.findViewById(R.id.load_layout).setVisibility(View.GONE); this.addFooterView(footer);// 加到底部 this.setOnScrollListener(this);// 監聽滾動到底部 } /** * 加載完畢 */ public void loadComplete() { isLoading = false; footer.findViewById(R.id.load_layout).setVisibility(View.GONE); } public void setLoaderListener(OnLoaderListener loaderListener) { this.loaderListener = loaderListener; } // 加載更多回調接口 public interface OnLoaderListener { public void onLoad(); } }
添加底部加載進度條spa
footer_layout.xml實現以下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/load_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal" android:paddingBottom="10dip" android:paddingTop="10dip" > <ProgressBar style="?android:attr/progressBarStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="10條載入中..." /> </LinearLayout> </LinearLayout>
(4)MainActivity.java裏的實現:
package com.example.listviewdemo; import java.util.ArrayList; import com.example.listviewdemo.LoadListView.OnLoaderListener; import android.os.Bundle; import android.os.Handler; import android.app.Activity; public class MainActivity extends Activity implements OnLoaderListener { ArrayList<ApkInfo> apkInfos_list = new ArrayList<ApkInfo>(); MyAdapter adapter; LoadListView listview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getData(); showListView(apkInfos_list); } private void showListView(ArrayList<ApkInfo> apkInfos_list) { if (adapter == null) { listview = (LoadListView) findViewById(R.id.listview); listview.setLoaderListener(this); adapter = new MyAdapter(apkInfos_list, this); listview.setAdapter(adapter); } else { adapter.onDataChange(apkInfos_list); } } private void getData() { for (int i = 0; i < 10; i++) { ApkInfo apkInfo = new ApkInfo(); apkInfo.setName("測試程序I"); apkInfo.setInfo("50w用戶"); apkInfo.setDes("這是一個神奇的應用!"); apkInfo.setImage(R.drawable.ic_launcher); apkInfos_list.add(apkInfo); } } private void loadData() { for (int i = 0; i < 10; i++) { ApkInfo apkInfo = new ApkInfo(); apkInfo.setName("測試程序II"); apkInfo.setInfo("50w用戶"); apkInfo.setDes("這是一個更加神奇的應用!"); apkInfo.setImage(R.drawable.test_icon); apkInfos_list.add(apkInfo); } } @Override public void onLoad() { Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { // 獲取更多數據 loadData(); // 更新listview顯示; showListView(apkInfos_list); // 通知listview加載完畢 listview.loadComplete(); } }, 2000); } }
activity_main.xml配置文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <com.example.listviewdemo.LoadListView android:id="@+id/listview" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/white" android:cacheColorHint="#00000000" android:dividerHeight="5dip" > </com.example.listviewdemo.LoadListView> </RelativeLayout>
到這裏整個實現就算完成了,這裏使用了handler.postDelayed延時兩秒加載只是爲了實驗效果。這是在慕課網上學習時的筆記,你們要想更加深刻地瞭解相關知識,請移步慕課網吧,感受很實用!