ListView的下拉刷新、滑动删除和上拉加载更多
来源:互联网 发布:python 2.7不支持中文 编辑:程序博客网 时间:2024/05/16 05:44
实现思路:
1、在ListView中添加header并在开始时隐藏,通过设置header的topPadding为负的header的高度,实现该效果
2、监听手势(用onTouchEvent),先判断ListView是否已经到达顶部,到达顶部以后根据滑动幅度(手指还没有抬起来)可分为两种状态,一种是幅度不够,则松开手指后LiveView恢复原样,一种是下拉幅度够了则更改header中的View信息,第三种状态是正在刷新,在松开手指时更新为该状态
3、ListView的滑动监听,如果在滑动时为状态3,则开启线程更新ListView中的数据(借助handler)
效果图:
header布局:
<?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"> <!--ListView的头部布局--> <FrameLayout android:id="@+id/fl" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="120dp"> <ImageView android:id="@+id/refresh" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/pull_to_refresh_arrow" /> <ProgressBar android:id="@+id/progress" style="@style/Widget.AppCompat.ProgressBar" android:layout_gravity="center" android:max="100" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="gone" /> </FrameLayout> <LinearLayout android:id="@+id/ly" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_toRightOf="@id/fl" android:gravity="center_horizontal" android:orientation="vertical" android:paddingBottom="10dp" android:paddingLeft="10dp" android:paddingRight="10dp" android:paddingTop="10dp"> <TextView android:id="@+id/tip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="下拉刷新" android:textSize="15sp" /> <TextView android:id="@+id/update_last_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_horizontal" /> </LinearLayout></RelativeLayout>
mainActivity布局:
<?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:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.he.sample.MainActivity"> <com.example.he.sample.myListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="wrap_content"></com.example.he.sample.myListView></RelativeLayout>
myListView:
/** * header下拉时的三种种状态,UN_PREPARE表示滑动的幅度不够不需要刷新,PREPARE表示的含义是现在松手就能刷新,REFRESH表示正在刷新 */enum State { UN_PREPARE, PREPARE, REFRESH}public class myListView extends ListView { private View header; private int headerHeight; private int startY; private boolean top;//用于判断是否在顶部滑动 private boolean firstState = true;//是否是第一次进行状态判断 private State state = State.UN_PREPARE;//滑动的状态,用于listView滑动事件的处理,见MainActivity.class private TextView title; private ImageView image; private ProgressBar bar; public myListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context); } public myListView(Context context) { super(context); initView(context); } public myListView(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } /** * 加载header视图 * * @param context */ private void initView(Context context) { header = LayoutInflater.from(context).inflate(R.layout.head, null); title = (TextView) header.findViewById(R.id.tip); image = (ImageView) header.findViewById(R.id.refresh); bar = (ProgressBar) header.findViewById(R.id.progress); header.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);//测量head headerHeight = header.getMeasuredHeight();//获取高度 topPadding(-headerHeight); this.addHeaderView(header); } /** * 修改header的PaddingTop值达到隐藏header、随着滑动慢慢出现的效果 * * @param topPadding */ protected void topPadding(int topPadding) { header.setPadding(header.getPaddingLeft(), topPadding, header.getPaddingRight(), header.getPaddingBottom()); header.invalidate(); } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: int t = this.getFirstVisiblePosition(); //t为0表示到达屏幕顶部 if (t == 0) { top = true; startY = (int) ev.getY(); } break; case MotionEvent.ACTION_UP: top = false; firstState = true; //在状态2时松手则切换到状态3的视图 if (state == State.PREPARE) refreshView(State.REFRESH, 0); //在状态1时松手则恢复原样 if (state == State.UN_PREPARE) topPadding(-headerHeight); break; case MotionEvent.ACTION_MOVE: if (top) onMove(ev); break; } return super.onTouchEvent(ev); } /** * 手指正在滑动时进行状态判断 * @param event */ private void onMove(MotionEvent event) { int lastY = (int) event.getY(); int space = lastY - startY; int padding = space - headerHeight; Log.i("padding", "" + padding); //状态1 if (padding < 30) { Log.i("state", "1"); if (firstState) refreshView(State.UN_PREPARE, padding); } //状态2 else if (padding > 30 && padding < 100) { firstState = false; refreshView(State.PREPARE, padding); } } /** * 根据不同的状态,完成相应的操作 */ private void refreshView(State s, int padding) { switch (s) { case UN_PREPARE: topPadding(padding); state = State.UN_PREPARE;//更新状态 bar.setVisibility(View.GONE); image.setVisibility(View.VISIBLE); title.setText("下拉刷新"); break; case PREPARE: image.setVisibility(View.VISIBLE); bar.setVisibility(View.GONE); topPadding(padding); state = State.PREPARE;//更新状态 //更新header中的视图 /** * 创建旋转动画达到向下的箭头朝上的目的,旋转180度,以自身为中心 */ RotateAnimation animation = new RotateAnimation(0, 180, RotateAnimation.RELATIVE_TO_SELF, 0.5F, RotateAnimation.RELATIVE_TO_SELF, 0.5F); animation.setDuration(0);//0毫秒内完成效果 animation.setFillAfter(true);//图片的显示为执行动画后的样子 image.startAnimation(animation); title.setText("松手进行刷新"); topPadding(padding); break; case REFRESH: image.setVisibility(View.GONE);//隐藏image bar.setVisibility(View.VISIBLE);//显示bar //更新header中的视图 image.clearAnimation();//清除image上的动画 title.setText("正在刷新"); state = State.REFRESH;//更新状态 break; } } public int getHeaderHeight() { return headerHeight; } public State getState() { return state; }}
MainActivity:
public class MainActivity extends AppCompatActivity { private static final int OK = 1; private myListView listView; private ArrayAdapter<Integer> adapter; private int headerHeight; private List<Integer> list; private Random random = new Random(47);//随机数 private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case OK: adapter.notifyDataSetChanged();//刷新数据 listView.topPadding(-headerHeight);//隐藏header break; } } }; @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (myListView) findViewById(R.id.lv); headerHeight = listView.getHeaderHeight(); list = new ArrayList<Integer>(); initList(); adapter = new ArrayAdapter<Integer>(this, android.R.layout.simple_list_item_1, list); listView.setAdapter(adapter); /** * listView的滑动监听 */ listView.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { //正在刷新则刷新数据 if (listView.getState() == State.REFRESH) { onRefresh(); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }); } private void initList() { for (int i = 0; i < 50; i++) { list.add(random.nextInt(50)); } } /** * 更新数据 */ private void onRefresh() { new Thread(new Runnable() { @Override public void run() { Message message = new Message(); message.what = OK; for (int i : list) { list.set(i, random.nextInt(50)); } handler.sendMessageDelayed(message, 2000);//2s以后发送message } }).start(); }}
源码地址:点击打开链接
在自己实现的下拉刷新的基础上添加了ListView的滑动删除,关于滑动删除的教程请看这篇文章:点击打开链接,但是这位博主的代码是不适合添加了header的ListView的,如果完全按文中代码加到我这个项目中会出现部分item无法滑动的问题,只需将文中的
//我们想知道当前点击了哪一行 int position = pointToPosition(x, y); if (position != INVALID_POSITION) { DataHolder data = (DataHolder) getItemAtPosition(position); itemRoot = data.rootView; }修改为
int position = pointToPosition(x, y);int firstPosition = getFirstVisiblePosition();if (position != INVALID_POSITION) {curView = (ScrollDeleteLinearLayout) getChildAt(position - firstPosition);}
其实官方给我们提供了SwipeRefreshLayout可用于ListView的刷新,它已经帮我们把内部实现封装好了,Demo:点击打开链接
ListView的上拉加载更多和下拉刷新的代码基本上是一样的,只不过不是添加header而是添加footer,其他实现基本相同,有个要注意的地方是,由于ListView添加数据能直接显示出来,所以添加的位置要做变动否则看不出效果
下拉加载更多的Demo:点击打开链接
0 0
- ListView的下拉刷新、滑动删除和上拉加载更多
- listview的下拉刷新和上拉加载更多
- listview的上拉加载更多和下拉刷新
- 自定义ListView的下拉刷新和上拉加载更多
- ListView下拉刷新和上拉加载更多的实现
- listview下拉刷新 上拉(滑动分页)加载更多
- listview下拉刷新 上拉(滑动分页)加载更多
- listview下拉刷新 上拉(滑动分页)加载更多
- listview下拉刷新 上拉(滑动分页)加载更多
- listview下拉刷新 上拉(滑动分页)加载更多
- listview下拉刷新 上拉(滑动分页)加载更多
- listview下拉刷新 上拉(滑动分页)加载更多
- 仿QQ实现ListView中item的左右滑动同时实现ListView的上拉刷新和下拉加载更多
- 带有上拉加载下拉刷新和可滑动删除功能的ListView的简单实现
- 下拉刷新、上拉获取更多、左右滑动的ListView
- Listview 下拉刷新,上拉加载更多
- Listview下拉刷新上拉加载更多
- 下拉刷新,上拉加载更多ListView
- HDU 2709 Sumsets 递推
- 1023. Have Fun with Numbers (20)?
- rtl8192 调试
- Java Web Start 发布计算器应用程序
- Android微信分享
- ListView的下拉刷新、滑动删除和上拉加载更多
- 132. Palindrome Partitioning II
- 计算器应用程序
- 第十二周oj项目D汉罗塔
- Objective-C编程 - 关于Block的要点
- Linux 内核资源限制 -- 栈限制
- 基于opencv的简单视频处理类示例
- adb
- openv直方图均衡化综合示例