最近有这么一个GridView加载更多的需求,当然了,看到这个以后我首先想到是PullToRefresh,但是坑爹的我居然打不开!!!于是我开始找伟大的度娘了,一查后又发现还是不满足的需求,没办法,自己动手。由于之前有自己封装过加载更多的ListView,通过addFooterView来实现动画效果,可是GridView却没有这个属性啊,o(╥﹏╥)o作为一名程序猿,怎么能不想想办法呢,不然怎么在妹子面前秀呢~嘿嘿嘿 现在我们自己动手来封装,源码在最后~
先来看一下我的效果图:
一共有以下几个文件:
主要代码都在LoadMoreGridView.java 中,所以我们主要对它分析,这个为自定义View,继承RelativeLayout,先看看它的界面布局如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="@+id/auto_load_gv_base_sv"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/auto_load_gv_base_ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.spring.loaddemo.ScrollWithGridView
android:id="@+id/auto_load_gv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:horizontalSpacing="10dp"
android:numColumns="2"
android:verticalSpacing="10dp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/auto_load_gv_footer_ll"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:orientation="horizontal"
android:visibility="gone">
<ImageView
android:id="@+id/auto_load_gv_footer_image_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/progress_bar_drawable" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="@string/loading_more_data" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>
可以看到我在最外层套了一层ScrollView,因为我们自定义了底部的加载动画,为了保证动画布局能和GridView一起滚动,所以要套用ScrollView。如果你直接在中间使用GridView就会出现GridView显示不全,因为ScrollView和GridView都是滚动布局,会出现滚动冲突,解决办法呢就是重写OnMeasure方法,这里不多讨论。
接下来就是关键代码了,我们监听ScrollView的Touch方法,当用户手指抬起时,就去判断是否已经到达底部,
baseSv.setOnTouchListener(new OnTouchListener() {
private int lastY = 0;
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
lastY = baseSv.getScrollY();
if (lastY == (baseLl.getHeight() - baseSv.getHeight()) && !isLoadMore && isEnable) {
footerLl.setVisibility(View.VISIBLE);
isLoadMore = true;
new Handler().post(new Runnable() {
@Override
public void run() {
//ScrollView滚动到底部
baseSv.fullScroll(ScrollView.FOCUS_DOWN);
}
});
if (onLoadGridListener != null)
onLoadGridListener.onLoadMore();
}
}
return false;
}
});
这里需要注意了,baseSv.getScrollY()这个表示除了屏幕之外的高度,也就是不可见高度,
baseLl.getHeight()是当前总高度,
baseSv.getHeight()是屏幕当前显示出来的高度,
所以当两者的差值等于不可见区域的高度的时候,表示已经到达底部了,就可以进行加载更多数据的操作
最后放上LoadMoreGridView.java全部代码供大家参考,
public class LoadMoreGridView extends RelativeLayout {
public ScrollView baseSv;
private LinearLayout baseLl, footerLl;
private ScrollWithGridView dataGv;
private BaseAdapter dataAdapter;
private boolean isLoadMore;
private boolean isEnable = true;
public LoadMoreGridView(Context context) {
super(context);
init();
}
public LoadMoreGridView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public LoadMoreGridView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
View view = LayoutInflater.from(getContext()).inflate(R.layout.auto_load_grid_view_layout, this);
baseSv = view.findViewById(R.id.auto_load_gv_base_sv);
baseLl = view.findViewById(R.id.auto_load_gv_base_ll);
dataGv = view.findViewById(R.id.auto_load_gv);
footerLl = view.findViewById(R.id.auto_load_gv_footer_ll);
ImageView animatorIv = view.findViewById(R.id.auto_load_gv_footer_image_iv);
AnimationDrawable animationDrawable = (AnimationDrawable) animatorIv.getDrawable();
animationDrawable.start();
dataGv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (onLoadGridListener != null)
onLoadGridListener.onItemClick(position);
}
});
baseSv.setOnTouchListener(new OnTouchListener() {
private int lastY = 0;
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
lastY = baseSv.getScrollY();
if (lastY == (baseLl.getHeight() - baseSv.getHeight()) && !isLoadMore && isEnable) {
footerLl.setVisibility(View.VISIBLE);
isLoadMore = true;
new Handler().post(new Runnable() {
@Override
public void run() {
//ScrollView滚动到底部
baseSv.fullScroll(ScrollView.FOCUS_DOWN);
}
});
if (onLoadGridListener != null)
onLoadGridListener.onLoadMore();
}
}
return false;
}
});
}
/**
* 设置适配器
*/
public void setAdapter(BaseAdapter baseAdapter) {
dataAdapter = baseAdapter;
dataGv.setAdapter(dataAdapter);
}
/**
* 加载数据完成调用
*/
public void loadDataComplete() {
isLoadMore = false;
footerLl.setVisibility(View.GONE);
dataAdapter.notifyDataSetChanged();
new Handler().post(new Runnable() {
@Override
public void run() {
//ScrollView滚动到底部
baseSv.fullScroll(ScrollView.FOCUS_DOWN);
}
});
}
public void setEnable(boolean enable) {
isEnable = enable;
}
private OnLoadGridListener onLoadGridListener;
public void setOnLoadGridListener(OnLoadGridListener onLoadGridListener) {
this.onLoadGridListener = onLoadGridListener;
}
public interface OnLoadGridListener {
void onItemClick(int position);
void onLoadMore();
}
}
源码在这里
就是以上这些了,其实很简单,一定要去尝试,这样才能进步,有兴趣的老铁加我我们一起进步啊。我们交流交流人生,交流交流感想呀~ 嘿嘿嘿 *✧⁺˚⁺ପ(๑・ω・)੭ु⁾⁾