美文网首页app开发程序猿学习Android大法好
高仿支付宝9.9.2版本生活模块界面来讲解Coordinator

高仿支付宝9.9.2版本生活模块界面来讲解Coordinator

作者: Jack921 | 来源:发表于2016-09-16 23:52 被阅读8064次

    首先先看看仿制的效果先,如下图:


    fangzhifubao.gif

    是不是很像支付宝的效果呢,我们今天就要通过讲解android5.0新出的控件CoordinatorLayout,AppBarLayout,CollapsingToolbarLayout来实现这个效果。

    在讲解之前先看看界面布局文件,在一个一个讲讲怎么实现吧:

    <android.support.design.widget.CoordinatorLayout 
      xmlns:android="http://schemas.android.com/apk/res/android" 
      xmlns:app="http://schemas.android.com/apk/res-auto" 
      xmlns:tools="http://schemas.android.com/tools" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:fitsSystemWindows="true" 
    tools:context="com.example.jack.coordinatorlayouttest.ScrollingActivity"> 
    
    <android.support.design.widget.AppBarLayout 
      android:id="@+id/app_bar"
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:fitsSystemWindows="true" 
      android:theme="@style/AppTheme.AppBarOverlay"> 
    
    <android.support.design.widget.CollapsingToolbarLayout 
      android:id="@+id/toolbar_layout" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:fitsSystemWindows="true" 
      app:contentScrim="@color/color1984D1" 
      app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" app:title=" "> 
    
    <include layout="@layout/shenghuo_head1" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="100dp" 
      android:layout_marginBottom="25dp" 
      app:layout_collapseMode="parallax" 
      app:layout_collapseParallaxMultiplier="0.8"/> 
    
    <android.support.v7.widget.Toolbar android:id="@+id/toolbar" 
      android:layout_width="match_parent" 
      android:layout_height="?attr/actionBarSize" 
      app:contentInsetLeft="0dp" app:contentInsetStart="0dp" 
      app:layout_collapseMode="pin">
    
     <include android:id="@+id/toolbar1" 
      layout="@layout/toolbar_head1" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" /> 
    
    <include android:id="@+id/toolbar2" 
      layout="@layout/toolbar_head2" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" android:visibility="gone"/> 
    
    </android.support.v7.widget.Toolbar> 
    </android.support.design.widget.CollapsingToolbarLayout>  
    </android.support.design.widget.AppBarLayout>  
    <include 
    layout="@layout/content_scrolling" />
    </android.support.design.widget.CoordinatorLayout>
    

    1.CoordinatorLayout

    这就是整个高仿支付宝界面的核心布局界面的,看看代码量也不多吧,只要就是用了
    CoordinatorLayout,AppBarLayout,CollapsingToolbarLayou,Toolbar这四个控件吧。
    在各个布局文件里,最外围的是CoordinatorLayout这个控件,这个有什么作用呢,就我的大白话来说就是协调子View之间动作的一个父View,通过Behavior来给子view实现交互的。这样好像还是有点说不通,没关系同学们通过看上面的布局文件,可以发现

    img1.PNG
    这一个内容界面是的布局是<include layout="@layout/content_scrolling" />这一句的内容是:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 
       xmlns:android="http://schemas.android.com/apk/res/android"  
       xmlns:app="http://schemas.android.com/apk/res-auto" 
       xmlns:tools="http://schemas.android.com/tools"  
       android:layout_width="match_parent"
       android:layout_height="match_parent" 
       android:orientation="vertical" 
       tools:showIn="@layout/activity_scrolling" 
       app:layout_behavior="@string/appbar_scrolling_view_behavior">
     <android.support.v7.widget.RecyclerView     
        android:id="@+id/myRecyclerView" 
        android:layout_width="match_parent"
        android:layout_height="match_parent">
     </android.support.v7.widget.RecyclerView>
    </LinearLayout>
    

    没错就是一个linearLayout包裹着RecyclerView组成他的内容界面,在这代码里有这一句app:layout_behavior="@string/appbar_scrolling_view_behavior"就是这句和CoordinatorLayout控件互动实现滑动,总结就是CoordinatorLayout控件和app:layout_behavior来进行互动,进而CoordinatorLayout的子控件和app:layout_behavior互动。当然@string/appbar_scrolling_view_behavior是系统自带的,本质是一个类,我们也可以自定义这个类实现其他效果,不过这不是我们这一章所讲的了,我们点到即止。

    2.AppBarLayout

    其次就是AppBarLayout,去除官方解释,简单来说就是它可以让你定制当某个可滚动View的滚动手势发生变化时,其内部的子View实现何种动作。内部的子View通过在布局中加app:layout_scrollFlags设置执行的动作。而layout_srcollFlags的动作主要如下:

    1. scroll:值设为scroll的View会跟随滚动事件一起发生移动。
    2. enterAlways:值设为enterAlways的View,当ScrollView往下滚动时,该View会直接往下滚动。而不用考虑ScrollView是否在滚动。
    3. exitUntilCollapsed:值设为exitUntilCollapsed的View,当这个View要往上逐渐“消逝”时,会一直往上滑动,直到剩下的的高度达到它的最小高度后,再响应ScrollView的内部滑动事件。
    4. enterAlwaysCollapsed:是enterAlways的附加选项,一般跟enterAlways一起使用,它是指,View在往下“出现”的时候,首先是enterAlways效果,当View的高度达到最小高度时,View就暂时不去往下滚动,直到ScrollView滑动到顶部不再滑动时,View再继续往下滑动,直到滑到View的顶部结束。

    这是layout_srcollFlags里可以设置的各个属性的解释,考虑文章的重点是模仿支付宝所以没有篇幅和每个属性都给个效果图,所以各属性你们有空还要自己试一试,这样子才能掌握更好。我们这里AppBarLayout关联的是CollapsingToolbarLayout,设置的属性是app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"里面的scroll让

    img2.PNG
    这可以滑动,而exitUntilCollapsed实现的效果是
    img4.PNG 这一块当滑动到最顶的时候不会跟这个继续滑到最顶,而保留这一块。最后snap这是属性是子View不会存在局部显示的情况,滚动Child View的部分高度,当我们松开手指时,Child View要么向上全部滚出屏幕,要么向下全部滚进屏幕。

    3.CollapsingToolbarLayout

    是用来对Toolbar进行再次包装的ViewGroup,主要是用于实现折叠的App Bar效果。CollapsingToolbarLayout只要有这方面:
    1.title展开时是最大的,然后随着收缩会越来越少,直到屏幕的顶部,通过app:title设置title,不然就默认。
    2.通过setContentScrim(Drawable)来设置达到某一个状态之后的出现的效果3.通过setStatusBarScrim(Drawable)来设置达到某一个状态之后的状态栏出现的效果
    4.当app:layout_collapseMode设为parallax子View可以选择在当前的布局当时是否以“视差”的方式来跟随滚动
    5.当app:layout_collapseMode设为pinToolbar固定位置而不受移动的影响
    在我们实现这里,我们把layout="@layout/shenghuo_head1"

    img4.PNG
    设为app:layout_collapseMode="parallax"让它以“视差”的方式来跟随滚动,而toolbar设为app:layout_collapseMode="pin"以让他固定不动。

    4.Toolbar动态变化

    在此整体布局就已经完成,不过还有一个效果就是向上移动是toolbar的的View是动态变化的,一开始我以为这些控件会有这个功能吧,没想到找了很久都没找到,没办法只能自己实现了。二话不说上代码:

    private AppBarLayout mAppBarLayout=null;
     private View mToolbar1=null; 
    private View mToolbar2=null; 
    private ImageView mZhangdan=null;
    private TextView mZhangdan_txt=null; 
    private ImageView mTongxunlu=null; 
    private ImageView mJiahao=null; 
    private ImageView mZhangdan2=null; 
    private ImageView mShaoyishao=null; 
    private ImageView mSearch=null; 
    private ImageView mZhaoxiang=null; 
    private RecyclerView myRecyclerView; 
    
    @Override protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); setContentView(R.layout.activity_scrolling);
    
    myRecyclerView=(RecyclerView)findViewById(R.id.myRecyclerView);
    myRecyclerView.setLayoutManager(new LinearLayoutManager(this)); 
    myRecyclerView.setAdapter(new ToolbarAdapter(this)); 
    mAppBarLayout=(AppBarLayout)findViewById(R.id.app_bar); 
    
    mToolbar1=(View)findViewById(R.id.toolbar1); 
    mToolbar2=(View)findViewById(R.id.toolbar2);
    
    mZhangdan=(ImageView)findViewById(R.id.img_zhangdan); 
    mZhangdan_txt=(TextView)findViewById(R.id.img_zhangdan_txt); 
    mTongxunlu=(ImageView)findViewById(R.id.tongxunlu);
    mJiahao=(ImageView)findViewById(R.id.jiahao); 
    
    mZhangdan2=(ImageView)findViewById(R.id.img_shaomiao); 
    mShaoyishao=(ImageView)findViewById(R.id.img_fukuang); 
    mSearch=(ImageView)findViewById(R.id.img_search); 
    mZhaoxiang=(ImageView)findViewById(R.id.img_zhaoxiang); 
    
    mAppBarLayout.addOnOffsetChangedListener(
    new AppBarLayout.OnOffsetChangedListener() {
     @Override public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { 
    if (verticalOffset == 0){
     //张开
    mToolbar1.setVisibility(View.VISIBLE);
    mToolbar2.setVisibility(View.GONE); 
    setToolbar1Alpha(255); 
    } else if (Math.abs(verticalOffset)>=appBarLayout.getTotalScrollRange()) {
     //收缩 
    mToolbar1.setVisibility(View.GONE); 
    mToolbar2.setVisibility(View.VISIBLE); 
    setToolbar2Alpha(255); 
    } else {
     int alpha=255-Math.abs(verticalOffset)-150; 
    if(alpha<=0){ 
    //收缩
    toolbar mToolbar1.setVisibility(View.GONE); 
    mToolbar2.setVisibility(View.VISIBLE); 
    setToolbar2Alpha(Math.abs(verticalOffset)); 
    }else{ 
    //张开
    toolbar mToolbar1.setVisibility(View.VISIBLE); 
    mToolbar2.setVisibility(View.GONE); setToolbar1Alpha(alpha); 
      }
     }
     }
     });
     }
     //设置展开时各控件的透明度 
    public void setToolbar1Alpha(int alpha){
      mZhangdan.getDrawable().setAlpha(alpha); 
      mZhangdan_txt.setTextColor(Color.argb(alpha,255,255,255)); 
      mTongxunlu.getDrawable().setAlpha(alpha); 
      mJiahao.getDrawable().setAlpha(alpha); 
    } 
    //设置闭合时各控件的透明度 
    public void setToolbar2Alpha(int alpha){
      mZhangdan2.getDrawable().setAlpha(alpha); 
      mShaoyishao.getDrawable().setAlpha(alpha);
      mSearch.getDrawable().setAlpha(alpha);     
      mZhaoxiang.getDrawable().setAlpha(alpha); 
    }
    

    代码还是有点多了不过最核心就设置AppBarLayout 的监听器addOnOffsetChangedListener来进行效果的处理。当verticalOffset=0的时候即使整个展开的是时候要做的就是显示要显示的,隐藏要隐藏的设置,在设置透明度,同理当verticalOffset等于appBarLayout.getTotalScrollRange()即等于最大值的时候,就是关闭的时候,处理的展开相反。当他在中间值的时候,通过`int alpha=255-Math.abs(verticalOffset)-150;得到要设置的透明度,减去150是为了让效果更明显。当alpha小于0的时候是执行展开的toolbar的透明度效果,反之大于0的时候是闭合时toolbar的透明图效果。

    剩下的看源码
    如果对你有帮助就请给我给星星或喜欢吧

    相关文章

      网友评论

      • fc021d51d46b:你好,最近在开发这效果,发现收缩时的headlayout是系统控制的,与支付宝的动画相比消失的太快的,而且向上的移动距离过小,有什么方法解决吗?
      • 就是这么Nice:楼主在activity重新获取焦点的时候
        <include layout="@layout/shenghuo_head1"/>布局中的图片有时会变成透明的(就是扫一扫、付款、卡券、咻一咻上面的图片会变成透明的)。这是怎么回事?
      • 骆马湖游民:在底部加上类似微信的导航栏 切换到其他界面的时候 view会下移。百度是因为app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" 搞了很长时间没有弄好,有什么方法吗
        骆马湖游民: @张稳_f12c 搞定了,谢谢
        张稳_f12c:布局文件里
        step.1去掉CoordinatorLayout中的android:fitsSystemWindows="true"
        step.2去掉AppBarLayout中的android:fitsSystemWindows="true"
        我得这样就搞定了
      • 5891089a54ea:遇到两个问题:
        1,快速滑动的flinging动作 不会展开头部,这个问题其实挺严重,实际使用中体验很不好。
        2,支付宝的刷新位置在那一排付款图标的下边,所以付款图标应该不是在RecyclerView内部的。
        两个问题折腾了整整两天,并没有找到完美的解决方案,不知道有没有大牛赐教一下。
        MS_CAOXU:你好 这俩问题解决了没?
        F野鸽子:你好, 请问现在问题解决了吗?
      • 1b0b4fc71f64:楼主 把recyclerview换成listview 不加那个第一个item的那个转账那个 怎么实现不了那个效果
      • 朝花夕拾不起来:展开或折叠时toolbar会闪一下,这是bug吧?
        1b0b4fc71f64:楼主 把recyclerview换成listview 不加那个第一个item的那个转账那个 怎么实现不了那个效果
        朝花夕拾不起来:哦哦,改过透明度参数就好了
      • 6feae1cb6c13:楼主,请教一个问题
        我想 AppBarLayout.setVisibility(View.GONE);
        好像没有效果,请问是哪里需要设置什么参数,
        还是需要其他方法来实现
        Jack921:@6feae1cb6c13 你实际下过源码试过了吗,不明白你什么问题
      • Lz_Docker:👍👍
      • xueximj:下拉时支付宝的可以把上面的appbarlayout带出来,这个怎么整
        xueximj:@Jack921 不是的啦,是那个下滑自然滑动,会自动展开,而不用再下拉一下,这个感觉是不是要处理behavior,这玩意还没看
        Jack921:@xueximj https://github.com/dalong982242260/PullRefresh
        Jack921:@xueximj 你是说下拉刷新的笑脸吗
      • 3711a05e1876:效果不错,很支付宝
        正在学android,先mark一个
      • Anonymous___:闪烁是因为设置alpha的值超过了255.
        Jack921:@Anonymous___ 是临界值alpha收缩多次为0的时候就会出现,之前一直在模拟器所以看不出,谢谢反馈 :blush:
      • Lz_Docker:楼主有点问题: toolbar会闪烁,因该是因为 上滑的距离和透明度的判断存在重复导致的,当上滑距离足够时 toolbar1显示 toobar2透明度达到时 toobar1 又显示所以就闪烁了, 应该加个toobar2打开时的状态,如果已经打开就不再次打开。不知道对不对, :+1:
        Jack921:@xueximj :+1:
        xueximj:哥们把那一块改成这样就好啦,那个100,是我自己感觉的,你可以取值三分之一或者四分之一这样适用性应该更好点,这个值就是titlebar高度
        if (isFirst){
        scrollDistance = appBarLayout.getTotalScrollRange();
        isFirst = false;
        }
        int alpha = 100 - Math.abs(verticalOffset);
        if (alpha >= 0){
        if (View.VISIBLE != mToolbar1.getVisibility()){
        mToolbar1.setVisibility(View.VISIBLE);
        }
        if (View.GONE != mToolbar2.getVisibility()){
        mToolbar2.setVisibility(View.GONE);
        }
        setToolbar1Alpha(alpha * 255 / 100);
        }else {
        if (View.GONE != mToolbar1.getVisibility()){
        mToolbar1.setVisibility(View.GONE);
        }
        if (View.VISIBLE != mToolbar2.getVisibility()){
        mToolbar2.setVisibility(View.VISIBLE);
        }
        setToolbar2Alpha(Math.abs(alpha) * 255 / (scrollDistance - 100));
        }
        Jack921:@Lz_Docker谢谢你提出的问题,之前在一直在模拟器上所以没发现,今天已经修复了这个问题,是临界值alpha多次为0的时候就会出现这问题,代码已上传github你可以下来看看还会不会,如果还有问题欢迎反应,谢谢。
      • HannyYeung:哥们,我也按照你的做了,但是我得上面状态栏没任何变化啊
        HannyYeung:是的还要加入v-21啊
        Jack921: @HannyYeung 状态栏除了有界面文件还有代码,建议你下载源码看吧

      本文标题:高仿支付宝9.9.2版本生活模块界面来讲解Coordinator

      本文链接:https://www.haomeiwen.com/subject/rzviettx.html