Activity定義使用的相關的屬性:
/** 活動精選距離屏幕的座標 */
private int[] locationActive = new int[2];
/** title標題距離屏幕的座標 */
private int locationTitleY;
/** 是否手指向上滑動(startY>MoveY) */
private boolean isMoveUp;
/** 是否執行title顯示或隱藏動畫 */
private boolean isRunAnim;
/** 是否顯示 */
private boolean isTitleShow;
/** title的高度 */
int titleHeight;
初始化相關位置信息,:注必須是在加載完頁面之後調用此代碼,否則獲取的location都爲0
int[] locationTitle = new int[2];
rlActTitleParent.getLocationOnScreen(locationTitle);
titleHeight = getResources().getDimensionPixelSize(R.dimen.home_title_height);
locationTitleY = locationTitle[1] + titleHeight;
location詳解:http://blog.csdn.net/lvxiangan/article/details/19971509
lvWelfare.setOnMoveListener(new OnMoveListener() {
@Override
public void onMoveList(Boolean isShow) {// 滑動顯示隱藏title
isMoveUp = isShow;
showTitle();
}
});
lvWelfare.setOnScrollListenerExtra(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {// 這個方法只有鬆開手纔會執行
if (scrollState == SCROLL_STATE_IDLE) {// setOnMoveListener OnScrollListener結合滑動顯示隱藏title
showTitle();
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
/***
*
* @description 顯示title
* @author zhongwr
* @params
* @update 2016年1月28日 下午5:56:35
*/
private void showTitle() {
if (isRunAnim) {
return;
}
rlActiveTitleParent.getLocationOnScreen(locationActive);
if (isMoveUp) {// 手指向下滑動(starty<MoveY)
if (locationActive[1] > locationTitleY) {
if (!isTitleShow) {
isTitleShow = true;
rlActTitleParent.setVisibility(View.VISIBLE);
setShowTitleAnimator(true);
}
}
} else {// 手指向上滑動:starty>MoveY
if (locationActive[1] <= locationTitleY) {
if (isTitleShow) {
isTitleShow = false;
// rlActTitleParent.setVisibility(View.GONE);
setShowTitleAnimator(false);
}
}
}
}
/**
*
* @description 設置動畫
* @author zhongwr
* @params
* @update 2016年1月28日 下午6:00:45
*/
private void setShowTitleAnimator(final boolean isShow) {
ValueAnimator animator;
if (isShow) {// 顯示
animator = ValueAnimator.ofFloat(-titleHeight, 0).setDuration(200);
} else {// 隱藏
animator = ValueAnimator.ofFloat(0, -titleHeight).setDuration(200);
}
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float translationY = (Float) animation.getAnimatedValue();
// 設置控件rlActTitleParent沿Y移動動畫,移動位置是translationY
ViewHelper.setTranslationY(rlActTitleParent, translationY);
}
});
animator.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator arg0) {
isRunAnim = true;
}
@Override
public void onAnimationRepeat(Animator arg0) {
}
@Override
public void onAnimationEnd(Animator arg0) {
isRunAnim = false;
if (!isShow) {
rlActTitleParent.setVisibility(View.GONE);
}
}
@Override
public void onAnimationCancel(Animator arg0) {
isRunAnim = false;
}
});
animator.start();
}
lvWelfare:Listview(集合上拉加載更多,下拉刷新功能;以上定義的回調接口以及onTouchEvent()都在這個類中
public class PullToRefreshListView extends ListView implements OnScrollListener {
private static final String TAG = "ElasticScrollView";
private final static int RELEASE_To_REFRESH = 0;
private final static int PULL_To_REFRESH = 1;
private final static int REFRESHING = 2;
private final static int DONE = 3;
private final static int LOADING = 4;
// 實際的padding的距離與界面上偏移距離的比例
private final static int RATIO = 3;
private int headContentWidth;
private int headContentHeight;
private LinearLayout innerLayout;
private LinearLayout headView;
private ProgressBar arrowImageView;
private ProgressBar progressBar;
private TextView tipsTextview;
private TextView lastUpdatedTextView;
private OnRefreshListener refreshListener;
private OnMoveListener mOnMoveListener;
private OnScrollStateChangedListener mScrollStateChangedListener;
private boolean isRefreshable;
private int state;
private boolean isBack;
// private RotateAnimation animation;
// private RotateAnimation reverseAnimation;
private boolean canReturn;
private boolean isRecored;
private int startY;
private String down_str = "下拉刷新";
private String release_str = "鬆開刷新";
private OnPullUpListener pullUpListener;
private Context mContext;
public PullToRefreshListView(Context context) {
super(context);
init(context);
}
public PullToRefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
mContext = context;
LayoutInflater inflater = LayoutInflater.from(context);
View view = getFirstHeadView();
if(view != null)
{
addHeaderView(view);
}
headView = (LinearLayout) inflater.inflate(R.layout.mylistview_head, null);
arrowImageView = (ProgressBar) headView.findViewById(R.id.head_arrowImageView);
progressBar = (ProgressBar) headView.findViewById(R.id.head_progressBar);
tipsTextview = (TextView) headView.findViewById(R.id.head_tipsTextView);
lastUpdatedTextView = (TextView) headView.findViewById(R.id.head_lastUpdatedTextView);
measureView(headView);
headContentHeight = headView.getMeasuredHeight();
headContentWidth = headView.getMeasuredWidth();
headView.setPadding(0, -1 * headContentHeight, 0, 0);
headView.invalidate();
Log.i("size", "width:" + headContentWidth + " height:" + headContentHeight);
addHeaderView(headView);
// animation = new RotateAnimation(0, -180,
// Animation.RELATIVE_TO_SELF, 0.5f,
// Animation.RELATIVE_TO_SELF, 0.5f);
// animation.setInterpolator(new LinearInterpolator());
// animation.setDuration(250);
// 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);
state = DONE;
isRefreshable = false;
canReturn = false;
}
public View getFirstHeadView()
{
return null;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
try {
if (isRefreshable) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (getScrollY() == 0 && !isRecored) {
isRecored = true;
startY = (int) event.getY();
Log.i(TAG, "在down時候記錄當前位置‘");
}
break;
case MotionEvent.ACTION_UP:
if (state != REFRESHING && state != LOADING) {
if (state == DONE) {
// 什麼都不做
}
if (state == PULL_To_REFRESH) {
state = DONE;
changeHeaderViewByState();
onPullUp();
Log.i(TAG, "由下拉刷新狀態,到done狀態");
}
if (state == RELEASE_To_REFRESH) {
state = REFRESHING;
changeHeaderViewByState();
onRefresh();
onPullUp();
Log.i(TAG, "由鬆開刷新狀態,到done狀態");
}
}
isRecored = false;
isBack = false;
break;
case MotionEvent.ACTION_MOVE:
int tempY = (int) event.getY();
if (!isRecored && getScrollY() == 0) {
Log.i(TAG, "在move時候記錄下位置");
isRecored = true;
startY = tempY;
} else {
if (startY < tempY) {
if (mOnMoveListener != null) {
mOnMoveListener.onMoveList(true);
}
} else {
if (mOnMoveListener != null) {
mOnMoveListener.onMoveList(false);
}
}
}
if (state != REFRESHING && isRecored && state != LOADING
&& PullToRefreshListView.this.getFirstVisiblePosition() == 0) {
// 可以鬆手去刷新了
if (state == RELEASE_To_REFRESH) {
canReturn = true;
if (((tempY - startY) / RATIO < headContentHeight) && (tempY - startY) > 0) {
state = PULL_To_REFRESH;
changeHeaderViewByState();
Log.i(TAG, "由鬆開刷新狀態轉變到下拉刷新狀態");
}
// 一下子推到頂了
else if (tempY - startY <= 0) {
state = DONE;
changeHeaderViewByState();
Log.i(TAG, "由鬆開刷新狀態轉變到done狀態");
} else {
// 不用進行特別的操作,只用更新paddingTop的值就行了
}
}
// 還沒有到達顯示鬆開刷新的時候,DONE或者是PULL_To_REFRESH狀態
if (state == PULL_To_REFRESH) {
canReturn = true;
// 下拉到可以進入RELEASE_TO_REFRESH的狀態
if ((tempY - startY) / RATIO >= headContentHeight) {
state = RELEASE_To_REFRESH;
isBack = true;
changeHeaderViewByState();
Log.i(TAG, "由done或者下拉刷新狀態轉變到鬆開刷新");
}
// 上推到頂了
else if (tempY - startY <= 0) {
state = DONE;
changeHeaderViewByState();
Log.i(TAG, "由DOne或者下拉刷新狀態轉變到done狀態");
}
}
// done狀態下
if (state == DONE) {
if (tempY - startY > 0) {
state = PULL_To_REFRESH;
changeHeaderViewByState();
}
}
// 更新headView的size
if (state == PULL_To_REFRESH) {
headView.setPadding(0, -1 * headContentHeight + (tempY - startY) / RATIO, 0, 0);
}
// 更新headView的paddingTop
if (state == RELEASE_To_REFRESH) {
headView.setPadding(0, (tempY - startY) / RATIO - headContentHeight, 0, 0);
}
if (canReturn) {
canReturn = false;
return true;
}
}
break;
}
}
return super.onTouchEvent(event);
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
}
/**
* 顯示“正在刷新”view
*/
public void showRefreshingView() {
state = REFRESHING;
changeHeaderViewByState();
}
// 當狀態改變時候,調用該方法,以更新界面
private void changeHeaderViewByState() {
switch (state) {
case RELEASE_To_REFRESH:
arrowImageView.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
tipsTextview.setVisibility(View.VISIBLE);
lastUpdatedTextView.setVisibility(View.VISIBLE);
// arrowImageView.clearAnimation();
// arrowImageView.startAnimation(animation);
tipsTextview.setText(release_str);
Log.i(TAG, "當前狀態,鬆開刷新");
break;
case PULL_To_REFRESH:
progressBar.setVisibility(View.GONE);
tipsTextview.setVisibility(View.VISIBLE);
lastUpdatedTextView.setVisibility(View.VISIBLE);
arrowImageView.clearAnimation();
arrowImageView.setVisibility(View.VISIBLE);
// 是由RELEASE_To_REFRESH狀態轉變來的
if (isBack) {
isBack = false;
// arrowImageView.clearAnimation();
// arrowImageView.startAnimation(reverseAnimation);
tipsTextview.setText(down_str);
} else {
tipsTextview.setText(down_str);
}
Log.i(TAG, "當前狀態,下拉刷新");
break;
case REFRESHING:
headView.setPadding(0, 0, 0, 0);
progressBar.setVisibility(View.VISIBLE);
arrowImageView.clearAnimation();
arrowImageView.setVisibility(View.GONE);
tipsTextview.setText("正在刷新...");
lastUpdatedTextView.setVisibility(View.VISIBLE);
Log.i(TAG, "當前狀態,正在刷新...");
break;
case DONE:
headView.setPadding(0, -1 * headContentHeight, 0, 0);
progressBar.setVisibility(View.GONE);
arrowImageView.clearAnimation();
arrowImageView.destroyDrawingCache();
progressBar.destroyDrawingCache();
// arrowImageView.setImageResource(R.drawable.head_arrow);
tipsTextview.setText(down_str);
lastUpdatedTextView.setVisibility(View.VISIBLE);
Log.i(TAG, "當前狀態,done");
break;
}
}
private void measureView(View child) {
ViewGroup.LayoutParams p = child.getLayoutParams();
if (p == null) {
p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
}
public void setOnMoveListener(OnMoveListener moveListener) {
this.mOnMoveListener = moveListener;
}
public interface OnMoveListener {
public void onMoveList(Boolean isShow);
}
public void setonRefreshListener(OnRefreshListener refreshListener) {
this.refreshListener = refreshListener;
isRefreshable = true;
}
public interface OnRefreshListener {
public void onRefresh();
}
@SuppressWarnings("deprecation")
public void onRefreshComplete() {
state = DONE;
lastUpdatedTextView.setText("最近更新:" + new Date().toLocaleString());
changeHeaderViewByState();
invalidate();
scrollTo(0, 0);
}
public void setDownStr(String s) {
down_str = s;
}
public void setReleaseStr(String s) {
release_str = s;
}
private void onRefresh() {
if (refreshListener != null) {
if (null != mLoadingMoreListener) {
setFootVisiable(View.GONE, View.GONE, llFootLoadingParent.getVisibility());
}
refreshListener.onRefresh();
}
}
public void addChild(View child) {
innerLayout.addView(child);
}
public void addChild(View child, int position) {
innerLayout.addView(child, position);
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
private void onPullUp() {
if (pullUpListener != null) {
pullUpListener.onPullUp();
}
}
public void setOnPullUpListener(OnPullUpListener pullUpListener) {
this.pullUpListener = pullUpListener;
}
public interface OnPullUpListener {
public void onPullUp();
}
/**
* xml加載完之後會調用這個方法
* */
@Override
protected void onFinishInflate() {
super.onFinishInflate();
}
/** 加載更多的底部 */
private View mFootView;
private RelativeLayout rlFootNoMoreParent;
private LinearLayout llFootLoadingParent;
/** 加載更多的監聽器 */
private OnLoadingMoreListener mLoadingMoreListener;
/** 加載出錯時,點擊加載更多 */
private Button btnReload;
/**沒有更多*/
private TextView tvNoMoreText;
/** 設置上拉加載更多可用 */
public void setLoadingMoreEnable(OnLoadingMoreListener loadingMoreListener) {
this.mLoadingMoreListener = loadingMoreListener;
// 添加底部
mFootView = LayoutInflater.from(mContext).inflate(R.layout.get_more, null);
rlFootNoMoreParent = (RelativeLayout) this.mFootView.findViewById(R.id.rl_no_more_parent);
llFootLoadingParent = (LinearLayout) this.mFootView.findViewById(R.id.ll_loading_parent);
tvNoMoreText = (TextView) this.mFootView.findViewById(R.id.foot_layout_no_more_text);
btnReload = (Button) this.mFootView.findViewById(R.id.bt_load);
btnReload.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if ("加載失敗,點擊重試".equals(btnReload.getText().toString()) && null != mLoadingMoreListener) {
mLoadingMoreListener.onLoadingMore(PullToRefreshListView.this, OnScrollListener.SCROLL_STATE_IDLE);
}
}
});
// 首次加載應該是隱藏的
// setFootVisiable(View.VISIBLE, View.GONE, View.GONE);
addFooterView(this.mFootView);
// 添加底部之後就可以上拉加載更多 :這個監聽器,可以消除上滑的時候不加載圖片
setOnScrollListener(new PauseOnScrollListener(ImageLoader.getInstance(), true, true, this));
}
/**
*
* @description 設置沒有更多文本顏色值
* @author zhongwr
* @update 2015-12-14 下午8:26:07
*/
public void setNoMoreTextColor(int colorResId) {
if (null != tvNoMoreText) {
tvNoMoreText.setTextColor(colorResId);
}
}
public View getFootView() {
return mFootView;
}
public boolean removeFootView() {
return removeFooterView(this.mFootView);
}
/**
*
* @description 加載完成
* @param isNoMore
* 是否沒有更多了
* @author zhongwr
* @update 2015-11-6 上午1:08:15
*/
public void setOnLoadingMoreCompelete(boolean isNoMore) {
setOnLoadingMoreCompelete(isNoMore, false);
}
public void setOnLoadingMoreCompelete() {
setFootVisiable(View.GONE, View.GONE, View.GONE);
this.isLoadingMore = false;
}
/**
*
* @description 加載完成
* @param isNoMore
* 是否沒有更多了
* @param isLoadingMoreFailed
* 加載更多時出錯
* @author zhongwr
* @update 2015-11-6 上午1:08:15
*/
public void setOnLoadingMoreCompelete(boolean isNoMore, boolean isLoadingMoreFailed) {
if (!isLoadingMoreFailed) {
if (!"加載更多...".equals(btnReload.getText().toString())) {
btnReload.setText("加載更多...");
}
if (isNoMore) {
setFootVisiable(View.VISIBLE, View.VISIBLE, View.GONE);
} else {
setFootVisiable(View.VISIBLE, View.GONE, View.VISIBLE);
}
} else {// 加載失敗,提示點擊重試
btnReload.setText("加載失敗,點擊重試");
setFootVisiable(View.VISIBLE, View.GONE, View.VISIBLE);
}
this.isLoadingMore = false;
}
/***
*
* @description 用於下拉刷新時,隱藏底部
* @author zhongwr
* @update 2015-11-25 下午5:24:51
*/
public void hiddenFootView() {
if (null != mFootView) {
isLoadingMore = false;
mFootView.setVisibility(View.GONE);
}
}
/**
*
* @description 顯示底部
* @author zhongwr
* @params
* @update 2016年1月4日 下午4:16:06
*/
public void showFootView() {
if (null != mFootView) {
mFootView.setVisibility(View.VISIBLE);
}
}
/***
*
* @description 設置底部可見:加載更多或沒有更多
* @author zhongwr
* @param footView
* 這個底部是否可見
* @param footNoMoreParent
* 沒有更多是否可見
* @param footLoadingParent
* 加載更多是否可見
* @update 2015年9月24日 上午11:26:32
*/
private void setFootVisiable(int footView, int footNoMoreParent, int footLoadingParent) {
if (null != mFootView) {
if (footView != mFootView.getVisibility()) {
mFootView.setVisibility(footView);
}
// 整個底部可見,設置子佈局是否可見
if (footNoMoreParent != rlFootNoMoreParent.getVisibility()) {
this.rlFootNoMoreParent.setVisibility(footNoMoreParent);
}
if (footLoadingParent != llFootLoadingParent.getVisibility()) {
llFootLoadingParent.setVisibility(footLoadingParent);
}
}
}
/** 是否加載更多 */
private boolean isLoadingMore;
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if(mOnScrollListenerExtra != null)
{
mOnScrollListenerExtra.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// 不是首頁&歷史數據沒有加載完&最後一天item&上一次已經加載完成
Logcat.dLog("isLoadingMore = " + (view.getLastVisiblePosition() == view.getCount() - 1) + " idle = "
+ (scrollState == SCROLL_STATE_IDLE) + " done = " + (state == DONE) + " isLoadingMore = "
+ isLoadingMore);
Logcat.dLog("rlFootNoMoreParent = "+(rlFootNoMoreParent.getVisibility() == View.GONE));
if (rlFootNoMoreParent.getVisibility() == View.GONE && view.getLastVisiblePosition() == view.getCount() - 1 && scrollState == SCROLL_STATE_IDLE && state == DONE
&& !isLoadingMore) {
isLoadingMore = true;
setFootVisiable(View.VISIBLE, View.GONE, View.VISIBLE);
if (null != mLoadingMoreListener) {
mLoadingMoreListener.onLoadingMore(view, scrollState);
}
}
// 實現滑動狀態改變事件
if (mScrollStateChangedListener != null) {
mScrollStateChangedListener.onScrollStateChanged(view, scrollState);
}
if(mOnScrollListenerExtra != null)
{
mOnScrollListenerExtra.onScrollStateChanged(view, scrollState);
}
}
/**
* @Description 增加ListView滑動狀態改變監聽 接口
* @author chenxinghong
* @date 2015-12-17
*/
public interface OnScrollStateChangedListener {
public void onScrollStateChanged(AbsListView view, int scrollState);
}
public void setOnScrollStateChangedListener(OnScrollStateChangedListener listener) {
this.mScrollStateChangedListener = listener;
}
private OnScrollListener mOnScrollListenerExtra;
public void setOnScrollListenerExtra(OnScrollListener listener) {
this.mOnScrollListenerExtra = listener;
}
/***
* 加載更多的接口
*
* @author zhongwr
* @update 2015年9月28日 下午6:03:35
*/
public interface OnLoadingMoreListener {
public void onLoadingMore(AbsListView view, int scrollState);
}
}