【框架】RefreshListView下拉刷新

布局:

<com.example.administrator.d30_myrefreshlistview.RefreshListView
android:id="@+id/refresh_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="10dp"
>
<ImageView
android:id="@+id/image_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/indicator_arrow"
android:layout_centerInParent="true"
/>
<ProgressBar
android:id="@+id/pb_rotate"
android:layout_width="30dp"
android:layout_height="30dp"
android:indeterminate="false"
android:indeterminateDuration="1000"
android:indeterminateDrawable="@drawable/indecate_rotate"
android:layout_centerInParent="true"
android:visibility="invisible"
/>
</RelativeLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
>
<TextView
android:id="@+id/tv_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textColor="#aa000000"
android:text="下拉刷新"
android:layout_marginBottom="10dp"
/>
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="@android:color/darker_gray"
android:text="最后刷新"
android:layout_marginBottom="10dp"
/>
</LinearLayout>
<ProgressBar
android:layout_width="30dp"
android:layout_height="30dp"
android:id="@+id/pb_rotate_footer"
android:indeterminateDrawable="@drawable/indecate_rotate"
android:indeterminateDuration="1000"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="正在加载..."
android:textSize="20sp"
android:textColor="#aa000000"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"/>

代码:

/*
1:创建集合,准备数据。
2:创建适配器。
3:设置适配器。
*/
public class MainActivity extends AppCompatActivity {
private RefreshListView listview;
private List<String> strs;
private MyAdapter adapter;
private boolean flag = true;//true表示下拉刷新,false表示上拉加载。
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
//下载数据已经完成。
//更新界面。
adapter.notifyDataSetChanged();
//RefreshListView界面要还原初始状态。
listview.completeView();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview = (RefreshListView) findViewById(R.id.refresh_listview);
//添加监听
listview.setOnRefreshListener(new RefreshListView.onRefreshListener() {
@Override
public void onPullRefresh() {
//模拟请求网络数据。
requestDataFromServer(true);
} @Override
public void onLoadMore() {
//模拟请求下一页网络数据。
requestDataFromServer(false);
}
});
initData();
adapter = new MyAdapter();
listview.setAdapter(adapter);
} private void requestDataFromServer(final boolean flag) {
new Thread(new Runnable() {
@Override
public void run() {
SystemClock.sleep(3000);
//1;添加新的数据。
if(flag) {
strs.add(0, "下拉刷新的数据");
//2;通知ui线程更新界面。
handler.sendEmptyMessage(1);
}else{
//上拉加载。
strs.add("加载更多的数据"+1);
strs.add("加载更多的数据"+2);
strs.add("加载更多的数据"+3);
handler.sendEmptyMessage(1);
}
}
}).start();
} private void initData() {
strs = new ArrayList<String>();
for(int i=0;i<18;i++){
strs.add("listview 原来的数据"+i);
}
}
class MyAdapter extends BaseAdapter{ @Override
public int getCount() {
return strs.size();
} @Override
public Object getItem(int position) {
return strs.get(position);
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView item_view = new TextView(MainActivity.this);
item_view.setPadding(0,10,0,10);
//设置字体
item_view.setTextSize(20);
//设置内容
item_view.setText(strs.get(position));
return item_view;
}
}
}
public class RefreshListView extends ListView implements AbsListView.OnScrollListener {
private View headerView;
private int headerView_height;
private int down_y;//按下的时候y的坐标
private static final int PULL_REFRESH = 0;//表示下拉刷新--允许下拉刷新
private static final int RELEASE_REFRESH = 1;//表示松开刷新--允许松开刷新
private static final int REFRESHING = 2;//表示正在刷新--头部完全显示。---正在请求网络数据。
private int current_state = PULL_REFRESH;//最初状态
private ImageView image_arrow;//箭头控件
private TextView tv_state, tv_time;//状态文本框,时间文本显示框。
private ProgressBar pb_rotate;//旋转动画。
private RotateAnimation downAnimation, upAnimation;
private int padding_top;//表示headview的padding_top;
private onRefreshListener listener;//使用者传过来的实现的对象。
private View footView;//底部控件。
private int footView_height;//底部控件的高度。
public RefreshListView(Context context) {
super(context);
init();
} public RefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
} private void init() {
//设置监听
setOnScrollListener(this);
initHeaderView();
initRotateAnimation();//创建2个动画
initFooterView();
} private void initFooterView() {
footView = View.inflate(getContext(),R.layout.layout_footer,null);
footView.measure(0, 0);
footView_height =footView.getMeasuredHeight();
//设置隐藏
footView.setPadding(0, -footView_height, 0, 0);
addFooterView(footView);
} private void initRotateAnimation() {
//往下动画。
downAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
downAnimation.setDuration(300);
downAnimation.setFillAfter(true);
//往上动画
upAnimation = new RotateAnimation(-180, -360, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
upAnimation.setDuration(300);
upAnimation.setFillAfter(true);
} private void initHeaderView() {
headerView = View.inflate(getContext(), R.layout.layout_header, null);
image_arrow = (ImageView) headerView.findViewById(R.id.image_arrow);
tv_state = (TextView) headerView.findViewById(R.id.tv_state);
tv_time = (TextView) headerView.findViewById(R.id.tv_time);
pb_rotate = (ProgressBar) headerView.findViewById(R.id.pb_rotate);
//设置头部控件的一些属性。--下拉刷新主要是通过更改头部控件的padding值来隐藏和显示的。
//先要计算头部控件的高度。
headerView.measure(0, 0);//先执行onMearsure();
headerView_height = headerView.getMeasuredHeight();
headerView.setPadding(0, -headerView_height, 0, 0);//隐藏头部
//添加给listview.
addHeaderView(headerView);
} @Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
down_y = (int) ev.getY();
//按下状态
break;
case MotionEvent.ACTION_MOVE:
//滑动的状态
//1:获得当前的y坐标
int y = (int) ev.getY();
//2:计算滑动了多远。
int delta_y = y - down_y;//往下滑delta_y>0,,往上滑 delta_y<0
padding_top = delta_y + (-headerView_height);
//将值设置给头部控件。
if (padding_top > -headerView_height) {//说明头部要么正好隐藏要么显示一部分或者更多。
headerView.setPadding(0, padding_top, 0, 0);
if (padding_top >= 0 && current_state == PULL_REFRESH) {
current_state = RELEASE_REFRESH;//松开刷新。
//变化
//1:箭头往上执行动画
//2:文字改变。----tv_state---松开刷新。
refreshView();
} else if (padding_top < 0 && current_state == RELEASE_REFRESH) {
current_state = PULL_REFRESH;
//变化
// 1:箭头往下执行动画
//2:文字改变---下拉刷新
refreshView();
}
return true;//消费这个事件。意思就是让listview不要有滚动的行为,杜绝listview滚动。 }
break;
case MotionEvent.ACTION_UP:
//松开的状态
if(current_state==PULL_REFRESH){
//隐藏
headerView.setPadding(0,-headerView_height,0,0);
}else if(current_state==RELEASE_REFRESH){
//更改状态。
current_state = REFRESHING;
//更新界面。
refreshView();
//5:要请求网络数据,
if(listener!=null){
listener.onPullRefresh();//请求新的数据。
}
}
break;
}
return super.onTouchEvent(ev);
}
private boolean flag;//true表示数据已经显示完。
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(scrollState==SCROLL_STATE_IDLE && flag){
isLoadMore = true;
//请求下一页
//1:底部要显示。
footView.setPadding(0,0,0,0);
//2:请求下一页数据。
if(listener!=null){
listener.onLoadMore();
}
}
} @Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
flag = firstVisibleItem+visibleItemCount==totalItemCount;
} public interface onRefreshListener{
void onPullRefresh();
void onLoadMore();
}
public void setOnRefreshListener(onRefreshListener listener){
this.listener = listener;
}
private void refreshView() {
switch (current_state) {
case RELEASE_REFRESH:
//动画
//1:箭头往上执行动画
image_arrow.startAnimation(upAnimation);
//2:文字改变。----tv_state---松开刷新。
tv_state.setText("松开刷新");
break;
case PULL_REFRESH:
// 1:箭头往下执行动画
image_arrow.startAnimation(downAnimation);
//2:文字改变---下拉刷新
tv_state.setText("下拉刷新");
break;
case REFRESHING:
//1:头部要正常显示。
headerView.setPadding(0, 0, 0, 0);
//2:箭头隐藏
image_arrow.setVisibility(INVISIBLE);
//3:进度条显示。
pb_rotate.setVisibility(VISIBLE);
//4:文字更改。
tv_state.setText("正在刷新");
break; }
}
private boolean isLoadMore;//true表示上拉加载,false表示下拉刷新。
//还原初始化状态。
public void completeView(){
if(!isLoadMore) {
//1:箭头要显示。
image_arrow.clearAnimation();//这个时候有可能箭头有可能在执行动画。将动画进行清除。
image_arrow.setVisibility(VISIBLE);
//2:进度动画要隐藏
pb_rotate.setVisibility(INVISIBLE);
//3:tv_state文字改变为下拉刷新。
tv_state.setText("下拉刷新");
//4;状态---更改为下拉刷新。
current_state = PULL_REFRESH;
//5:tv_time更改为当前的时间
tv_time.setText(getTime());
//隐藏
headerView.setPadding(0, -headerView_height, 0, 0);
}else{
footView.setPadding(0,-footView_height,0,0);
isLoadMore = false;
// 定位到最后一条。
setSelection(getCount()-1);//定位到最后一条数据。
}
}
private String getTime(){
SimpleDateFormat format = new SimpleDateFormat("yyyy MM dd HH:mm:ss");
return format.format(new Date());
}
}
上一篇:喵哈哈村的魔法考试 Round #1 (Div.2) 题解


下一篇:喵哈哈村的魔法考试 Round #7 (Div.2) 题解