Android Design风格实现可折叠页面CoordinatorLayout+AppBarLayout+CollapsingToolbarLayout

最近有个页面需要做到折叠效果,然后去看了下Design包,百度找资料,反反复复,今天总算做到差不多效果,记录下。

首页是添加包,因为还是用的javaEE开发工具,更新了下ADT以及sdk后,下载Android Support library包,需要说的是,如果你的sdk manager如果没有获取到Android

 Support library包,如下图1,

这个是时候勾选上obsolete选项,就可以看到了,如下图,需更新到最新版本


都更新到最新版本后,在sdk目录找到support目录下的v7包下appcompat(这里我还导入了RecyclerView包)的以及design包,在eclipse中右键import进去,这个时候

记得勾选copy到项目空间里,然后design以及v7其他导入包,都选择最新版本的编译环境,我选的是6.0,appcompat这里需要作为库,被design引用,同时design也需要

作为库,被自己需要用到的项目引用,包都导入完成后,就可以在项目里开始搭截面了。


design下不使用actionbar,改用toolbar,所以这里activity使用的主题是noactionbar,在res文件下的values-v19中新建style.xml,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
       <style name="ActionBarTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowTranslucentNavigation" >true</item>
        <item name="android:windowTranslucentStatus">true</item>
        <!-- toolbar(actionbar)颜色 -->
        <item name="colorPrimary">#ff7e00</item>
        <!-- 状态栏颜色 -->
        <item name="colorPrimaryDark">#ff7e00</item>
        <item name="colorAccent">#ff7e00</item>
    </style>
</resources>

activity直接应用该主题,就行了,下面贴上activity的xml文件:

<?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:app1="http://schemas.android.com/apk/res/com.metre_design"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="true"
    android:fitsSystemWindows="true"
    android:paddingTop="25dp" >


    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true" >


        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="256dp"
            android:fitsSystemWindows="true"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" 
            android:id="@+id/appbarlayout">


            <android.support.design.widget.CollapsingToolbarLayout
                android:id="@+id/collapse_toolbar"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_scrollFlags="scroll|enterAlways|exitUntilCollapsed|snap"
                android:fitsSystemWindows="true"
                app:contentScrim="@color/bar_bg_color" >


                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    app:layout_collapseMode="parallax"
                    app:layout_collapseParallaxMultiplier="0.7"
                    android:background="@drawable/mus"
                    android:fitsSystemWindows="true" >


                    <ImageView
                        android:id="@+id/header"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:scaleType="centerCrop" />


                    <TextView
                        android:id="@+id/tv_title"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_centerInParent="true"
                        android:text="这只是个标题"
                        android:textColor="@color/black" />


                    <TextView
                        android:id="@+id/tv_title2"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_below="@id/tv_title"
                        android:layout_centerInParent="true"
                        android:text="这只是个标题"
                        android:textColor="@color/black" />
                </RelativeLayout>


                <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="45dp"
                    app:layout_collapseMode="pin"
                    android:gravity="top"
                    android:minHeight="45dp"
                    app:contentInsetStart="0dp"
                    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                    app:titleMarginTop="15dp" >
                    
                    <include layout="@layout/toolbar" />
                    
                </android.support.v7.widget.Toolbar>
            </android.support.design.widget.CollapsingToolbarLayout>
        </android.support.design.widget.AppBarLayout>


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:orientation="vertical" >


            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="45dp"
                app:tabGravity="fill"
                app:tabMode="fixed" />


            <android.support.v7.widget.RecyclerView
                android:id="@+id/behavior_demo_recycler"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </LinearLayout>
    </android.support.design.widget.CoordinatorLayout>


</LinearLayout>


布局依次是LinearLayout-CoordinatorLayout-AppBarLayout-CollapsingToolbarLayout


代码内容具体跟网上的都差不多,这里说下一些注意的,toobar在不设置 app:contentInsetStart="0dp"的属性下,左侧会有一个边距存在,就算自定义了toobar也会存

在,另外AppBarLayout下的布局需要包含可滑动的子布局,我尝试过直接放lRecyclerView或者listview,都不能把AppBarLayout推上去,触动不了折叠效果,这里也是

我不太明白的地方,加了个LinearLayout就可以了,有了解的求说下,然后这个触动滑动主要是通

 app:layout_behavior="@string/appbar_scrolling_view_behavior"这个属性来实现的,这个behavior也可以自定义,这个百度挺多资料找的,另外顶部几个布局都需要

加上 android:fitsSystemWindows="true"属性,CollapsingToolbarLayout中有一个属性也说一下,

app:layout_scrollFlags="scroll|enterAlways|exitUntilCollapsed|snap",这个属性绝对了折叠的效果,scroll是必须的,另外的几个是看应用场景选择

这里的toolbar我是用自定义的布局,xml如下:

