博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 滑动定位+吸附悬停效果实现
阅读量:5096 次
发布时间:2019-06-13

本文共 5241 字,大约阅读时间需要 17 分钟。

在前两篇文章中,分别介绍了tablayout+scrollview 和 tablayout+recyclerview 实现的滑动定位的功能,文章链接:

仔细看的话,这种滑动定位的功能,还可以整体滑动,再加上顶部tablayout 吸附悬停的效果。

实现效果:

16503887c9b0eed4?w=184&h=301&f=gif&s=840685

布局

这里采用的是两个 tablayout。

一个用于占位,位于原始位置,scrollview内部,随scrollview滚动;另一个则是在滑动过程中,不断滑动,滑动到顶部时吸附在屏幕顶部,用户实际操作的也是这个tablayout。

实现

滑动定位的功能可以参考之前的文章,这里主要是进行吸附悬停的效果。

数据初始化:

/** * 占位tablayout,用于滑动过程中去确定实际的tablayout的位置 */private TabLayout holderTabLayout;/** * 实际操作的tablayout, */private TabLayout realTabLayout;private CustomScrollView scrollView;private LinearLayout container;private String[] tabTxt = {"客厅", "卧室", "餐厅", "书房", "阳台", "儿童房"};private List
anchorList = new ArrayList<>();//判读是否是scrollview主动引起的滑动,true-是,false-否,由tablayout引起的private boolean isScroll;//记录上一次位置,防止在同一内容块里滑动 重复定位到tablayoutprivate int lastPos = 0;//监听判断最后一个模块的高度,不满一屏时让最后一个模块撑满屏幕private ViewTreeObserver.OnGlobalLayoutListener listener;for (int i = 0; i < tabTxt.length; i++) { AnchorView anchorView = new AnchorView(this); anchorView.setAnchorTxt(tabTxt[i]); anchorView.setContentTxt(tabTxt[i]); anchorList.add(anchorView); container.addView(anchorView);}for (int i = 0; i < tabTxt.length; i++) { holderTabLayout.addTab(holderTabLayout.newTab().setText(tabTxt[i])); realTabLayout.addTab(realTabLayout.newTab().setText(tabTxt[i]));}

一开始让实际的tablayout 移动到占位的tablayout 处,覆盖占位的tablayout。

listener = new ViewTreeObserver.OnGlobalLayoutListener() {    @Override    public void onGlobalLayout() {        //计算让最后一个view高度撑满屏幕        int screenH = getScreenHeight();        int statusBarH = getStatusBarHeight(AliHomeMoreActivity.this);        int tabH = holderTabLayout.getHeight();        int lastH = screenH - statusBarH - tabH - 16 * 3;        AnchorView anchorView = anchorList.get(anchorList.size() - 1);        if (anchorView.getHeight() < lastH) {            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);            params.height = lastH;            anchorView.setLayoutParams(params);        }        //一开始让实际的tablayout 移动到 占位的tablayout处,覆盖占位的tablayout        realTabLayout.setTranslationY(holderTabLayout.getTop());        realTabLayout.setVisibility(View.VISIBLE);        container.getViewTreeObserver().removeOnGlobalLayoutListener(listener);    }};container.getViewTreeObserver().addOnGlobalLayoutListener(listener);private int getScreenHeight() {    return getResources().getDisplayMetrics().heightPixels;}public int getStatusBarHeight(Context context) {    int result = 0;    int resourceId = context.getResources()            .getIdentifier("status_bar_height", "dimen", "android");    if (resourceId > 0) {        result = context.getResources().getDimensionPixelSize(resourceId);    }    return result;}

scrollview滑动

主要在滑动过程这不断监听滑动的距离,再移动实际的tablayout ,当在屏幕内时,让其一直覆盖在占位的tablayout 上,看上去是跟着scrollview 一起滑动的;当滑出屏幕时,实际的tablayout 不断移动 使其相对屏幕静止,看上去是吸附在屏幕顶部。

scrollView.setOnTouchListener(new View.OnTouchListener() {    @Override    public boolean onTouch(View v, MotionEvent event) {        if (event.getAction() == MotionEvent.ACTION_DOWN) {            isScroll = true;        }        return false;    }});//监听scrollview滑动scrollView.setCallbacks(new CustomScrollView.Callbacks() {    @Override    public void onScrollChanged(int x, int y, int oldx, int oldy) {        //根据滑动的距离y(不断变化的) 和 holderTabLayout距离父布局顶部的距离(这个距离是固定的)对比,        //当y < holderTabLayout.getTop()时,holderTabLayout 仍在屏幕内,realTabLayout不断移动holderTabLayout.getTop()距离,覆盖holderTabLayout        //当y > holderTabLayout.getTop()时,holderTabLayout 移出,realTabLayout不断移动y,相对的停留在顶部,看上去是静止的        int translation = Math.max(y, holderTabLayout.getTop());        realTabLayout.setTranslationY(translation);        if (isScroll) {            for (int i = tabTxt.length - 1; i >= 0; i--) {                //需要y减去顶部内容区域的高度(具体看项目的高度,这里demo写死的200dp)                if (y - 200 * 3 > anchorList.get(i).getTop() - 10) {                    setScrollPos(i);                    break;                }            }        }    }});private void setScrollPos(int newPos) {    if (lastPos != newPos) {        realTabLayout.setScrollPosition(newPos, 0, true);    }    lastPos = newPos;}

tablayout点击切换

由于实际操作的是realtablayout ,所以这里只需要一直监听该tablayout。

//实际的tablayout的点击切换realTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {    @Override    public void onTabSelected(TabLayout.Tab tab) {        isScroll = false;        int pos = tab.getPosition();        int top = anchorList.get(pos).getTop();        //同样这里滑动要加上顶部内容区域的高度(这里写死的高度)        scrollView.smoothScrollTo(0, top + 200 * 3);    }    @Override    public void onTabUnselected(TabLayout.Tab tab) {    }    @Override    public void onTabReselected(TabLayout.Tab tab) {    }});

至此,滑动定位+顶部吸附悬停 的效果结束了。做完之后,再看这个效果,其实和 支付宝-首页 更多 那个页面里的滑动效果一样。

代码与之前文章的在同一个git地址里。

详细代码见

github地址:

欢迎关注我的博客:

更多精彩欢迎关注微信号:春风十里不如认识你
image.png

有个「佛系码农圈」,欢迎大家加入畅聊,开心就好!

16508a18f5903bf0?w=188&h=250&f=jpeg&s=40959
过期了,可加我微信 tx467220125 拉你入群。

转载于:https://www.cnblogs.com/taixiang/p/9426874.html

你可能感兴趣的文章
Docker Stack 部署web集群
查看>>
韵语编年之十五:2004—— 2007.【 附:《吴忠史话》----吴忠的历史大事与名人】...
查看>>
杨森翔的书法-19
查看>>
css画圆
查看>>
视图时时更新
查看>>
【PMP】财务测量指标ROI、PBP、NPV、IRR、BCR
查看>>
【Shell】Read命令
查看>>
BZOJ1061 NOI2008 志愿者招募 单纯形
查看>>
code forces 996D Suit and Tie
查看>>
PHP操作Mysql
查看>>
win7 64安装msyql
查看>>
vue-cli的webpack使用说明
查看>>
机试指南第二章-经典入门-排序模板
查看>>
验证数字的正则表达式
查看>>
Android的ListView分页功能
查看>>
LeetCode 69.sqrt(x)
查看>>
sns
查看>>
PATA1040题解
查看>>
Unity 5.3配置开发环境、安卓环境
查看>>
信息反馈—冲刺08
查看>>