下拉刷新、上拉加载更多功能的实现
来源:互联网 发布:淘宝月赚三千 编辑:程序博客网 时间:2024/05/22 15:03
如需转载请注明出处:http://blog.csdn.net/tyhj_sf/article/details/51079448
1 实现原理
自定义DraggableListView继承ListView,重新实现onTouchEvent(MotionEvent ev)方法,在此方法中根据用户动作事件(ACTION_DOWN、ACTION_MOVE、ACTION_UP)计算用户手指滑动的方向和距离,然后根据方向和距离值控制DraggableListView的header和footer的高度。
类图如下:
在上面的类图中, 类DraggableListViewHeader是DraggableListView的header,类DraggableListViewFooter是DraggableListView的footer,这个两个类并未扩展任何组件,它们只是分别组合了header、footer需要的所有组件,例如显示刷新时间的TextView、指示箭头ImageView、进度条组件等。这是自定义组件的方法之一。
对于接口OnDraggableListViewListener,使用到Android源码中很常见的回调机制,对于这一机制不清楚的同学可以看我的这一篇文章:源码分析——从button的点击事件看Android中回调机制
原理很简单,下面直接贴出类的具体实现,注释很详细,相信你能够看懂。
2 源码
2.1 DraggableListViewHeader类源码
package com.util.pulltorefresh_loadmore;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;import android.annotation.SuppressLint;import android.app.Activity;import android.content.Context;import android.content.SharedPreferences;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.animation.Animation;import android.view.animation.RotateAnimation;import android.widget.ImageView;import android.widget.ProgressBar;import android.widget.RelativeLayout;import android.widget.RelativeLayout.LayoutParams;import android.widget.TextView;/** * 自定义Listview的header,不继承view,只是所有view组件的聚合。 * * @author tyhj_sf@163.com * */public final class DraggableListViewHeader { private final static String TAG = "DraggableListViewHeader"; /** * header最小高度 */ private final static int HEADER_HEIGHT_MIN = 0; /** * header最大高度 */ private final static int HEADER_HEIGHT_MAX = 100; /** * header状态:正常态,仅提示用户可下拉刷新 */ public final static int STATE_NORMAL = 1; /** * header状态:就绪态,提示用户松手可刷新 */ public final static int STATE_READY = 2; /** * header状态:提示用户正在刷新 */ public final static int STATE_REFRESHING = 3; /** * header状态:提示用户刷新成功,该状态仅表示刷新结束后的几秒钟内。 */ public final static int STATE_SUCCESS = 4; /** * header状态:提示用户刷新失败 */ public final static int STATE_FAILURE = 5; /** * 旋转动画持续时间 */ private final long ROTATE_ANIM_DURATION = 180; /**Root of Listview header Layout */ private RelativeLayout header; /**The container of all Views*/ private RelativeLayout viewContainer; private TextView actionHint; private TextView lastTimeHint; private TextView lastTime; private ProgressBar progressBar; private ImageView arrowImageView; private Animation headerRotateUpAnim; private Animation headerRotateDownAnim; /**宿主activity*/ private Activity activity; private int headerState; public DraggableListViewHeader(Context context) { // TODO Auto-generated constructor stub headerState = STATE_NORMAL; init(context); } @SuppressLint("InflateParams") private void init(Context context) { // TODO Auto-generated method stub Log.d(TAG, "初始化执行开始"); LayoutInflater layoutInflater = LayoutInflater.from(context); viewContainer = (RelativeLayout) layoutInflater.inflate( R.layout.draggablelistview_header, null); header = new RelativeLayout(context); header.setVisibility(View.GONE); header.addView(viewContainer, new RelativeLayout.LayoutParams( LayoutParams.MATCH_PARENT, HEADER_HEIGHT_MIN)); Log.d(TAG, "NULL判别:viewContainer=" + viewContainer); actionHint = (TextView) viewContainer .findViewById(R.id.draggablelistview_header_hint_textview); lastTimeHint = (TextView) viewContainer .findViewById(R.id.draggablelistview_header_last_time_textview); lastTime = (TextView) viewContainer .findViewById(R.id.draggablelistview_header_time); lastTime.setText(context.getSharedPreferences(TAG, Context.MODE_PRIVATE).getString("lastTime", "未知")); progressBar = (ProgressBar) viewContainer .findViewById(R.id.draggablelistview_header_progressbar); arrowImageView = (ImageView) viewContainer .findViewById(R.id.draggablelistview_header_arrow); Log.d(TAG, "headerRotateUpAnim动画初始化执行开始"); headerRotateUpAnim = new RotateAnimation(0.0f, -180.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); headerRotateUpAnim.setDuration(ROTATE_ANIM_DURATION); headerRotateUpAnim.setFillAfter(true); Log.d(TAG, "headerRotateDownAnim动画初始化执行开始"); headerRotateDownAnim = new RotateAnimation(-180.0f, 0.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); headerRotateDownAnim.setDuration(ROTATE_ANIM_DURATION); headerRotateDownAnim.setFillAfter(true); Log.d(TAG, "初始化执行完成"); } public RelativeLayout getCustumHeader() { Log.d(TAG, "viewContainer=" + header); return header; } /** * get the root view of layout file of header * * @return */ public RelativeLayout getViewContainer() { return viewContainer; } /** * 设置header视图的布局高度 * * @param height */ public void setHeadertHeight(int height) { // 阈值处理 if (height <= DraggableListViewHeader.HEADER_HEIGHT_MIN) { height = DraggableListViewHeader.HEADER_HEIGHT_MIN; if (getHeaderState() != STATE_REFRESHING) { header.setVisibility(View.GONE); Log.d(TAG, "阈值处理-STATE_NORMAL"); setHeaderState(STATE_NORMAL); } else { // continue. } } else { header.setVisibility(View.VISIBLE); if (height > DraggableListViewHeader.HEADER_HEIGHT_MAX) { height = DraggableListViewHeader.HEADER_HEIGHT_MAX; if (getHeaderState() != STATE_REFRESHING) { Log.d(TAG, "阈值处理-STATE_READY"); setHeaderState(STATE_READY); } else { // continue. } } else { if (getHeaderState() != STATE_REFRESHING) { Log.d(TAG, "阈值处理-STATE_NORMAL"); setHeaderState(STATE_NORMAL); } else { // continue. } } } RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) viewContainer .getLayoutParams(); Log.d(TAG, "layoutParams=" + layoutParams); layoutParams.height = height; viewContainer.setLayoutParams(layoutParams); } public int getHeaderHeight() { return header.getHeight(); } /** * 通过补偿值更新header的高度 * * @param offset * 补偿值 */ public void updateHeaderHeightByOffset(int offset) { int currentHeight=header.getHeight()+offset; setHeadertHeight(currentHeight); } /** * 复位header,可视高度最小、不可视、状态为STATE_NORMAL */ public void resetHeader() { setHeadertHeight(DraggableListViewHeader.HEADER_HEIGHT_MIN); header.setVisibility(View.GONE); header.clearAnimation(); setHeaderState(DraggableListViewHeader.STATE_NORMAL); } public void setHeaderState(int state) { if (state == DraggableListViewHeader.STATE_REFRESHING) { arrowImageView.setVisibility(View.INVISIBLE); progressBar.setVisibility(View.VISIBLE); lastTimeHint.setVisibility(View.VISIBLE); lastTime.setVisibility(View.VISIBLE); } else if (state == STATE_SUCCESS || state == STATE_FAILURE) { arrowImageView.setVisibility(View.GONE); progressBar.setVisibility(View.GONE); lastTimeHint.setVisibility(View.GONE); lastTime.setVisibility(View.GONE); } else { arrowImageView.setVisibility(View.VISIBLE); progressBar.setVisibility(View.INVISIBLE); lastTimeHint.setVisibility(View.VISIBLE); lastTime.setVisibility(View.VISIBLE); } switch (state) { case DraggableListViewHeader.STATE_NORMAL: actionHint.setText(R.string.draggablelistview_header_hint_normal); if (headerState == DraggableListViewHeader.STATE_READY) { arrowImageView.startAnimation(headerRotateDownAnim); } else { arrowImageView.clearAnimation(); } Log.d(TAG, "处理STATE_NORMAL工作完成"); break; case DraggableListViewHeader.STATE_READY: if (headerState != DraggableListViewHeader.STATE_READY) { actionHint .setText(R.string.draggablelistview_header_hint_ready); arrowImageView.startAnimation(headerRotateUpAnim); } else { // continue. } Log.d(TAG, "处理STATE_READY工作完成"); break; case DraggableListViewHeader.STATE_REFRESHING: actionHint .setText(R.string.draggablelistview_header_hint_refreshing); arrowImageView.clearAnimation(); break; case DraggableListViewHeader.STATE_SUCCESS: actionHint .setText(R.string.draggablelistview_header_hint_refresh_finished); // TODO更新刷新完成的时间 SimpleDateFormat formatter = new SimpleDateFormat( "MM月dd日 HH:mm:ss"); Date curDate = new Date(System.currentTimeMillis()); String str = formatter.format(curDate); lastTime.setText(str); SharedPreferences sharedPreferences=activity.getSharedPreferences(TAG, Context.MODE_PRIVATE); sharedPreferences.edit().putString("lastTime", str).apply(); Log.d(TAG, "处理STATE_FINISHED工作完成"); break; case DraggableListViewHeader.STATE_FAILURE: actionHint .setText(R.string.draggablelistview_header_hint_refresh_failure); Log.d(TAG, "处理STATE_FAILURE工作完成"); break; default: break; } headerState = state; } public int getHeaderState() { return headerState; } /** * 提示刷新成功 * @param activity 宿主activity */ public void showRefreshSuccess(Activity activity) { this.activity=activity; if (!Thread.currentThread().getName().equals("MAIN")) { activity.runOnUiThread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub setHeaderState(STATE_SUCCESS); } }); }else { setHeaderState(STATE_SUCCESS); } Timer timer=new Timer(); timer.schedule(new UiTask(activity,timer), 2500); } /** * 提示刷新失败 * @param activity 宿主activity */ public void showRefreshFailure(Activity activity) { this.activity=activity; if (!Thread.currentThread().getName().equals("MAIN")) { activity.runOnUiThread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub setHeaderState(STATE_FAILURE); } }); }else { setHeaderState(STATE_FAILURE); } Timer timer=new Timer(); timer.schedule(new UiTask(activity,timer), 2500); } /** * 处理UI任务 * @author tyhj_sf@163.com * */ private class UiTask extends TimerTask{ Activity activity; Timer timer; public UiTask(Activity activity,Timer timer) { // TODO Auto-generated constructor stub super(); this.activity=activity; this.timer=timer; } @Override public void run() { // TODO 使header不可视 activity.runOnUiThread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub header.setVisibility(View.GONE); resetHeader(); timer.cancel(); } }); } }}
2.2 DraggableListViewFooter的源码
package com.util.pulltorefresh_loadmore;import android.annotation.SuppressLint;import android.app.Activity;import android.content.Context;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.widget.EditText;import android.widget.ProgressBar;import android.widget.RelativeLayout;import android.widget.RelativeLayout.LayoutParams;import android.widget.TextView;/** * 不继承view,只是所有view组件的聚合。 * * @author Administrator * */public class DraggableListViewFooter { private final static String TAG = "DraggableListViewFooter"; private final static int FOOTER_HEIGHT_MIN = 0; private final static int FOOTER_HEIGHT_MAX = 80; /** * footer状态:正常态,仅提示用户可上拉加载更多 */ public final static int STATE_NORMAL = 1; /** * footer状态:就绪态,提示用户松手可加载 */ public final static int STATE_READY = 2; /** * footer状态:提示用户正在加载更多 */ public final static int STATE_REFRESHING = 3; /** * footer状态:提示用户刷新成功,该状态仅表示刷新结束后的几秒钟内。 */ public final static int STATE_SUCCESS = 4; /** * footer状态:提示用户刷新失败 */ public final static int STATE_FAILURE = 5; private RelativeLayout viewContainer; /** * footer布局视图 */ private RelativeLayout footer; private TextView actionHint; private ProgressBar progressBar; private int footerState; public DraggableListViewFooter(Context context) { // TODO Auto-generated constructor stub init(context); } /** * 初始化视图 * * @param context */ @SuppressLint("InflateParams") private void init(Context context) { // TODO Auto-generated method stub viewContainer = (RelativeLayout) LayoutInflater.from(context).inflate( R.layout.draggablistview_footer, null); footer = new RelativeLayout(context); footer.addView(viewContainer, new RelativeLayout.LayoutParams( LayoutParams.MATCH_PARENT, FOOTER_HEIGHT_MIN)); footer.setVisibility(View.GONE); actionHint = (TextView) viewContainer .findViewById(R.id.draggablelistview_footer_hint_textview); progressBar = (ProgressBar) viewContainer .findViewById(R.id.draggablelistview_footer_progressbar); footerState = DraggableListViewFooter.STATE_NORMAL; Log.d(TAG, "初始化执行完成"); } public RelativeLayout getCustumFooter() { return footer; } /** * get the root view of layout file of fooder * * @return */ public RelativeLayout getViewContainer() { return viewContainer; } /** * 设置footer视图的布局高度 * * @param height */ public void setFootertHeight(int height) { // 阈值处理 if (height <= DraggableListViewFooter.FOOTER_HEIGHT_MIN) { height = DraggableListViewFooter.FOOTER_HEIGHT_MIN; footer.setVisibility(View.GONE); setFooterState(STATE_NORMAL); } else { footer.setVisibility(View.VISIBLE); if (height > DraggableListViewFooter.FOOTER_HEIGHT_MAX) { height = DraggableListViewFooter.FOOTER_HEIGHT_MAX; setFooterState(STATE_READY); } else { setFooterState(STATE_NORMAL); } } RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) viewContainer .getLayoutParams(); layoutParams.height = height; viewContainer.setLayoutParams(layoutParams); } public int getFooterHeight() { return footer.getHeight(); } /** * 通过补偿值更新footer的高度,根据高度阈值设定footer状态。 * * @param offset * 补偿值 */ public void updateHeaderHeightByOffset(int offset) { setFootertHeight(footer.getHeight() + offset); } /** * 复位footer,可视高度最小、不可视、状态为STATE_NORMAL */ public void resetFooter() { setFootertHeight(DraggableListViewFooter.FOOTER_HEIGHT_MIN); footer.setVisibility(View.GONE); setFooterState(DraggableListViewFooter.STATE_NORMAL); } public void setFooterState(int state) { switch (state) { case DraggableListViewFooter.STATE_NORMAL: progressBar.setVisibility(View.GONE); actionHint.setVisibility(View.VISIBLE); actionHint.setText(R.string.draggablelistview_footer_hint_normal); break; case DraggableListViewFooter.STATE_READY: progressBar.setVisibility(View.GONE); actionHint.setVisibility(View.VISIBLE); if (footerState == DraggableListViewFooter.STATE_NORMAL) { actionHint .setText(R.string.draggablelistview_footer_hint_ready); } else { // do nothing } break; case DraggableListViewFooter.STATE_REFRESHING: progressBar.setVisibility(View.VISIBLE); actionHint.setVisibility(View.GONE); if (footerState == DraggableListViewFooter.STATE_READY) { actionHint .setText(R.string.draggablelistview_footer_hint_loading); } else { // do nothing } break; case DraggableListViewFooter.STATE_SUCCESS: RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) viewContainer .getLayoutParams(); layoutParams.height = 0; viewContainer.setLayoutParams(layoutParams); footer.setVisibility(View.GONE); break; case DraggableListViewFooter.STATE_FAILURE: footer.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); actionHint.setVisibility(View.VISIBLE); actionHint .setText(R.string.draggablelistview_footer_hint_load_failure); break; default: break; } footerState = state; } public int getFooterState() { return footerState; } /** * 提示加载成功 * * @param activity * 宿主activity */ public void showLoadSuccess(Activity activity) { if (!Thread.currentThread().getName().equals("MAIN")) { activity.runOnUiThread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub setFooterState(STATE_SUCCESS); } }); } else { setFooterState(STATE_SUCCESS); } } /** * 提示加载失败 * * @param activity * 宿主activity */ public void showLoadFailure(Activity activity) { if (!Thread.currentThread().getName().equals("MAIN")) { activity.runOnUiThread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub setFooterState(STATE_FAILURE); } }); } else { setFooterState(STATE_FAILURE); } }}
2.3 DraggableListView的源码
package com.util.pulltorefresh_loadmore;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.widget.ListView;/** * 自定义带下拉刷新和上拉加载更多的Listview组件 * * @author sunfeng * @since 2016-3-18 * */public final class DraggableListView extends ListView { private final static String TAG = "DraggableListView"; private final static double FREQUENCY_CONTROL = 1.8; private int lastY = -1; private int totalItemCount = 0; // private OnScrollListener onDraggableListViewScrollListener; private DraggableListViewHeader headerView; private DraggableListViewFooter footerView; private OnDraggableListViewListener onDraggableListViewListener; /** * @param context */ public DraggableListView(Context context) { super(context); // TODO Auto-generated constructor stub initWithContext(context); } /** * @param context * @param attrs * @param defStyle */ public DraggableListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub initWithContext(context); } /** * @param context * @param attrs */ public DraggableListView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub initWithContext(context); } @Override public boolean onTouchEvent(MotionEvent ev) { // TODO Auto-generated method stub switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: lastY = (int) ev.getRawY(); totalItemCount = getAdapter().getCount(); Log.d(TAG, "MotionEvent.ACTION_DOWN执行"); break; case MotionEvent.ACTION_MOVE: final int offsetY = (int) ((ev.getRawY() - lastY) / DraggableListView.FREQUENCY_CONTROL); lastY = (int) ev.getRawY(); // 滑动到顶部 if ((headerView.getHeaderState() == DraggableListViewHeader.STATE_NORMAL || headerView .getHeaderState() == DraggableListViewHeader.STATE_READY) && (footerView.getFooterState() != DraggableListViewFooter.STATE_REFRESHING) && (getFirstVisiblePosition() == 0)&&(offsetY > 0)) { headerView.updateHeaderHeightByOffset(offsetY); } // 滑动到底部 if (headerView.getHeaderState() != DraggableListViewHeader.STATE_REFRESHING && footerView.getFooterState() != DraggableListViewFooter.STATE_REFRESHING && ((getLastVisiblePosition() == (totalItemCount - 1)) && (offsetY < 0))) { footerView.updateHeaderHeightByOffset(-offsetY); } Log.d(TAG, "MotionEvent.ACTION_MOVE执行"); break; case MotionEvent.ACTION_UP: if (headerView.getHeaderState() == DraggableListViewHeader.STATE_READY) { headerView .setHeaderState(DraggableListViewHeader.STATE_REFRESHING); // 刷新DraggableListView onDraggableListViewListener.onRefresh(); } else if (headerView.getHeaderState() == DraggableListViewHeader.STATE_NORMAL || footerView.getFooterState() != DraggableListViewFooter.STATE_NORMAL) { // TODO 复位header headerView.resetHeader(); } else { // do nothing } if (footerView.getFooterState() == DraggableListViewFooter.STATE_READY) { footerView .setFooterState(DraggableListViewFooter.STATE_REFRESHING); // 加载更多数据到DraggableListView onDraggableListViewListener.onLoadMore(); } else if (headerView.getHeaderState() != DraggableListViewHeader.STATE_NORMAL || footerView.getFooterState() == DraggableListViewFooter.STATE_NORMAL) { // TODO 复位footer footerView.resetFooter(); } else { // do nothing } Log.d(TAG, "MotionEvent.ACTION_UP执行"); break; default: // 异常终止滑动操作时,复位header和footer headerView.resetHeader(); footerView.resetFooter(); break; } return super.onTouchEvent(ev); } /** * 用context初始化 * * @param context */ protected void initWithContext(Context context) { // TODO 初始化 Log.d(TAG, "初始化开始执行"); Thread.currentThread().setName("MAIN"); lastY = -1; headerView = new DraggableListViewHeader(context); addHeaderView(headerView.getCustumHeader()); footerView = new DraggableListViewFooter(context); addFooterView(footerView.getCustumFooter()); Log.d(TAG, "初始化执行完成"); } public DraggableListViewHeader getHeaderView() { return headerView; } public DraggableListViewFooter getFooterView() { return footerView; } public void setOnDraggableListViewListener(OnDraggableListViewListener d) { onDraggableListViewListener = d; } public interface OnDraggableListViewListener { /** * 下拉回调刷新 */ public void onRefresh(); /** * 上拉加载更多 */ public void onLoadMore(); }}
3 使用方法
下面通过一个简单的实验演示这个带下拉刷新和上拉加载更多功能的Listview的使用方法。
3.1 主程序源码
package com.util.pulltorefresh_loadmore;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import com.util.pulltorefresh_loadmore.DraggableListView.OnDraggableListViewListener;import android.app.Activity;import android.app.TaskStackBuilder;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.Adapter;import android.widget.ListAdapter;import android.widget.ProgressBar;import android.widget.SimpleAdapter;import android.widget.Toast;public class MainActivity extends Activity { private DraggableListView draggableListView; private List<Map<String, String>> list; private Map<String, String> map; private Adapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); draggableListView=(DraggableListView)findViewById(R.id.listview); draggableListView.setOnDraggableListViewListener(new OnDraggableListViewListener() { @Override public void onRefresh() { // TODO Auto-generated method stub new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } draggableListView.getHeaderView().showRefreshFailure(MainActivity.this); } }).start(); } @Override public void onLoadMore() { // TODO Auto-generated method stub new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } draggableListView.getFooterView().showLoadSuccess(MainActivity.this); } }).start(); } }); list=new ArrayList<Map<String,String>>(); map=new HashMap<>(); map.put("1", "牛肉"); map.put("2", "鸡肉"); list.add(map); map=new HashMap<>(); map.put("1", "苹果"); map.put("2", "香蕉"); list.add(map); map=new HashMap<>(); map.put("1", "1"); map.put("2", "11"); list.add(map); map=new HashMap<>(); map.put("1", "2"); map.put("2", "22"); list.add(map); map=new HashMap<>(); map.put("1", "3"); map.put("2", "33"); list.add(map); map=new HashMap<>(); map.put("1", "4"); map.put("2", "44"); list.add(map); map=new HashMap<>(); map.put("1", "5"); map.put("2", "55"); list.add(map); map=new HashMap<>(); map.put("1", "6"); map.put("2", "66"); list.add(map); map=new HashMap<>(); map.put("1", "7"); map.put("2", "77"); list.add(map); map=new HashMap<>(); map.put("1", "8"); map.put("2", "88"); list.add(map); map=new HashMap<>(); map.put("1", "9"); map.put("2", "99"); list.add(map); map=new HashMap<>(); map.put("1", "0"); map.put("2", "00"); list.add(map); map=new HashMap<>(); map.put("1", "11"); map.put("2", "111"); list.add(map); adapter=new SimpleAdapter(this, list, R.layout.listitem, new String[]{"1","2"}, new int[]{R.id.item_1,R.id.item_2}); draggableListView.setAdapter((ListAdapter)adapter); }}
3.2 布局文件
布局文件很简单,这里直接贴出来。
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="${relativePackage}.${activityClass}"> <com.util.pulltorefresh_loadmore.DraggableListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent" /></RelativeLayout>
listitem.xml文件:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/item_1" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="16sp" /> <TextView android:id="@+id/item_2" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="16sp" /></LinearLayout>
4 说明
这个源码完全是本人的实现思路,很简单,通过阅读源码相信你能看懂的。
有不足的地方欢迎留言或私信我提出。
有需要完整源代码同学请发私信留下你的邮箱。
- 下拉刷新、上拉加载更多功能的实现
- SwipeRefreshLayout实现下拉刷新、上拉加载更多功能
- 常见功能--下拉刷新、上拉加载更多效果实现
- 手机端的下拉刷新上拉加载更多功能的实现
- Android ListView下拉刷新上拉加载更多的实现
- listview下拉刷新,上拉加载更多的实现方法
- Android实现ListView的下拉刷新、上拉加载更多
- ListView下拉刷新和上拉加载更多的实现
- RecyclerView 上拉加载更多下拉刷新的一种实现
- RecyclerView+SwipeRefreshLayout实现上拉刷新,下拉加载更多的功能
- RecycleView控件的使用(三) 实现上拉加载更多下拉刷新功能
- 小程序 实现上拉加载更多 和下拉刷新的功能
- 自定义ListView下拉刷新上拉加载更多功能
- 自定义上拉加载下拉刷新控件,从而实现滑动到底部时上拉加载更多的功能
- android ListView上拉加载更多 下拉刷新功能实现(采用pull-to-refresh)
- Android实现微博下拉刷新上拉加载更多功能
- android ListView上拉加载更多 下拉刷新功能实现(采用pull-to-refresh)
- android ListView上拉加载更多 下拉刷新功能实现(采用pull-to-refresh)
- 杭电oj-1233-还是畅通工程(并查集加Kruskal算法)
- 适配器模式剖析
- Mac下发布Qt应用程序
- C/C++—— 默认构造函数是否会执行
- 使用for进行removeChild的注意问题
- 下拉刷新、上拉加载更多功能的实现
- 中序和后序生成二叉树
- iOS开发--CocoaPods的安装和使用说明
- ZooKeeper安装与运行
- 一次代码提速过程
- C++之模版应用(顺序表)
- opencv3实现的傅里叶变换
- 对java中synchronized的认识
- @ Html.ActionLink的用法详解