上拉刷新、下拉加载
来源:互联网 发布:巨人网络现在怎么样 编辑:程序博客网 时间:2024/06/07 14:17
思路:
listView来做
效果图:
mainActivity
package com.maker_huige.myapplication;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.view.ViewGroup;import android.view.Window;import android.widget.BaseAdapter;import android.widget.TextView;import com.maker_huige.ui.RejectListView;import java.util.ArrayList;public class MainActivity extends AppCompatActivity { RejectListView rl; ArrayList<String> strings; MyAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); initUI(); rl.setRejectListener(new RejectListView.OnRejectListener(){ @Override public void onReject() { new Thread(){ @Override public void run() { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } strings.add(0,"我是下拉出来的数据"); runOnUiThread(new Runnable() { @Override public void run() { adapter.notifyDataSetChanged(); rl.onRejectComplete();//刷新结束,恢复界面效果 } }); } }.start(); } @Override public void onLoadMore() { new Thread(){ @Override public void run() { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } strings.add("我是加载更多出来的数据"); runOnUiThread(new Runnable() { @Override public void run() { adapter.notifyDataSetChanged(); rl.onRejectComplete();//刷新结束,恢复界面效果 } }); } }.start(); } }); adapter = new MyAdapter(); rl.setAdapter(adapter); } private void initUI() { rl = (RejectListView) findViewById(R.id.listview); strings = new ArrayList<String>(); for(int i = 0; i< 30; i++){ strings.add("这是一个listView" + i); } } class MyAdapter extends BaseAdapter{ @Override public int getCount() { return strings.size(); } @Override public View getView(int i, View view, ViewGroup viewGroup) { TextView textView = new TextView(getApplicationContext()); textView.setText(getItem(i)); textView.setTextSize(26f); return textView; } @Override public String getItem(int i) { return strings.get(i); } @Override public long getItemId(int i) { return i; } }}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout 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:orientation="vertical" tools:context="com.maker_huige.myapplication.MainActivity"> <com.maker_huige.ui.RejectListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent"> </com.maker_huige.ui.RejectListView></LinearLayout>
RejectListView
package com.maker_huige.ui;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.animation.Animation;import android.view.animation.RotateAnimation;import android.widget.AbsListView;import android.widget.ImageView;import android.widget.ListView;import android.widget.ProgressBar;import android.widget.TextView;import com.maker_huige.myapplication.R;import java.text.SimpleDateFormat;public class RejectListView extends ListView implements AbsListView.OnScrollListener{ View mHeader_view; int mMeasuredHeight; float Down_y; float Move_y; public static final int PULL_TO_REFRESH = 0;//下拉刷新 public static final int RELEASE_REFRESH = 1;//释放刷新 public static final int REFRESHING = 2; //刷新中 int currentState = PULL_TO_REFRESH; RotateAnimation rotate_up; RotateAnimation rotate_dow; ImageView mArrowView; ProgressBar mPb; TextView mTitle; TextView mDes; View mFooterView; boolean isLoadMore; int mFooterdHeight; private OnRejectListener onRejectListener; public RejectListView(Context context) { super(context); init(); } public RejectListView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public RejectListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { initHeader(); initAnimation(); initFooter(); setOnScrollListener(this); } private void initFooter() { mFooterView = View.inflate(getContext(), R.layout.listview_footer, null); mFooterView.measure(0,0); mFooterdHeight = mFooterView.getMeasuredHeight(); addFooterView(mFooterView); } private void initAnimation() { // 向上转, 围绕着自己的中心, 逆时针旋转0 -> -180. rotate_up = new RotateAnimation(0f,-180f, Animation.RELATIVE_TO_SELF,0.5f, Animation.RELATIVE_TO_SELF,0.5f); rotate_up.setDuration(500); rotate_up.setFillAfter(true); // 向下转, 围绕着自己的中心, 逆时针旋转 -180 -> -360 rotate_dow = new RotateAnimation(-180f,-360f, Animation.RELATIVE_TO_SELF,0.5f, Animation.RELATIVE_TO_SELF,0.5f); rotate_dow.setDuration(500); rotate_dow.setFillAfter(true); } private void initHeader() { mHeader_view = View.inflate(getContext(), R.layout.listview_header,null); //提前手动测量宽高 mHeader_view.measure(0,0); mMeasuredHeight = mHeader_view.getMeasuredHeight(); mHeader_view.setPadding(0,-mMeasuredHeight,0,0); mArrowView = (ImageView) mHeader_view.findViewById(R.id.arrowView); mPb = (ProgressBar) mHeader_view.findViewById(R.id.pb); mTitle = (TextView) mHeader_view.findViewById(R.id.tv_title); mDes = (TextView) mHeader_view.findViewById(R.id.tv_des); addHeaderView(mHeader_view); } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()){ case MotionEvent.ACTION_DOWN: Down_y = ev.getY(); break; case MotionEvent.ACTION_MOVE: Move_y = ev.getY(); if (currentState == REFRESHING){ return super.onTouchEvent(ev); } float offset = Move_y - Down_y;//移动的偏移量 //只有偏移量>0,并且当前第一个可见条目索引是0,才放大头部 if(offset>0 && getFirstVisiblePosition() == 0){// int paddingTop = -自身高度 + 偏移量 int paddingTop = (int)(-mMeasuredHeight + offset); mHeader_view.setPadding(0,paddingTop,0,0); if(paddingTop >= 0 && currentState != RELEASE_REFRESH){//头部完全显示 //切换成释放刷新模式 currentState = RELEASE_REFRESH; //更新最新的状态值,并更新头部内容 updateHeader(); }else if(paddingTop <0 && currentState != PULL_TO_REFRESH){ //切换成下拉刷新模式 currentState = PULL_TO_REFRESH; //更新最新的状态值,并更新头部内容 updateHeader(); } return true;//当前事件被我们处理并消费 } break; case MotionEvent.ACTION_UP: if (currentState == PULL_TO_REFRESH){ mHeader_view.setPadding(0,-mMeasuredHeight,0,0); }else if (currentState == RELEASE_REFRESH){ mHeader_view.setPadding(0,0,0,0); currentState = REFRESHING; updateHeader(); } break; } return super.onTouchEvent(ev); } private void updateHeader() { switch (currentState){ case RELEASE_REFRESH://释放刷新模式 mArrowView.startAnimation(rotate_up); mTitle.setText("释放刷新"); break; case PULL_TO_REFRESH://下拉刷新模式 mArrowView.startAnimation(rotate_dow); mTitle.setText("下拉刷新"); break; case REFRESHING://刷新中 mArrowView.clearAnimation(); mArrowView.setVisibility(View.INVISIBLE); mPb.setVisibility(View.VISIBLE); mTitle.setText("正在刷新中..."); if (onRejectListener != null){ onRejectListener.onReject();//通知调用者,让其网络加载更多数据 } break; } } public void onRejectComplete() { if (isLoadMore){ //加载更多 mFooterView.setPadding(0,-mFooterdHeight,0,0); isLoadMore = false; }else{ //下拉刷新 currentState = PULL_TO_REFRESH; mTitle.setText("下拉刷新"); mHeader_view.setPadding(0,-mMeasuredHeight,0,0); mPb.setVisibility(View.INVISIBLE); mArrowView.setVisibility(View.VISIBLE); String time = getTime(); mDes.setText("最后刷新时间" + time); } } public void setRejectListener(OnRejectListener onRejectListener) { this.onRejectListener =onRejectListener; } private String getTime() { long millis = System.currentTimeMillis(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return format.format(millis); } /**会用到原码的一些常量 * int SCROLL_STATE_FLING = 2;滑翔 int SCROLL_STATE_IDLE = 0;空闲 int SCROLL_STATE_TOUCH_SCROLL = 1;触摸滑动 * @param absListView * @param i */ @Override public void onScrollStateChanged(AbsListView absListView, int i) { if (isLoadMore){ return; } //状态更新的时候 if(i == SCROLL_STATE_IDLE && getLastVisiblePosition() >= getCount()-1){ isLoadMore = true; mFooterView.setPadding(0,0,0,0); setSelection(getCount()); if (onRejectListener != null){ onRejectListener.onLoadMore(); } } } @Override public void onScroll(AbsListView absListView, int i, int i1, int i2) { //滑动过程 } public interface OnRejectListener{ void onReject();//下拉刷新 void onLoadMore();//加载更多 }}
listview_header.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:padding="5dp" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:layout_width="50dp" android:layout_height="50dp"> <ImageView android:id="@+id/arrowView" android:layout_gravity="center" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@mipmap/common_listview_headview_red_arrow"/> <ProgressBar android:id="@+id/pb" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="invisible" /> </FrameLayout> <LinearLayout android:layout_marginLeft="10dp" android:gravity="center" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/tv_title" android:textColor="#f00" android:textSize="26dp" android:text="下拉更新" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/tv_des" android:singleLine="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#000" android:textSize="16dp" android:text="2016年12月27日15:28:11" /> </LinearLayout></LinearLayout>
listview_footer.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:gravity="center" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <ProgressBar android:layout_margin="5dp" android:layout_width="50dp" android:layout_height="50dp" /> <TextView android:layout_marginLeft="5dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="26dp" android:textColor="#f00" android:text="加载更多" /></LinearLayout>
0 0
- 上拉加载 下拉刷新
- 下拉刷新 * 上拉加载
- 上拉刷新 下拉加载
- 下拉刷新,上拉加载
- 上拉刷新下拉加载
- 下拉刷新,上拉加载
- 上拉刷新,下拉加载
- 上拉刷新下拉加载
- 上拉刷新下拉加载
- 上拉加载,下拉刷新
- 上拉刷新,下拉加载
- 下拉刷新,上拉加载
- 上拉加载,下拉刷新
- 上拉刷新,下拉加载
- 下拉加载上拉刷新
- 下拉刷新-上拉加载
- 上拉刷新,下拉加载
- 上拉加载,下拉刷新
- Android软键盘(五)如何判断软键盘是否显示
- 【Java】十款经典游戏的Java版本(开源)
- java 进程和线程的区别与联系
- Bug 14275161 - ORA-600 [rwoirw: check ret val] on CTAS with predicate move around
- 438. Find All Anagrams in a String#3(Done)
- 上拉刷新、下拉加载
- UVa - 11300 - Spreading the Wealth ( 数学推导 )
- 第43篇白板同步延迟问题解决方案解决(五)及data传输模式分析(二)
- Android Fragment 真正的完全解析(上)
- EventBus使用
- hdu 3749 点双连通分量
- 仿百度地图
- ADB常用命令
- 数据结构课程设计