?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >


    <TextView
        android:id="@+id/toolbar_back"
        android:layout_width="20dp"
        android:layout_height="35dp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="10dp"
        android:background="@drawable/back"
        android:textColor="#BFBFBF"
        android:textSize="16dp" />


    <TextView
        android:id="@+id/toolbar_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textColor="#FFFFFF"
        android:textSize="16dp" />


    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toLeftOf="@+id/toolbar_num"
        android:background="@android:drawable/ic_menu_upload" />


    <TextView
        android:id="@+id/toolbar_num"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginLeft="16dp"
        android:paddingRight="10dp"
        android:text="num"
        android:textColor="#FFFFFF"
        android:textSize="16dp" />


</RelativeLayout>

AppBarLayout中可以监听到折叠状态-是否折叠完成-或者折叠中,需要先继承接口AppBarLayout.OnOffsetChangedListener,


import android.support.design.widget.AppBarLayout;

//监听AppBarLayout折叠状态
public abstract class AppBarStateChangeListener implements
AppBarLayout.OnOffsetChangedListener {
public enum State {
EXPANDED, COLLAPSED, IDLE
}

private State mCurrentState = State.IDLE;

@Override
public final void onOffsetChanged(AppBarLayout appBarLayout, int i) {
if (i == 0) {
if (mCurrentState != State.EXPANDED) {
onStateChanged(appBarLayout, State.EXPANDED);
}
mCurrentState = State.EXPANDED;
} else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) {
if (mCurrentState != State.COLLAPSED) {
onStateChanged(appBarLayout, State.COLLAPSED);
}
mCurrentState = State.COLLAPSED;
} else {
if (mCurrentState != State.IDLE) {
onStateChanged(appBarLayout, State.IDLE);
}
mCurrentState = State.IDLE;
}
}


public abstract void onStateChanged(AppBarLayout appBarLayout, State state);
}


然后在调用AppBarStateChangeListener 就行,MainActivity代码如下:

package com.metre_design;


import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.support.v7.widget.Toolbar;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;


public class MainActivity extends AppCompatActivity {
AppBarLayout appbarlayout;
Toolbar toolbar;
TabLayout tablayout;
ViewPager viewpager;
TextView toolbar_back,toolbar_title;
RecyclerView lv;
private List<String> mDatas;
private HomeAdapter mAdapter;

private SimpleFragmentPagerAdapter pagerAdapter;


@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

              //针对状态栏透明以及颜色设置
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {  
       Window window = getWindow();  
       window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS  
               | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);  
       window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN  
               | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION  
               | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);  
       window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);  
       //获取样式中的属性值  
       TypedValue typedValue = new TypedValue();  
       this.getTheme().resolveAttribute(android.R.attr.colorPrimary, typedValue, true);  
       int[] attribute = new int[] { android.R.attr.colorPrimary };  
       TypedArray array = this.obtainStyledAttributes(typedValue.resourceId, attribute);  
       int color = array.getColor(0, Color.TRANSPARENT);  
       array.recycle();  
       window.setStatusBarColor(color);  
   }  
initData();
toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("");
setSupportActionBar(toolbar);
toolbar_back=(TextView)findViewById(R.id.toolbar_back);
toolbar_back.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "ok", Toast.LENGTH_SHORT).show();
}
});

toolbar_title=(TextView)findViewById(R.id.toolbar_title);
toolbar_title.setText("测试");

tablayout = (TabLayout) findViewById(R.id.tabs);
tablayout.addTab(tablayout.newTab().setText("Tab 1"));
tablayout.addTab(tablayout.newTab().setText("Tab 2"));
tablayout.addTab(tablayout.newTab().setText("Tab 3"));


lv = (RecyclerView) findViewById(R.id.behavior_demo_recycler);
lv.setLayoutManager(new LinearLayoutManager(this));
// 设置Item增加、移除动画
lv.setItemAnimator(new DefaultItemAnimator());
lv.setAdapter(mAdapter = new HomeAdapter());

appbarlayout=(AppBarLayout)findViewById(R.id.appbarlayout);
//监听appbarlayout折叠状态
appbarlayout.addOnOffsetChangedListener(new AppBarStateChangeListener() {
@Override
public void onStateChanged(AppBarLayout appBarLayout, State state) {
if( state == State.EXPANDED ) {
                   //展开状态
toolbar_title.setText("");
               }else if(state == State.COLLAPSED){
                   //折叠状态
               toolbar_title.setText("测试");
               }else {
                   //中间状态
               }
}

});
}


protected void initData() {
mDatas = new ArrayList<String>();
for (int i = 'A'; i < 'z'; i++) {
mDatas.add("" + (char) i);
}
}

class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder> {


@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
MyViewHolder holder = new MyViewHolder(LayoutInflater.from(
MainActivity.this).inflate(R.layout.item_home, parent,
false));
return holder;
}


@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.tv.setText(mDatas.get(position));
}


@Override
public int getItemCount() {
return mDatas.size();
}


class MyViewHolder extends ViewHolder {


TextView tv;


public MyViewHolder(View view) {
super(view);
tv = (TextView) view.findViewById(R.id.id_num);
}
}
}
}

状态栏的着色需要先设置透明,然后再设置颜色,主题中已经设置透明属性,代码判断版本着色,到这里具体算完成差不多了,过程遇到挺多问题,百度的很多,有什么不合理的地方,求留言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值