本文主要是介绍继承SwipeRefreshLayout实现上拉加载更多功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Android 的SwipeRefreshLayout是一个比较好的下拉刷新控件,现在已经有越来越多的企业开始使用这个控件了。但是遗憾的是这个控件并没有上拉加载更多的功能,所以自己抽空,根据网上已有的例子,自己写了一个。
首先必须要做的是创建一个类继承SwipeRefreshLayout,这里我把它命名为:XZHRefreshLayout
/*** TODO:Created by XuZhenhao on 2016/12/6.*/public class XZHRefreshLayout extends SwipeRefreshLayout {private boolean isLoading = false;private ListView mListView;private View mListFooter;private OnLoadListener mLoadListener;public XZHRefreshLayout(Context context) {this(context, null);}public XZHRefreshLayout(Context context, AttributeSet attrs) {super(context, attrs);//这里初始化FooterView,并给里面的一个菊花图片添加一个动画mListFooter = LayoutInflater.from(context).inflate(R.layout.list_footer, null, false);Animation anim = AnimationUtils.loadAnimation(context, R.anim.img_animation);LinearInterpolator lin = new LinearInterpolator();anim.setInterpolator(lin);mListFooter.findViewById(R.id.progress_iv).startAnimation(anim);}//这里set回调函数public void setOnLoadListener(OnLoadListener loadListener) {this.mLoadListener = loadListener;}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);//这里判断ViewGroup里面是不是有个子View,并且第一个是不是ListViewint childCount = getChildCount();if (childCount > 0) {View child = getChildAt(0);if (child instanceof ListView) {mListView = (ListView) child;}}}//用于添加和移除FooterViewpublic void setLoad(boolean isLoad) {isLoading = isLoad;if (isLoad) {mListView.addFooterView(mListFooter);} else {mListView.removeFooterView(mListFooter);}}//记录手指触摸屏幕的上一个Y坐标值private float lastY;@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {int action = ev.getAction();float currentY = ev.getY();switch (action) {case MotionEvent.ACTION_DOWN:break;case MotionEvent.ACTION_MOVE://如果当前的Y坐标小于上一个Y坐标的值说明是向上滑动,,并且子ListView不为null,并且没有FooterViewif (currentY < lastY && mListView != null && mListView.getFooterViewsCount() == 0) {//如果当前listView的最后一个item的position等于可见范围内最后一个item的position,
//并且屏幕中的item总数小于11,当前没有加载FooterViewif (mListView.getAdapter().getCount() - 1 == mListView.getLastVisiblePosition()
&& mListView.getChildCount() >= 11 && !isLoading) {setLoad(true);//添加FooterViewmLoadListener.onLoad();//执行回调函数}}break;}lastY = currentY;return super.onInterceptTouchEvent(ev);}//回调public interface OnLoadListener {void onLoad();}
}
最核心的代码已经实现了,网上有很多Demo是在onScroll方法中实现的,但是我发现在滑动到底部时,onScroll方法一直在执行,那么这样的话会导致我们一直的执行回调函数,因为这里的回调函数是用来加载数据的,从而会导致不停地获取数据,不停的添加和移除FooterView,并且导致ListView的点击事件失效,所以我将其移到了onInterceptTouchEvent(MotionEvent ev)里面去执行。
下面上Activity的代码:
public class MessageListActivity extends AppCompatActivity {private Toolbar SMSToolbar;private XZHRefreshLayout refreshLayout;private ListView lvSMSList;private MessageListAdapter adapter;private List smsList;private MRLTDao dao;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_message_list);initData();initView();}/*** TODO: 初始化控件*/private void initView() {SMSToolbar = (Toolbar) findViewById(R.id.sms_list_toolbar);SMSToolbar.setTitle("短信列表");SMSToolbar.setNavigationIcon(ContextCompat.getDrawable(this, R.mipmap.btn_back));SMSToolbar.setNavigationOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {onBackPressed();}});//实现我们自定义的下拉刷新控件refreshLayout = (XZHRefreshLayout) findViewById(R.id.refresh_sms_ly);refreshLayout.setColorSchemeColors(ContextCompat.getColor(this, android.R.color.holo_blue_bright),ContextCompat.getColor(this, android.R.color.holo_green_light),ContextCompat.getColor(this, android.R.color.holo_orange_light),ContextCompat.getColor(this, android.R.color.holo_red_light));//监听下拉刷新事件refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {@Overridepublic void onRefresh() {new Handler().postDelayed(new Runnable() {@Overridepublic void run() {smsList.clear();smsList.addAll(dao.querySMSALL(0));adapter.notifyDataSetChanged();refreshLayout.setRefreshing(false);}}, 1500);}});//我们写的回调函数,在里面做查找数据的方法refreshLayout.setOnLoadListener(new XZHRefreshLayout.OnLoadListener() {@Overridepublic void onLoad() {new Handler().postDelayed(new Runnable() {@Overridepublic void run() {//我这里是用了一个Sqlite,大家可以根据自己的实际应用在这里做数据的查询,相信大家一般都不可能会有问题。if (dao != null && smsList != null) {List<SmsEntity> datas = dao.querySMSALL(smsList.size());if (datas.size() > 0) {//如果查询到有数据,就添加到数据源里面去。smsList.addAll(datas);adapter.notifyDataSetChanged();}else{//如果没有数据,就弹一个吐司MyToast.show(MessageListActivity.this,"没有更多数据!");}}refreshLayout.setLoad(false);}}, 1000);}});lvSMSList = (ListView) findViewById(R.id.sms_list_lv);adapter = new MessageListAdapter(this, smsList);lvSMSList.setAdapter(adapter);lvSMSList.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {SmsEntity entity = (SmsEntity) adapter.getItem(position);showSMSDialog(entity);}});}/*** TODO: 初始化数据*/private void initData() {if (smsList == null)smsList = new ArrayList<>();if (dao == null)dao = new MRLTDao(getApplicationContext());smsList = dao.querySMSALL(0);}@Overrideprotected void onDestroy() {super.onDestroy();}//点击item弹一个Dialog,显示当前Item的内容private void showSMSDialog(SmsEntity entity) {if (entity == null) {return;}final AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setTitle(entity.getSendcode());builder.setMessage("接收时间:"+entity.getCreate_time()+"\n"+entity.getContent());builder.setPositiveButton("知道了", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.cancel();}});builder.create().show();}
}
总的来说Activity里面完全没有啥技术含量,只是有可能代码写的其丑无比。
下面上XML:
1.Activity的XML文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/activity_message_list"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.yihuacomputer.sdmrlt.ui.MessageListActivity"><android.support.v7.widget.Toolbarandroid:id="@+id/sms_list_toolbar"android:layout_width="match_parent"android:layout_height="50dp"android:background="@color/cpb_blue"app:titleTextColor="@color/cpb_white" />
<com.yihuacomputer.sdmrlt.ui.view.XZHRefreshLayoutandroid:id="@+id/refresh_sms_ly"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_below="@+id/sms_list_toolbar"><ListViewandroid:id="@+id/sms_list_lv"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingLeft="12dp"android:paddingRight="12dp"android:scrollbars="none"></ListView>
</com.yihuacomputer.sdmrlt.ui.view.XZHRefreshLayout></RelativeLayout>
2.ListView的Item的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:gravity="center_vertical"android:orientation="horizontal"android:paddingBottom="4dp"android:paddingTop="4dp"android:weightSum="10"><ImageViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:src="@mipmap/will" /><RelativeLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="9"android:layout_marginLeft="4dp"><TextViewandroid:id="@+id/item_sms_rvd_tv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="@color/colorPrimaryDark"android:maxLength="15"android:textSize="16sp" /><TextViewandroid:id="@+id/item_sms_time_tv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="@color/colorPrimaryDark"android:textSize="16sp"android:layout_alignParentTop="true"android:layout_alignParentEnd="true" /><TextViewandroid:id="@+id/item_sms_content_tv"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@+id/item_sms_rvd_tv"android:maxLines="1"android:textColor="@color/menu_fragment_background"android:textSize="14sp" /></RelativeLayout>
</LinearLayout>
3.FooterView的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="45dp"android:gravity="center"android:orientation="horizontal"><ImageViewandroid:id="@+id/progress_iv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@mipmap/gpu" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="正在加载..."/></LinearLayout>
所有的XML文件里面就用到了两个Image,大家随便去找两个就可以了,我是解压了手机QQ的App后这里面找的。
好了所有的东西基本已经实现,大家还可以在这个基础上扩展一下,比如加一个动画,让FooterView被移除的时候好看一点,不要那么突兀的就消失了,如果大家实现了,希望能留个言让我学习学习!!!公司没有录屏工具,我就不上图了。
这篇关于继承SwipeRefreshLayout实现上拉加载更多功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!