android之listview悬浮topBar效果

虽然listview是过去式,但由于项目中还是有用listview,百度一番都是scrollview中的悬浮bar,没有看到有listview的悬浮bar,所以自己写一个悬浮bar;参照夏大神的scrollview的悬浮demo

效果如下:

自定义的Listview和scrollView没什么区别都是重写onScrollChange()然后在里边调用自己实现的接口,是对外提供的接口吧,这里没有封装,需要的可以自己将其封装,然后在自己项目中使用。

重点的方法:
onScrollChanged()方法:是在ListView和ScrollView在滚动时会回调的方法并且能获取到当前最新的top left和上一次的top 和left
getViewTreeObservew().addOnGlobalLayoutLister():这是View都有的方法,可以监控改view的变化(如显示、隐藏)都会回调以及在view被绘制时会被回调。

思路如下:

一、可以使用getViewTreeObservew().addOnGlobalLayoutLister():方法在第一次进入到这个页面后将悬浮的bar与目标view绘制重合。防止显示隐藏会有一闪的情况
二、在onScrollChaged()方法中回调自定义的接口onScrollListener的方法onScroll()在这里通过layout()方法不断重新绘制悬浮bar的位置。

基本就如此

package com.example.zwr.listviewfloatbardemo; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.widget.ImageView; import android.widget.LinearLayout; /** * @author zhongwr */ public class MainActivity extends Activity implements FloatListView.OnScrollListener { protected static final String TAG = "FloatListView"; /** * 自定义的listview */ private FloatListView lvFloat; /** * listview中的headView中要悬浮的view */ private LinearLayout mFloatTargetLayout; /** * 悬浮的view,跟headView的要一致 */ private LinearLayout mFloatTopLayout; private View head; @SuppressWarnings("deprecation") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lvFloat = (FloatListView) findViewById(R.id.scrollView); head = getLayoutInflater().inflate(R.layout.buy_layout_head, null); lvFloat.addHeaderView(head); mFloatTargetLayout = (LinearLayout) findViewById(R.id.buy); mFloatTopLayout = (LinearLayout) findViewById(R.id.top_buy_layout); lvFloat.setOnScrollListener(this); // 当布局的状态或者控件的可见性发生改变回调的接口:当布局都绘制好后会执行一次 findViewById(R.id.parent_layout).getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // 这一步很重要,一开始让目标悬浮的view和要悬浮的view重合一起,之后悬浮view跟随一起目标view一起移动 onScroll(lvFloat.getScrollY()); } }); lvFloat.setAdapter(new DataListAdapter(this)); } @Override public void onScroll(int scrollY) { // SrcollView和这个Listview不同之处:scrolly是scrollview.getTop(),parent的坐标没变,只是手指向上滚动时就是scrollview滚出屏幕,但是top还是距离parent的距离,所以那里用max取最大值 //listview手指向上滑动屏幕时会导致headRoot的top为负值,因为head是滚出屏幕的head部分并不是listview中item重用机制 int headTop = head.getTop(); if (headTop <= 0 && Math.abs(headTop) <= mFloatTargetLayout.getTop() && scrollY >= 0) {//手指向上滑动屏幕 mFloatTopLayout.layout(0, mFloatTargetLayout.getTop() + headTop, mFloatTopLayout.getWidth(), mFloatTargetLayout.getTop() + headTop + mFloatTopLayout.getHeight()); } else if (headTop == 0) {//当手指从上往下滑动屏幕到达最顶端时,但还有一段可滑行的距离放手后又回到起始位置,跟系统有关 //此时这个listview的Top是负值所以要减去-scrolly:注这个scrollY=listview.getTop();让悬浮的Title跟随实际的title一起浮动 mFloatTopLayout.layout(0, mFloatTargetLayout.getTop() - scrollY, mFloatTopLayout.getWidth(), mFloatTargetLayout.getTop() - scrollY + mFloatTopLayout.getHeight()); } else if (headTop < 0) {//由于手指向上滑动屏幕的很快会导致title悬浮不到顶部,所以要强制其在顶部 mFloatTopLayout.layout(0, 0, mFloatTopLayout.getWidth(), mFloatTopLayout.getHeight()); } //这种方式会导致闪跳的现象,可以通过动画来实现 } }

主要是onScroll()方法的逻辑:

可以看看夏大神的实现

public void onScroll(int scrollY) { int mBuyLayout2ParentTop = Math.max(scrollY, mBuyLayout.getTop()); mTopBuyLayout.layout(0, mBuyLayout2ParentTop, mTopBuyLayout.getWidth(), mBuyLayout2ParentTop + mTopBuyLayout.getHeight()); }

他这里是直接使用scrollY(其实是scrollview的最新top值)和目标view的top值去最大,因为ScrollView是滑出屏幕的,但是其parent的位置没变,所以scrollview的top会越来越大而且是正值。所以可以通过这种方式来绘制悬浮的bar。

但是Listview的机制不一样,滑动出屏幕时item由于是重用机制,所以listView中的top并没有改变;巧的是head的机制有点像Scrollview滑出的机制,但是又不一样得到的head的top值是负值,猜测相对坐标由于listView这个父布局没动但是head已经滑出屏幕所以是负值。根据这个值处理我们想要的结果,剩下的onScroll()方法的注释写的很清楚了。

自定义的listView代码如下

package com.example.zwr.listviewfloatbardemo; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.widget.ListView; /** * * @author zhongwr * */ public class FloatListView extends ListView { private static final String TAG = "FloatListView"; private OnScrollListener onScrollListener; public FloatListView(Context context) { this(context, null); } public FloatListView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FloatListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /** * 设置滚动接口 * @param onScrollListener */ public void setOnScrollListener(OnScrollListener onScrollListener) { this.onScrollListener = onScrollListener; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { // Log.d(TAG, "w = "+w); // Log.d(TAG, "h = "+h); super.onSizeChanged(w, h, oldw, oldh); } /** * 滚动时会执行 * @param l 新的getLeft * @param t 新的getTop * @param oldl * @param oldt */ @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); // Log.d(TAG, "onScrollChanged l = " + l + " t = " + t); // Log.d(TAG, "onScrollChanged oldl = " + oldl + " oldt = " + oldt); if (onScrollListener != null) { onScrollListener.onScroll(t); } } /** * * 滚动的回调接口 * * @author xiaanming * */ public interface OnScrollListener{ /** * 回调方法, 返回MyScrollView滑动的Y方向距离 * @param scrollY * 、 */ public void onScroll(int scrollY); } }

没什么逻辑,就是重写了onSizeChaged()方法,然后在里边写了调用接口的回调。
就是这么简单!!

demo如下:listview悬浮topBar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

时间: 2024-08-29 18:54:59

android之listview悬浮topBar效果的相关文章

Android view滑动悬浮固定效果实现代码示例

1.背景 在项目开发过程中,有时候会碰到这样的需求:在滑动的过程中,在某时要将子view固定在顶部(常见的是将界面中的tab在滑动到顶部的时候进行固定). 之前写过一篇滑动组件悬浮固定在顶部的文章,但感觉还是有些复杂,因此就有了这次的实现.效果图: 2.思路 (CoordinatorLayout+AppBarLayout+CollapsingToolbarLayout)+TabLayout+ViewPager 3.代码实现 a.主布局代码 <?xml version="1.0"

android自定义listview实现header悬浮框效果

之前在使用iOS时,看到过一种分组的View,每一组都有一个Header,在上下滑动的时候,会有一个悬浮的Header,这种体验觉得很不错,请看下图: 上图中标红的1,2,3,4四张图中,当向上滑动时,仔细观察灰色条的Header变化,当第二组向上滑动时,会把第一组的悬浮Header挤上去. 这种效果在Android是没有的,iOS的SDK就自带这种效果.这篇文章就介绍如何在Android实现这种效果. 1.悬浮Header的实现 其实Android自带的联系人的App中就有这样的效果,我也是把

在Android中实现360手机卫士悬浮窗效果

大家好,今天给大家带来一个仿360手机卫士悬浮窗效果的教程,在开始之前请允许我说几句不相干的废 话. 不知不觉我发现自己接触Android已有近三个年头了,期间各种的成长少不了各位高手的帮助, 总是有很多高手喜欢把自己的经验写在网上,供大家来学习,我也是从中受惠了很多,在此我深表感谢.可 是我发现我却从来没有将自己平时的一些心得拿出来与大家分享,共同学习,太没有奉献精神了.于是我痛 定思痛,决定从今天开始写博客,希望可以指点在我后面的开发者,更快地进入Android开发者的行列当中. 好了,废话

基于Android实现ListView圆角效果_Android

本文演示如何在Android中实现ListView圆角效果. 无论是网站,还是APP,人们都爱看一些新颖的视图效果.直角看多了,就想看看圆角,这几年刮起了一阵阵的圆角设计风:CSS新标准纳入圆角元素,特别是在iphone中几乎随处可见圆角设计,现在也开始出现很多圆角名片了. 现在就给大家实现一个圆角的ListView效果. 圆角的设计,我们并不追求到处都用,无处不用,android中有少数界面用直角确实容易显得锋利,和周边界面太过对比而显得不协调,比如大栏目列表,设置等等,而采用圆角实现,则会活

Android基于ListView实现类似QQ空间的滚动翻页与滚动加载效果_Android

本文实例讲述了Android基于ListView实现类似QQ空间的滚动翻页与滚动加载效果.分享给大家供大家参考,具体如下: 1. 滚动加载 listView.setOnScrollListener(new OnScrollListener() { //添加滚动条滚到最底部,加载余下的元素 @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (scrollState == OnScro

Android基于ListView实现类似Market分页加载效果示例_Android

本文实例讲述了Android基于ListView实现类似Market分页加载效果.分享给大家供大家参考,具体如下: 最近几天研究ListView实现分页加载和滚动加载,发现可以用listView的OnScroll方法来实现,直接上代码 ListViewScroll.java package zy.lucifer.ListViewScroll; import android.app.Activity; import android.os.Bundle; import android.util.Lo

Android Animation实战之一个APP的ListView的动画效果_Android

熟悉了基础动画的实现后,便可以试着去实现常见APP中出现过的那些精美的动画.今天我主要给大家引入一个APP的ListView的动画效果: 当展示ListView时,Listview的每一个列表项都按照规定的动画显示出来. 说起来比较抽象,先给大家看一个动画效果,这是APP窝牛装修的ListView显示动画:     有木有觉得很酷炫?有木有啊!? 一.Layout Animation     所谓的布局动画,其实就是为ViewGroup添加显示动画效果,主要用过LayoutAnimationCo

Android中ListView + CheckBox实现单选、多选效果

还是先来看看是不是你想要的效果: 不废话,直接上代码,很简单,代码里都有注释 1 单选 public class SingleActivity extends AppCompatActivity { private ListView listView; private ArrayList<String> groups; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInsta

Android Animation实战之一个APP的ListView的动画效果

熟悉了基础动画的实现后,便可以试着去实现常见APP中出现过的那些精美的动画.今天我主要给大家引入一个APP的ListView的动画效果: 当展示ListView时,Listview的每一个列表项都按照规定的动画显示出来. 说起来比较抽象,先给大家看一个动画效果,这是APP窝牛装修的ListView显示动画: 有木有觉得很酷炫?有木有啊!? 一.Layout Animation     所谓的布局动画,其实就是为ViewGroup添加显示动画效果,主要用过LayoutAnimationContro