android之浮动title
2016-01-28 20:42
549 查看
Activity定义使用的相关的属性:
初始化相关位置信息,:注必须是在加载完页面之后调用此代码,否则获取的location都为0
location详解:/article/8007272.html
lvWelfare:Listview(集合上拉加载更多,下拉刷新功能;以上定义的回调接口以及onTouchEvent()都在这个类中
/** 活动精选距离屏幕的坐标 */ 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详解:/article/8007272.html
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); } }
相关文章推荐
- Android中自定义一个事件监听器
- Android自定义View
- Android中Relativelayout各个属性
- Android 6.0 inflate过程分析
- Android 5.1编译
- 【第一行代码】Android日志工具
- Android实现边录音边播放
- 【第一行代码】Android项目目录结构
- Android 四大组件 —— 活动(活动的隐式跳转)
- appium+java+cucumber+selenium-webdriver android
- android TextView实现跑马灯效果
- Android学习-----Android Studio 2.0 预览版下载
- 【免翻墙】搭建Android开发环境
- 【Android开发新手的学习笔记】使用LruCache对ListView进行优化
- Android Scroller完全解析,关于Scroller你所需知道的一切
- Android AsyncTask软件升级
- Android Studio bug:Gradle sync failed: Cause: org/gradle/api/publication/maven/internal/DefaultMaven
- [android]_[初级]_[通过会话thread_id查询群发信息(文本彩信)]
- Android 四大组件 —— 活动(使用Intent 实现活动的显示跳转)
- Android ActionBar完全解析,使用官方推荐的最佳导航栏(下)