android虽然定义了种类非常丰富的控件,但是有的时候这些自定义的控件还是不能满足我的要求,为了能够适配更多的需求,我们需要在原有的基础上进行自定义控件。
今天我向大家介绍的就是android中最常见的刷新类控件。因为我们最近正在参加一个项目,在项目组长的带领下,我学到了很多的东西,这对我的android技术的提升非常大,定义一个自定义控件可能不是很难,但是如何让这个自定义控件更加有效、更加快速地运行。
首先我们需要建立一个自定义控件类:
package com.example.ui.widget;
import com.example.androidtest.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
/**
* 下拉刷新控件
*
* @author JeffLee
* @version 1.0
* @created 2014-10-21
*/
public class PullToRefreshListView extends ListView implements OnScrollListener {
private final static String TAG = "PullToRefreshListView";
private static final int MAX_Y_OVERSCROLL_DISTANCE = 100;
private Context mContext;
private int mMaxYOverscrollDistance;
// 下拉刷新标志
private final static int PULL_To_REFRESH = 0;
// 松开刷新标志
private final static int RELEASE_To_REFRESH = 1;
// 正在刷新标志
public final static int REFRESHING = 2;
// 刷新完成标志
private final static int DONE = 3;
private LayoutInflater inflater;
private LinearLayout headView;
private TextView tipsTextview;
private TextView lastUpdatedTextView;
private ImageView arrowImageView;
private ProgressBar progressBar;
// 用来设置箭头图标动画效果
private RotateAnimation animation;
private RotateAnimation reverseAnimation;
// 用于保证startY的值在一个完整的touch事件中只被记录一次
private boolean isRecored;
private int headContentWidth;
private int headContentHeight;
private int headContentOriginalTopPadding;
private int startY;
private int firstItemIndex;
private int currentScrollState;
private int state;
private boolean isBack;
public OnRefreshListener refreshListener;
public OnLoadMoreListener loadMoreListener;
// -- footer view
private PullToRefreshFooter mFooterView;
private boolean mEnablePullLoad;
private boolean mPullLoading = false;
private boolean mIsFooterReady = false;
private float mFirstY = -1; // save event y
private boolean bloading = false;
public PullToRefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public PullToRefreshListView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public int getState() {
return state;
}
private void init(Context context) {
mContext = context;
final DisplayMetrics metrics = mContext.getResources()
.getDisplayMetrics();
final float density = metrics.density;
mMaxYOverscrollDistance = (int) (density * MAX_Y_OVERSCROLL_DISTANCE);
// 设置滑动效果
animation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF,
0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(200);
animation.setFillAfter(true);
reverseAnimation = new RotateAnimation(-180, 0,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
reverseAnimation.setInterpolator(new LinearInterpolator());
reverseAnimation.setDuration(200);
reverseAnimation.setFillAfter(true);
inflater = LayoutInflater.from(context);
headView = (LinearLayout) inflater.inflate(
R.layout.pull_to_refresh_head, null);
arrowImageView = (ImageView) headView
.findViewById(R.id.head_arrowImageView);
// arrowImageView.setMinimumWidth(50);
// arrowImageView.setMinimumHeight(50);
progressBar = (ProgressBar) headView
.findViewById(R.id.head_progressBar);
tipsTextview = (TextView) headView.findViewById(R.id.head_tipsTextView);
lastUpdatedTextView = (TextView) headView
.findViewById(R.id.head_lastUpdatedTextView);
headContentOriginalTopPadding = headView.getPaddingTop();
measureView(headView);
headContentHeight = headView.getMeasuredHeight();
headContentWidth = headView.getMeasuredWidth();
headView.setPadding(headView.getPaddingLeft(), -1 * headContentHeight,
headView.getPaddingRight(), headView.getPaddingBottom());
headView.invalidate();
addHeaderView(headView);
// init footer view
mFooterView = new PullToRefreshFooter(context);
setOnScrollListener(this);
}
@Override
public void setAdapter(ListAdapter adapter) {
super.setAdapter(adapter);
}
// 需要有加载更多功能时候的设置adapter的方式
public void setLoadMoreAdapter(ListAdapter adapter) {
setAdapter(adapter);
addFooterView();
}
public void addFooterView() {
if (mIsFooterReady == false) {
mIsFooterReady = true;
mFooterView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 不在下拉刷新状态,以及没有全部加载,且不在加载更多的状态下进行点击刷新
if (state != REFRESHING && !mPullLoading) { //
startLoadMore();
}
}
});
addFooterView(mFooterView);
}
}
/**
* stop load more, reset