赞
踩
思路:
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>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。