这是总体实现效果。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延时两秒加载只是为了实验效果。这是在慕课网上学习时的笔记,你们要想更加深刻地了解相关知识,请移步慕课网吧,感受很实用!