Android应用开发之Android 仿支付宝城市服务栏目tab选择滑动子View效果
凌雪 2018-11-29 来源 :网络 阅读 1283 评论 0

摘要:本文将带你了解Android应用开发之Android 仿支付宝城市服务栏目tab选择滑动子View效果,希望本文对大家学Android有所帮助。

本文将带你了解Android应用开发之Android 仿支付宝城市服务栏目tab选择滑动子View效果,希望本文对大家学Android有所帮助。


一. 图示
   
   
    支付宝效果
实现的效果
二. 思路讲解
    TabLayout+ScrollView实现即可。每一个tab对应scrollview中包裹的一层布局,以上有4个tab,也就需要inflate 4个布局文件,用来表示每一层的样式内容。
    1.页面加载完毕后,记住每一层父布局在Screen中所要滑动至顶部的距离Distance;
    2.操作:
    a. 当点击tab时:滑动scrollview该层的距离Distance;
    b. 当滑动scrollview至对应的层时: 选定对应的tab。
三. 代码
    1. 布局代码
    <!--?xml version="1.0"   encoding="utf-8"?--><linearlayout   android:id="@+id/activity_main"   android:layout_height="match_parent"   android:layout_width="match_parent" android:orientation="vertical"   tools:context="com.ganshenml.tabscrollviewdemo.MainActivity"   xmlns:android="https://schemas.android.com/apk/res/android"   xmlns:tools="https://schemas.android.com/tools">     <framelayout   android:layout_height="wrap_content"   android:layout_width="match_parent">         </android.support.design.widget.tablayout>         <framelayout   android:id="@+id/wrapperFl"   android:layout_height="match_parent"   android:layout_width="match_parent"></framelayout>    </framelayout>     <com.ganshenml.tabscrollviewdemo.observablescrollview   android:id="@+id/scrollView"   android:layout_height="wrap_content"   android:layout_width="match_parent">         <linearlayout   android:id="@+id/containerLl"   android:layout_height="match_parent"   android:layout_width="match_parent"   android:orientation="vertical">         </linearlayout>     </com.ganshenml.tabscrollviewdemo.observablescrollview></linearlayout>  
    布局代码很简单,可能会有的疑问点有:
    a. wrapperFl是用来干啥的?
    b. ObservableScrollView又是个什么东西?
