Android實現listview的上拉加載更多
實現邏輯:
最終效果
1、創建自定義ListView,並且監聽其滾動的事件
1.1 類屬性的聲明
private int firstVisibleItem; // 表示當前listview是否在第一行
private View v; // 提示的加載佈局
private IReflashListener iReflashListener; // 實現刷新的內部接口
1.2 類初始化public MyListView(Context context) {
super(context, null);
init();
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setOnScrollListener(this);
}
1.3 對其OnScrollListener的方法實現@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
/**
* firstVisibleItem==0: 表示在第一個Item項
* scrollState!=0: 該listview正在移動
*/
if (firstVisibleItem == 0 && scrollState != 0) {
// 進行添加頂部佈局
v = LayoutInflater.from(getContext()).inflate(R.layout.item_top_layout, null);
this.addHeaderView(v);
if (iReflashListener != null)
iReflashListener.onReflash(); // 加載數據
} else {
if (v != null) {
// 隱藏頂部佈局
this.removeHeaderView(v);
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
this.firstVisibleItem = firstVisibleItem;
}
動態加載數據的操作放在onScrollStateChanged中的原因:只有用戶在滾動該listview的時候才能進行加載數據。2、自定義ListView的類中應實現一個內部接口,用來實現加載更多數據的邏輯
3、動態佈局的創建
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/seekBar"
style="@android:style/Widget.ProgressBar.Small" />
<TextView android:text="下拉加載"
android:layout_marginLeft="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
將該組件放在任意的layout中即可。4、使用該listview,且在引用類中實現加載更多數據的內部接口
<com.example.administrator.listviewautoload.MyListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
此方式爲使用自定義組件。5、adapter實現
package com.example.administrator.listviewautoload;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.List;
/**
* 進行數據與listview的綁定
*/
public class MyAdapter extends BaseAdapter {
private List<String> lists; // item總數據
private Context context; // 上下文(此處級別因爲activity)
private ViewHolder viewHolder;
private boolean flag; // 是否可以加載更多
public MyAdapter(List<String> lists, Context context) {
this.lists = lists;
this.context = context;
}
@Override
public int getCount() {
return lists.size();
}
@Override
public Object getItem(int position) {
return lists.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
/**
* 做出一定的listview優化
*/
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.item_layout, null);
viewHolder = new ViewHolder();
viewHolder.textView = (TextView) convertView.findViewById(R.id.text);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.textView.setText(lists.get(position));
return convertView;
}
class ViewHolder {
TextView textView;
}
}
這個adapter還是非常簡單的,內部定義了一個ViewHolder類。 包含了一個listview item的組件。使用此種getView方法方式可以最優化的幫組我們節省Android內存(建議使用)。
最後一步,那就是動態的添加數據
public class MainActivity extends Activity implements MyListView.IReflashListener
我們實現它的方法,在該方法中就可以調用自己特有的加載數據方法,只要放入到adapter的數據源中,調用adapte的notifyDataSetChanged即可
@Override
public void onReflash() {
Toast.makeText(this, "MainActivity onReflash", Toast.LENGTH_SHORT).show();
/**
* 開始加載刷新的數據(此爲模擬動態加載出來的數據)
*/
for (int i = 0; i < 2; i++) {
lists.add(Integer.valueOf(lists.get(lists.size() - 1)) + 1 + "");
}
adapter.notifyDataSetChanged();
}
至此,我們的功能就基本實現了,有木有特別簡單。 因仔細注意MainActivity的init方法中listview.setiReflashListener(this) ;