首页 > 系统 > Android > 正文

Android ListView实现上拉加载下拉刷新和滑动删除功能

2019-12-12 04:18:46
字体:
来源:转载
供稿:网友

最近项目需要用到可以滑动删除并且带有上拉加载下拉刷新的Listview,查阅了一些资料,大多都是在SwipeMenuListView的基础上去添加头部和底部View,来扩展上拉加载和下拉刷新的功能,不过需要手动的去绘制UI及处理一些动画效果.用起来也不是特别方便.刚好项目中用到PulltorefreshLibrary库,就尝试着扩展了一个PullToRefreshSwipeMenuListView类来实现需求.先看一下效果:

实现步骤

一、组合Pulltorefresh与SwipeMenuListView

PulltorefreshLibrary库中包含很多种可以上拉加载下拉刷新的控件,经常用到的比如PullToRefreshListView,PullToRefreshGridView,PullToRefreshScrollView,它们的实现方式类似,本质上是在控件外部添加父布局,父布局中去添加控件的头部和底部View,来实现上拉加载下拉刷新的功能,所以扩展性很强.照猫画虎,copy一份PullToRefreshListView,对他做一些处理.

 protected ListView createListView(Context context, AttributeSet attrs) { final ListView lv; if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {  lv = new InternalListViewSDK9(context, attrs); } else {  lv = new InternalListView(context, attrs); } return lv; }

找到这部分代码,简单的做下修改:

 protected SwipeMenuListView createListView(Context context, AttributeSet attrs) { final SwipeMenuListView lv; lv = new SwipeMenuListView(context, attrs); return lv; }

为什么要copy一份PullToRefreshListView而不是其他的呢?因为SwipeMenuListView是继承自ListView的(看名字就可以发现),修改起来比较方便.为什么要修改这部分代码呢?往下看.找一下引用这部分代码的地方:

 @Override protected ListView createRefreshableView(Context context, AttributeSet attrs) { ListView lv = createListView(context, attrs); // Set it to this so it can be used in ListActivity/ListFragment lv.setId(android.R.id.list); return lv; }

是继承父类实现的方法,打开父类的该方法:

 /** * This is implemented by derived classes to return the created View. If you * need to use a custom View (such as a custom ListView), override this * method and return an instance of your custom class. * <p/> * Be sure to set the ID of the view in this method, especially if you're * using a ListActivity or ListFragment. * * @param context Context to create view with * @param attrs AttributeSet from wrapped class. Means that anything you *  include in the XML layout declaration will be routed to the *  created View * @return New instance of the Refreshable View */ protected abstract T createRefreshableView(Context context, AttributeSet attrs);

看一下注释,大概的意思是说,如果需要一个自定义的上拉加载下拉刷新View,可以返回该自定义View.并且返回值是T,一个泛型,说的很明白.看一下这个方法的引用mRefreshableView = createRefreshableView(context, attrs);看命名就知道,这个方法最终返回的是需要上拉加载下拉刷新功能的View.

感觉差不多可以了,来试一下,看一下效果:

好像效果不是很理想,有很多问题,比如滑动删除的时候可以上拉下拉,上拉时没有底部View.接下来来解决这些问题.

二、解决滑动冲突及相关问题

先来解决为什么没有底部View的问题,看一下copy过来修改过的PullToRefreshSwipeMenuListView类和PullToRefreshListView类,对比一下到底有什么区别,使得PullToRefreshSwipeMenuListView没有底部View,在PullToRefreshSwipeMenuListView中只修改了一个部分,就是把之前返回的InternalListView替换成了SwipeMenuListView,显然问题出现在InternalListView上,查看一下InternalListView(很容易找,是个内部类),可以看到这部分代码:

 @Override public void setAdapter(ListAdapter adapter) {  // Add the Footer View at the last possible moment  if (null != mLvFooterLoadingFrame && !mAddedLvFooter) {  addFooterView(mLvFooterLoadingFrame, null, false);  mAddedLvFooter = true;  }  super.setAdapter(adapter); }

底部View是在InternalListView调用setAdapter方法时添加上的,那头部View呢?查找一下,找到如下代码:

 @Override protected void handleStyledAttributes(TypedArray a) { super.handleStyledAttributes(a); mListViewExtrasEnabled = a.getBoolean(com.handmark.pulltorefresh.library.R.styleable.PullToRefresh_ptrListViewExtrasEnabled, true); if (mListViewExtrasEnabled) {  final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,   FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL);  // Create Loading Views ready for use later  FrameLayout frame = new FrameLayout(getContext());  mHeaderLoadingView = createLoadingLayout(getContext(), Mode.PULL_FROM_START, a);  mHeaderLoadingView.setVisibility(View.GONE);  // FrameLayout添加头View   frame.addView(mHeaderLoadingView, lp);  // 添加头部View  mRefreshableView.addHeaderView(frame, null, false);  mLvFooterLoadingFrame = new FrameLayout(getContext());  mFooterLoadingView = createLoadingLayout(getContext(), Mode.PULL_FROM_END, a);  mFooterLoadingView.setVisibility(View.GONE);  // FrameLayout添加底部View   mLvFooterLoadingFrame.addView(mFooterLoadingView, lp);  // 添加底部View  ...  /**  * If the value for Scrolling While Refreshing hasn't been  * explicitly set via XML, enable Scrolling While Refreshing.  */  if (!a.hasValue(com.handmark.pulltorefresh.library.R.styleable.PullToRefresh_ptrScrollingWhileRefreshingEnabled)) {  setScrollingWhileRefreshingEnabled(true);  } } }

发现头部是在初始化的时候被添加上,而底部并没有添加(代码中…的部分),InternalListView在setAdapter方法中,添加上了底部,SwipeMenuListView中并没有相关的处理,所以在…处添加代码
mRefreshableView.addFooterView(mLvFooterLoadingFrame, null, false);把底部加上,之前发现的没有底部的问题就解决了(当然也可以仿照InternalListView去修改一下SwipeMenuListView,不过比较麻烦,这里就不去做了)

接下来处理一下滑动删除时,可以进行上拉下拉操作的问题,很明显是滑动冲突的问题,想一下,当滑动删除时,不希望进行上拉下拉操作,而PullToRefreshSwipeMenuListView本身是一个ViewGroup,所以当滑动删除时,屏蔽掉父布局的滑动事件就可以了,打开SwipeMenuListView,在滑动事件中做一下处理即可:

 case MotionEvent.ACTION_MOVE:  float dy = Math.abs((ev.getY() - mDownY));  float dx = Math.abs((ev.getX() - mDownX));  if (mTouchState == TOUCH_STATE_X) {   if (mTouchView != null) {   mTouchView.onSwipe(ev);   }   getSelector().setState(new int[]{0});   ev.setAction(MotionEvent.ACTION_CANCEL);   super.onTouchEvent(ev);   // 处理滑动冲突,当处于滑动删除状态时,请求父布局不处理滑动事件   requestDisallowInterceptTouchEvent(true);   return true;  } else if (mTouchState == TOUCH_STATE_NONE) {   if (Math.abs(dy) > MAX_Y) {   mTouchState = TOUCH_STATE_Y;   } else if (dx > MAX_X) {   mTouchState = TOUCH_STATE_X;   if (mOnSwipeListener != null) {    mOnSwipeListener.onSwipeStart(mTouchPosition);   }   }  }  break;

很简单,就不多做说明了,不太清楚点击事件分发的童鞋,可以去查阅一下材料,这样一个带有上拉加载下拉刷新可滑动删除的ListView就基本完工了.

三、完整代码

PullToRefreshSwipeMenuListView:

package swipemenulistview;import android.content.Context;import android.content.res.TypedArray;import android.util.AttributeSet;import android.view.Gravity;import android.view.View;import android.widget.FrameLayout;import android.widget.ListAdapter;import android.widget.ListView;import com.handmark.pulltorefresh.library.LoadingLayoutProxy;import com.handmark.pulltorefresh.library.PullToRefreshAdapterViewBase;import com.handmark.pulltorefresh.library.internal.LoadingLayout;/** * Created by junweiliu on 16/10/12. */public class PullToRefreshSwipeMenuListView extends PullToRefreshAdapterViewBase<ListView> { private LoadingLayout mHeaderLoadingView; private LoadingLayout mFooterLoadingView; private FrameLayout mLvFooterLoadingFrame; private boolean mListViewExtrasEnabled; public PullToRefreshSwipeMenuListView(Context context) { super(context); } public PullToRefreshSwipeMenuListView(Context context, AttributeSet attrs) { super(context, attrs); } public PullToRefreshSwipeMenuListView(Context context, Mode mode) { super(context, mode); } public PullToRefreshSwipeMenuListView(Context context, Mode mode, AnimationStyle style) { super(context, mode, style); } @Override public final Orientation getPullToRefreshScrollDirection() { return Orientation.VERTICAL; } @Override protected void onRefreshing(final boolean doScroll) { /**  * If we're not showing the Refreshing view, or the list is empty, the  * the header/footer views won't show so we use the normal method.  */ ListAdapter adapter = mRefreshableView.getAdapter(); if (!mListViewExtrasEnabled || !getShowViewWhileRefreshing() || null == adapter || adapter.isEmpty()) {  super.onRefreshing(doScroll);  return; } super.onRefreshing(false); final LoadingLayout origLoadingView, listViewLoadingView, oppositeListViewLoadingView; final int selection, scrollToY; switch (getCurrentMode()) {  case MANUAL_REFRESH_ONLY:  case PULL_FROM_END:  origLoadingView = getFooterLayout();  listViewLoadingView = mFooterLoadingView;  oppositeListViewLoadingView = mHeaderLoadingView;  selection = mRefreshableView.getCount() - 1;  scrollToY = getScrollY() - getFooterSize();  break;  case PULL_FROM_START:  default:  origLoadingView = getHeaderLayout();  listViewLoadingView = mHeaderLoadingView;  oppositeListViewLoadingView = mFooterLoadingView;  selection = 0;  scrollToY = getScrollY() + getHeaderSize();  break; } // Hide our original Loading View origLoadingView.reset(); origLoadingView.hideAllViews(); // Make sure the opposite end is hidden too oppositeListViewLoadingView.setVisibility(View.GONE); // Show the ListView Loading View and set it to refresh. listViewLoadingView.setVisibility(View.VISIBLE); listViewLoadingView.refreshing(); if (doScroll) {  // We need to disable the automatic visibility changes for now  disableLoadingLayoutVisibilityChanges();  // We scroll slightly so that the ListView's header/footer is at the  // same Y position as our normal header/footer  setHeaderScroll(scrollToY);  // Make sure the ListView is scrolled to show the loading  // header/footer  mRefreshableView.setSelection(selection);  // Smooth scroll as normal  smoothScrollTo(0); } } @Override protected void onReset() { /**  * If the extras are not enabled, just call up to super and return.  */ if (!mListViewExtrasEnabled) {  super.onReset();  return; } final LoadingLayout originalLoadingLayout, listViewLoadingLayout; final int scrollToHeight, selection; final boolean scrollLvToEdge; switch (getCurrentMode()) {  case MANUAL_REFRESH_ONLY:  case PULL_FROM_END:  originalLoadingLayout = getFooterLayout();  listViewLoadingLayout = mFooterLoadingView;  selection = mRefreshableView.getCount() - 1;  scrollToHeight = getFooterSize();  scrollLvToEdge = Math.abs(mRefreshableView.getLastVisiblePosition() - selection) <= 1;  break;  case PULL_FROM_START:  default:  originalLoadingLayout = getHeaderLayout();  listViewLoadingLayout = mHeaderLoadingView;  scrollToHeight = -getHeaderSize();  selection = 0;  scrollLvToEdge = Math.abs(mRefreshableView.getFirstVisiblePosition() - selection) <= 1;  break; } // If the ListView header loading layout is showing, then we need to // flip so that the original one is showing instead if (listViewLoadingLayout.getVisibility() == View.VISIBLE) {  // Set our Original View to Visible  originalLoadingLayout.showInvisibleViews();  // Hide the ListView Header/Footer  listViewLoadingLayout.setVisibility(View.GONE);  /**  * Scroll so the View is at the same Y as the ListView  * header/footer, but only scroll if: we've pulled to refresh, it's  * positioned correctly  */  if (scrollLvToEdge && getState() != State.MANUAL_REFRESHING) {  mRefreshableView.setSelection(selection);  setHeaderScroll(scrollToHeight);  } } // Finally, call up to super super.onReset(); } @Override protected LoadingLayoutProxy createLoadingLayoutProxy(final boolean includeStart, final boolean includeEnd) { LoadingLayoutProxy proxy = super.createLoadingLayoutProxy(includeStart, includeEnd); if (mListViewExtrasEnabled) {  final Mode mode = getMode();  if (includeStart && mode.showHeaderLoadingLayout()) {  proxy.addLayout(mHeaderLoadingView);  }  if (includeEnd && mode.showFooterLoadingLayout()) {  proxy.addLayout(mFooterLoadingView);  } } return proxy; } protected SwipeMenuListView createListView(Context context, AttributeSet attrs) { final SwipeMenuListView lv;// if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {//  lv = new InternalListViewSDK9(context, attrs);// } else {//  lv = new InternalListView(context, attrs);// } lv = new SwipeMenuListView(context, attrs); return lv; } @Override protected ListView createRefreshableView(Context context, AttributeSet attrs) { ListView lv = createListView(context, attrs); // Set it to this so it can be used in ListActivity/ListFragment lv.setId(android.R.id.list); return lv; } @Override protected void handleStyledAttributes(TypedArray a) { super.handleStyledAttributes(a); mListViewExtrasEnabled = a.getBoolean(com.handmark.pulltorefresh.library.R.styleable.PullToRefresh_ptrListViewExtrasEnabled, true); if (mListViewExtrasEnabled) {  final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,   FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL);  // Create Loading Views ready for use later  FrameLayout frame = new FrameLayout(getContext());  mHeaderLoadingView = createLoadingLayout(getContext(), Mode.PULL_FROM_START, a);  mHeaderLoadingView.setVisibility(View.GONE);  frame.addView(mHeaderLoadingView, lp);  mRefreshableView.addHeaderView(frame, null, false);  mLvFooterLoadingFrame = new FrameLayout(getContext());  mFooterLoadingView = createLoadingLayout(getContext(), Mode.PULL_FROM_END, a);  mFooterLoadingView.setVisibility(View.GONE);  mLvFooterLoadingFrame.addView(mFooterLoadingView, lp);  // 添加底部加载view  mRefreshableView.addFooterView(mLvFooterLoadingFrame, null, false);  /**  * If the value for Scrolling While Refreshing hasn't been  * explicitly set via XML, enable Scrolling While Refreshing.  */  if (!a.hasValue(com.handmark.pulltorefresh.library.R.styleable.PullToRefresh_ptrScrollingWhileRefreshingEnabled)) {  setScrollingWhileRefreshingEnabled(true);  } } }}

SwipeMenuListView:

package swipemenulistview;import android.content.Context;import android.support.v4.view.MotionEventCompat;import android.util.AttributeSet;import android.util.TypedValue;import android.view.MotionEvent;import android.view.View;import android.view.animation.Interpolator;import android.widget.ListAdapter;import android.widget.ListView;/** * @author baoyz * @date 2014-8-18 */public class SwipeMenuListView extends ListView { private static final int TOUCH_STATE_NONE = 0; private static final int TOUCH_STATE_X = 1; private static final int TOUCH_STATE_Y = 2; public static final int DIRECTION_LEFT = 1; public static final int DIRECTION_RIGHT = -1; private int mDirection = 1;//swipe from right to left by default private int MAX_Y = 5; private int MAX_X = 3; private float mDownX; private float mDownY; private int mTouchState; private int mTouchPosition; private SwipeMenuLayout mTouchView; private OnSwipeListener mOnSwipeListener; private SwipeMenuCreator mMenuCreator; private OnMenuItemClickListener mOnMenuItemClickListener; private Interpolator mCloseInterpolator; private Interpolator mOpenInterpolator; public SwipeMenuListView(Context context) { super(context); init(); } public SwipeMenuListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } public SwipeMenuListView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { MAX_X = dp2px(MAX_X); MAX_Y = dp2px(MAX_Y); mTouchState = TOUCH_STATE_NONE; } @Override public void setAdapter(ListAdapter adapter) { super.setAdapter(new SwipeMenuAdapter(getContext(), adapter) {  @Override  public void createMenu(SwipeMenu menu) {  if (mMenuCreator != null) {   mMenuCreator.create(menu);  }  }  @Override  public void onItemClick(SwipeMenuView view, SwipeMenu menu,     int index) {  boolean flag = false;  if (mOnMenuItemClickListener != null) {   flag = mOnMenuItemClickListener.onMenuItemClick(    view.getPosition(), menu, index);  }  if (mTouchView != null && !flag) {   mTouchView.smoothCloseMenu();  }  } }); } public void setCloseInterpolator(Interpolator interpolator) { mCloseInterpolator = interpolator; } public void setOpenInterpolator(Interpolator interpolator) { mOpenInterpolator = interpolator; } public Interpolator getOpenInterpolator() { return mOpenInterpolator; } public Interpolator getCloseInterpolator() { return mCloseInterpolator; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent ev) { if (ev.getAction() != MotionEvent.ACTION_DOWN && mTouchView == null)  return super.onTouchEvent(ev); int action = MotionEventCompat.getActionMasked(ev); action = ev.getAction(); switch (action) {  case MotionEvent.ACTION_DOWN:  int oldPos = mTouchPosition;  mDownX = ev.getX();  mDownY = ev.getY();  mTouchState = TOUCH_STATE_NONE;  mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY());  if (mTouchPosition == oldPos && mTouchView != null   && mTouchView.isOpen()) {   mTouchState = TOUCH_STATE_X;   mTouchView.onSwipe(ev);   return true;  }  View view = getChildAt(mTouchPosition - getFirstVisiblePosition());  if (mTouchView != null && mTouchView.isOpen()) {   mTouchView.smoothCloseMenu();   mTouchView = null;   // return super.onTouchEvent(ev);   // try to cancel the touch event   MotionEvent cancelEvent = MotionEvent.obtain(ev);   cancelEvent.setAction(MotionEvent.ACTION_CANCEL);   onTouchEvent(cancelEvent);   return true;  }  if (view instanceof SwipeMenuLayout) {   mTouchView = (SwipeMenuLayout) view;   mTouchView.setSwipeDirection(mDirection);  }  if (mTouchView != null) {   mTouchView.onSwipe(ev);  }  break;  case MotionEvent.ACTION_MOVE:  float dy = Math.abs((ev.getY() - mDownY));  float dx = Math.abs((ev.getX() - mDownX));  if (mTouchState == TOUCH_STATE_X) {   if (mTouchView != null) {   mTouchView.onSwipe(ev);   }   getSelector().setState(new int[]{0});   ev.setAction(MotionEvent.ACTION_CANCEL);   super.onTouchEvent(ev);   // 处理滑动冲突,当处于滑动删除状态时,请求父布局不处理滑动事件   requestDisallowInterceptTouchEvent(true);   return true;  } else if (mTouchState == TOUCH_STATE_NONE) {   if (Math.abs(dy) > MAX_Y) {   mTouchState = TOUCH_STATE_Y;   } else if (dx > MAX_X) {   mTouchState = TOUCH_STATE_X;   if (mOnSwipeListener != null) {    mOnSwipeListener.onSwipeStart(mTouchPosition);   }   }  }  break;  case MotionEvent.ACTION_UP:  requestDisallowInterceptTouchEvent(false);  if (mTouchState == TOUCH_STATE_X) {   if (mTouchView != null) {   mTouchView.onSwipe(ev);   if (!mTouchView.isOpen()) {    mTouchPosition = -1;    mTouchView = null;   }   }   if (mOnSwipeListener != null) {   mOnSwipeListener.onSwipeEnd(mTouchPosition);   }   ev.setAction(MotionEvent.ACTION_CANCEL);   super.onTouchEvent(ev);   return true;  }  break; } return super.onTouchEvent(ev); } public void smoothOpenMenu(int position) { if (position >= getFirstVisiblePosition()  && position <= getLastVisiblePosition()) {  View view = getChildAt(position - getFirstVisiblePosition());  if (view instanceof SwipeMenuLayout) {  mTouchPosition = position;  if (mTouchView != null && mTouchView.isOpen()) {   mTouchView.smoothCloseMenu();  }  mTouchView = (SwipeMenuLayout) view;  mTouchView.setSwipeDirection(mDirection);  mTouchView.smoothOpenMenu();  } } } private int dp2px(int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,  getContext().getResources().getDisplayMetrics()); } public void setMenuCreator(SwipeMenuCreator menuCreator) { this.mMenuCreator = menuCreator; } public void setOnMenuItemClickListener(  OnMenuItemClickListener onMenuItemClickListener) { this.mOnMenuItemClickListener = onMenuItemClickListener; } public void setOnSwipeListener(OnSwipeListener onSwipeListener) { this.mOnSwipeListener = onSwipeListener; } public static interface OnMenuItemClickListener { boolean onMenuItemClick(int position, SwipeMenu menu, int index); } public static interface OnSwipeListener { void onSwipeStart(int position); void onSwipeEnd(int position); } public void setSwipeDirection(int direction) { mDirection = direction; }}

MainActivity:

package com.example.junweiliu.pulltorefreshswipemenulistviewdemo;import android.graphics.Color;import android.graphics.drawable.ColorDrawable;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.util.TypedValue;import android.view.View;import android.widget.AdapterView;import android.widget.ListView;import android.widget.SimpleAdapter;import android.widget.Toast;import com.handmark.pulltorefresh.library.PullToRefreshBase;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import swipemenulistview.PullToRefreshSwipeMenuListView;import swipemenulistview.SwipeMenu;import swipemenulistview.SwipeMenuCreator;import swipemenulistview.SwipeMenuItem;import swipemenulistview.SwipeMenuListView;public class MainActivity extends AppCompatActivity { /** * 控件 */ private PullToRefreshSwipeMenuListView mPullToRefreshSwipeMenuListView; /** * 适配器 */ private SimpleAdapter mAdapter; /** * 数据源 */ List<Map<String, Object>> datas = new ArrayList<Map<String, Object>>(); /** * 信息 */ private String[] message = {"数据0", "数据1", "数据2", "数据3", "数据4", "数据5", "数据6", "数据7", "数据8", "数据9", "数据10"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); initView(); } /** * 初始化控件 */ private void initView() { mPullToRefreshSwipeMenuListView = (PullToRefreshSwipeMenuListView) findViewById(R.id.psl_demo); mAdapter = new SimpleAdapter(this, datas, R.layout.item_adapter, new String[]{"message"}, new int[]{R.id.tv_message}); mPullToRefreshSwipeMenuListView.setMode(PullToRefreshBase.Mode.BOTH); mPullToRefreshSwipeMenuListView.setAdapter(mAdapter); // 创建删除滑块 SwipeMenuCreator creator = new SwipeMenuCreator() {  @Override  public void create(SwipeMenu menu) {  SwipeMenuItem deleteItem = new SwipeMenuItem(   getApplicationContext());  deleteItem.setBackground(new ColorDrawable(Color.rgb(0xFF,   0x20, 0x20)));  deleteItem.setWidth(dp2px(63));//  deleteItem.setIcon(R.drawable.ic_delete);  deleteItem.setTitle("删除");  deleteItem.setTitleSize(14);  deleteItem.setTitleColor(Color.WHITE);  menu.addMenuItem(deleteItem);  } }; // 设置滑块 ((SwipeMenuListView) mPullToRefreshSwipeMenuListView.getRefreshableView()).setMenuCreator(creator); // 滑块点击事件 ((SwipeMenuListView) mPullToRefreshSwipeMenuListView.getRefreshableView()).setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {  @Override  public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {  switch (index) {   case 0:   Toast.makeText(MainActivity.this, "删除我了" + position, Toast.LENGTH_SHORT).show();   break;  }  return false;  } }); // 滑动监听 ((SwipeMenuListView) mPullToRefreshSwipeMenuListView.getRefreshableView()).setOnSwipeListener(new SwipeMenuListView.OnSwipeListener() {  @Override  public void onSwipeStart(int position) {  }  @Override  public void onSwipeEnd(int position) {  } }); // 刷新加载事件 mPullToRefreshSwipeMenuListView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() {  @Override  public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {  new Handler(new Handler.Callback() {   @Override   public boolean handleMessage(Message message) {   Toast.makeText(MainActivity.this, "刷新成功", Toast.LENGTH_SHORT).show();   mPullToRefreshSwipeMenuListView.onRefreshComplete();   return false;   }  }).sendEmptyMessageDelayed(1, 1000);  }  @Override  public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {  new Handler(new Handler.Callback() {   @Override   public boolean handleMessage(Message message) {   Toast.makeText(MainActivity.this, "加载成功", Toast.LENGTH_SHORT).show();   mPullToRefreshSwipeMenuListView.onRefreshComplete();   return false;   }  }).sendEmptyMessageDelayed(2, 1000);  } }); // 点击事件 mPullToRefreshSwipeMenuListView.getRefreshableView().setOnItemClickListener(new AdapterView.OnItemClickListener() {  @Override  public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {  } }); } /** * 初始化数据 */ private void initData() { for (int i = 0; i < message.length; i++) {  Map<String, Object> data = new HashMap<String, Object>();  data.put("message", message[i]);  datas.add(data); } } /** * dp转px * * @param dp * @return */ private int dp2px(int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,  getResources().getDisplayMetrics()); }}

activity_main:

<?xml version="1.0" encoding="utf-8"?><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="com.example.junweiliu.pulltorefreshswipemenulistviewdemo.MainActivity"> <!--上拉加载下拉刷新滑动删除控件--> <swipemenulistview.PullToRefreshSwipeMenuListView  android:id="@+id/psl_demo"  android:layout_width="match_parent"  android:layout_height="match_parent" > </swipemenulistview.PullToRefreshSwipeMenuListView></RelativeLayout>

item_adapter:

<?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"  android:orientation="vertical"> <TextView  android:id="@+id/tv_message"  android:layout_width="wrap_content"  android:layout_height="match_parent"  android:paddingBottom="30dp"  android:paddingTop="30dp"  android:text="数据"  android:textColor="@android:color/black"  android:textSize="16sp"/></LinearLayout>

本文已经被整理到《Android下拉刷新上拉加载效果》,欢迎大家学习研究。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表