(后面说明)
    2. 逻辑代码
    public class MainActivity extends AppCompatActivity implements   ObservableScrollView.ScrollViewListener {    private   static final String TAG =   "MainActivity";    private FrameLayout   wrapperFl;    private TabLayout   tabLayout;    private ObservableScrollView   scrollView;    private LinearLayout   containerLl;    private boolean firstAlreadyInflated =   true;    private ViewGroup   firstFloorVg;    private ViewGroup   secondFloorVg;    private ViewGroup   thirdFloorVg;    private ViewGroup   fourthFloorVg;    private int secondFloorVgPositionDistance;//第二层滑动至顶部的距离    private   int thirdFloorVgPositionDistance;    private int   fourthFloorVgPositionDistance;    private int   currentPosition = 0;    private boolean   tabInterceptTouchEventTag = true;//标志位,用来区分是点击了tab还是手动滑动scrollview     @Override    protected   void onCreate(Bundle savedInstanceState)   {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initViews();        initListeners();    }     private   void initViews() {        wrapperFl =   (FrameLayout)   findViewById(R.id.wrapperFl);        tabLayout   = (TabLayout)   findViewById(R.id.tabLayout);        scrollView   = (ObservableScrollView)   findViewById(R.id.scrollView);        containerLl   = (LinearLayout)   findViewById(R.id.containerLl);        for   (int i = 0; i < 4; i++) {            tabLayout.addTab(tabLayout.newTab().setText("tab"   + (i +   1)));        }         firstFloorVg   = (ViewGroup) LayoutInflater.from(this).inflate(R.layout.item_floor_first,   null);        secondFloorVg =   (ViewGroup) LayoutInflater.from(this).inflate(R.layout.item_floor_second,   null);        thirdFloorVg =   (ViewGroup) LayoutInflater.from(this).inflate(R.layout.item_floor_third,   null);        fourthFloorVg =   (ViewGroup) LayoutInflater.from(this).inflate(R.layout.item_floor_fourth,   null);         containerLl.addView(firstFloorVg);        containerLl.addView(secondFloorVg);        containerLl.addView(thirdFloorVg);        containerLl.addView(fourthFloorVg);     }     @Override    public   void onWindowFocusChanged(boolean hasFocus) {        super.onWindowFocusChanged(hasFocus);        if   (firstAlreadyInflated) {//获取各层离screen顶部的位置以及计算滑动值相应顶部所需要的距离            firstAlreadyInflated   =   false;            int[]   firstFloorVgPosition = new int[2];            int[]   secondFloorVgPosition = new   int[2];            int[]   thirdFloorVgPosition = new   int[2];            int[]   fourthFloorVgPosition = new   int[2];            firstFloorVg.getLocationOnScreen(firstFloorVgPosition);            secondFloorVg.getLocationOnScreen(secondFloorVgPosition);            thirdFloorVg.getLocationOnScreen(thirdFloorVgPosition);            fourthFloorVg.getLocationOnScreen(fourthFloorVgPosition);            int   firstFloorVgPositionAnchor =   firstFloorVgPosition[1];            int   secondFloorVgPositionAnchor =   secondFloorVgPosition[1];            int   thirdFloorVgPositionAnchor =   thirdFloorVgPosition[1];            int   fourthFloorVgPositionAnchor =   fourthFloorVgPosition[1];             Log.d(TAG,   "第一层距离屏幕的距离是:"   +   firstFloorVgPosition[1]);            Log.d(TAG,   "第二层距离屏幕的距离是:"   +   secondFloorVgPosition[1]);            Log.d(TAG,   "第三层距离屏幕的距离是:"   +   thirdFloorVgPosition[1]);            Log.d(TAG,   "第四层距离屏幕的距离是:"   +   fourthFloorVgPosition[1]);             secondFloorVgPositionDistance   = secondFloorVgPositionAnchor -   firstFloorVgPositionAnchor;            thirdFloorVgPositionDistance   = thirdFloorVgPositionAnchor -   firstFloorVgPositionAnchor;            fourthFloorVgPositionDistance   = fourthFloorVgPositionAnchor - firstFloorVgPositionAnchor;        }    }     private   void initListeners()   {        wrapperFl.setOnTouchListener(new   View.OnTouchListener()   {            @Override            public   boolean onTouch(View v, MotionEvent event)   {                Log.d(TAG,"wrapperFl   onTouch");                tabInterceptTouchEventTag   = true;//让tab来处理滑动                return   false;            }        });        tabLayout.addOnTabSelectedListener(new   TabLayout.OnTabSelectedListener()   {            @Override            public   void onTabSelected(TabLayout.Tab tab)   {                currentPosition   =   tab.getPosition();                if(!tabInterceptTouchEventTag){//手动滑动页面时则不再次处理滑动                    return;                }                scrollView.computeScroll();                switch   (currentPosition) {                    case   0:                        scrollView.smoothScrollTo(0,   0);                        break;                    case   1:                        scrollView.smoothScrollTo(0,   secondFloorVgPositionDistance);                        break;                    case   2:                        scrollView.smoothScrollTo(0,   thirdFloorVgPositionDistance);                        break;                    case   3:                        scrollView.smoothScrollTo(0,   fourthFloorVgPositionDistance);                        break;                    default:                        break;                }            }             @Override            public   void onTabUnselected(TabLayout.Tab tab) {             }             @Override            public   void onTabReselected(TabLayout.Tab tab)   {             }        });        scrollView.setScrollViewListener(this);        scrollView.setOnTouchListener(new   View.OnTouchListener()   {            @Override            public   boolean onTouch(View v, MotionEvent event)   {                Log.d(TAG,   "scrollView   onTouch");                tabInterceptTouchEventTag   = false;//让scrollview处理滑动                return   false;            }        });    }     @Override    public   void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx,   int oldy) {        if   (tabInterceptTouchEventTag) {//让tab来处理滑动            return;        }        Log.d(TAG,   "当前scrollView的位置——>" +   y);        if (y <   secondFloorVgPositionDistance)   {            if   (currentPosition != 0) {                scrollView.computeScroll();                tabLayout.getTabAt(0).select();            }        }   else if (y < thirdFloorVgPositionDistance)   {            if   (currentPosition != 1) {                scrollView.computeScroll();                tabLayout.getTabAt(1).select();            }        }   else if (y < fourthFloorVgPositionDistance)   {            if   (currentPosition != 2) {                scrollView.computeScroll();                tabLayout.getTabAt(2).select();            }        }   else   {            if   (currentPosition != 3) {                scrollView.computeScroll();                tabLayout.getTabAt(3).select();            }        }    }}
    a. tabInterceptTouchEventTag 作为标志位是为了防止因scrollview触发了tab Selected从而再次引起scrollview滑动导致的滑动不流畅。
    b. wrapperFl的存在则是要去给   tabInterceptTouchEventTag 赋值,因为TabLayout的Touch、Click、Focus等事件被消化掉了,无法在这些事件中监听到对应的值的变化,所以通过wrapperFl来进行Touch事件的监听。
    c. ObservableScrollView 是继承自Scrollview,新增和改变了其中的以下方法:
    public void setScrollViewListener(ScrollViewListener scrollViewListener)   {       this.scrollViewListener =   scrollViewListener;   }    @Override   protected   void onScrollChanged(int x, int y, int oldx, int oldy)   {       super.onScrollChanged(x, y, oldx,   oldy);       if (scrollViewListener !=   null) {           scrollViewListener.onScrollChanged(this,   x, y, oldx,   oldy);       }   }    public   interface ScrollViewListener   {        void   onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int   oldy);    }
    这样就可以在activity主界面中监听到scrollview的滑动事件,从而获取当前整个scrollview所处的位置,进而去判定是否需要选定对应的tab。    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!

本文由 @凌雪 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved