Android基础篇-材料设计兼容库(Design Support Library)

一.CoordinatorLayout(协调布局)

CoordinatorLayout作为“super-powered FrameLayout”基本实现两个功能:
1、作为顶层布局
2、调度协调子布局

CoordinatorLayout是一个非常强大的控件,它接管了child组件之间的交互。

二:悬浮操作按钮 Floating Action Button

floating action button 是一个负责显示界面基本操作的圆形按钮。Design library中的FloatingActionButton 实现了一个默认颜色为主题中colorAccent的悬浮操作按钮。

效果图:
这里写图片描述

代码

<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"
    tools:context=".MainActivity">
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="30dp"
        android:src="@android:drawable/ic_dialog_email"
        android:layout_gravity="bottom|right"/>
</android.support.design.widget.CoordinatorLayout>

除了一般大小的悬浮操作按钮,它还支持mini size(fabSize=“mini”)。FloatingActionButton继承自ImageView,你可以使用android:src或者ImageView的任意方法,比如setImageDrawable()来设置FloatingActionButton里面的图标。

三,SnackBar(升级版的Toast)

为一个操作提供轻量级的,快速的反馈是使用snackbar的最好时机。snackbar显示在屏幕的底部,包含了文字信息与一个可选的操作按钮。在指定时间结束之后自动消失。另外,用户还可以在超时之前将它滑动删除。

效果图:
这里写图片描述

代码:

Snackbar.make(view,"点击了FloatingActionButton",Snackbar.LENGTH_SHORT)
                        .setAction("Hello SnackBar", new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                Toast.makeText(MainActivity.this,"点击了Snackbar",Toast.LENGTH_SHORT).show();
                            }
                        })
                        .show();

因为我这里使用CoordinatorLayout作为父布局,floatingActionButton以动画效果进入的时候自动向上移动让出位置,并且在floatingActionButton动画地消失的时候回到原来的位置,不需要额外的代码。

你应该注意到了make()方法中把一个View作为第一个参数 - Snackbar试图找到一个合适的父亲以确保自己是被放置于底部。

四:TabLayout:

Design library的TabLayout 既实现了固定的选项卡 - view的宽度平均分配,也实现了可滚动的选项卡 - view宽度不固定同时可以横向滚动。

它可以使tab的选中事件能更新ViewPager,同时ViewPager的页面改变能更新tab的选中状态。

效果图:
这里写图片描述

代码:
activity_main

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:orientation="vertical">
    <android.support.design.widget.TabLayout
        android:id="@+id/tabLayout"
        app:tabGravity="fill"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="fixed"
        />
    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#ffffff"
        />
</LinearLayout>

关于TabLayout的tabMode和tabGrabity属性:
TabGravity:放置Tab的Gravity,有GRAVITY_CENTER 和 GRAVITY_FILL两种效果。顾名思义,一个是居中,另一个是尽可能的填充(注意,GRAVITY_FILL需要和MODE_FIXED一起使用才有效果)

TabMode:布局中Tab的行为模式(behavior mode),有两种值:MODE_FIXED 和 MODE_SCROLLABLE。

MODE_FIXED:固定tabs,并同时显示所有的tabs。

MODE_SCROLLABLE:可滚动tabs,显示一部分tabs,在这个模式下能包含长标签和大量的tabs,最好用于用户不需要直接比较tabs。

MainActivity

import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import java.util.ArrayList;
import static android.support.design.widget.TabLayout.*;

public class MainActivity extends AppCompatActivity {

    Context context;
    ViewPager viewPager;
    TabLayout tabLayout;
    ArrayList<View> list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context=this;
        initView();
    }


    public void initView(){
        list=new ArrayList<View>();
        LayoutInflater inflater= LayoutInflater.from(context);
        View view1=inflater.inflate(R.layout.page1,null);
        View view2=inflater.inflate(R.layout.page2,null);
        View view3=inflater.inflate(R.layout.page3,null);
        list.add(view1);list.add(view2);list.add(view3);
        viewPager= (ViewPager) findViewById(R.id.viewPager);
        tabLayout= (TabLayout) findViewById(R.id.tabLayout);
        MyAdapter adapter=new MyAdapter();
        viewPager.setAdapter(adapter);
        //与ViewPager建立联系
        tabLayout.setupWithViewPager(viewPager);
    }

    public class MyAdapter extends PagerAdapter{
        private String[] titles = new String[]{"Tab1", "Tab2", "Tab3"};
        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == arg1;
        }

        @Override
        public int getCount() {
            return list.size();
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return titles[position];
        }

        @Override
        public void destroyItem(View container, int position, Object object) {
            ((ViewPager) container).removeView(list.get(position));
        }

        @Override
        public Object instantiateItem(View container, int position) {
            ((ViewPager) container).addView(list.get(position));
            return list.get(position);
        }
    }


}

注意:上面的Tab标签只有在adapter中重写getPageTitle方法才会显示tab

五、AppBarLayout

详情参考:http://www.open-open.com/lib/view/open1472718470375.html

效果图:
这里写图片描述

布局代码:

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/coordinator_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolBar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="#30469b"
            app:layout_scrollFlags="scroll|enterAlways" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tabLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#30469b"
            app:tabGravity="fill"
            app:tabMode="fixed"
            app:tabSelectedTextColor="#ff0000"
            app:tabTextColor="#ffffff" />
    </android.support.design.widget.AppBarLayout>


        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

</android.support.design.widget.CoordinatorLayout>

MainActivity:

import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.TextViewCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;
import static android.support.design.widget.TabLayout.*;

public class MainActivity extends AppCompatActivity {

    Context context;
    ViewPager viewPager;
    TabLayout tabLayout;
    ArrayList<View> list;
    Toolbar toolbar;
    RecyclerView recyclerView;
    ArrayList<String> strings=new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        context=this;
        initView();
    }

    public void initData(){
        for (int i=0;i<30;i++){
            strings.add(i+"");
        }
    }

    public void initView(){
        list=new ArrayList<View>();
        LayoutInflater inflater= LayoutInflater.from(context);
        View view1=inflater.inflate(R.layout.page1,null);
        View view2=inflater.inflate(R.layout.page2,null);
        View view3=inflater.inflate(R.layout.page3,null);
        list.add(view1);list.add(view2);list.add(view3);
        recyclerView= (RecyclerView)view1. findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(context,LinearLayoutManager.VERTICAL,false));
        RecyclerAdapter adapter1=new RecyclerAdapter();
        recyclerView.setAdapter(adapter1);
        viewPager= (ViewPager) findViewById(R.id.viewpager);
        tabLayout= (TabLayout) findViewById(R.id.tabLayout);
        toolbar= (Toolbar) findViewById(R.id.toolBar);
        setSupportActionBar(toolbar);
        MyAdapter adapter=new MyAdapter();
        viewPager.setAdapter(adapter);
        //与ViewPager建立联系
        tabLayout.setupWithViewPager(viewPager);
    }

    public class MyAdapter extends PagerAdapter{
        private String[] titles = new String[]{"Tab1", "Tab2", "Tab3"};
        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == arg1;
        }

        @Override
        public int getCount() {
            return list.size();
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return titles[position];
        }

        @Override
        public void destroyItem(View container, int position, Object object) {
            ((ViewPager) container).removeView(list.get(position));
        }

        @Override
        public Object instantiateItem(View container, int position) {
            ((ViewPager) container).addView(list.get(position));
            return list.get(position);
        }
    }

    public class  RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder>{

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View itemView=LayoutInflater.from(parent.getContext()).inflate(R.layout.page_item,parent,false);
            ViewHolder viewHolder=new ViewHolder(itemView);
            return viewHolder;
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            holder.tv_item.setText(strings.get(position));
        }

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

        public class ViewHolder extends  RecyclerView.ViewHolder{

            TextView tv_item;
            public ViewHolder(View itemView) {
                super(itemView);
                tv_item= (TextView)itemView.findViewById(R.id.tv_item);
            }
        }

    }
}

六,TextInputLayout(EditText升级版):

TextInputLayout控件和LinearLayout完全一样,它只是一个容器。跟ScrollView一样,TextInputLayout只接受一个子元素。子元素需要是一个EditText元素。

众所周知EditText有一个hint属性,在为输入任何东西 时候,hint会默认显示,一点我们输入,hint则影藏,TextInputLayout则完全解决了这个问题,hint显示在EditText上方。

包含在TextInputLayout中的EditText如果InputType是TextPaswrod,系统会帮你添加一个显示或者隐藏密码的控件在EditText末尾

TextInputLayout有一个setError()方法可以监听当前输入的数据是否符合要求去验证错误。

效果图:
这里写图片描述

布局代码:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/coordinator_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.TextInputLayout
        android:id="@+id/usernameWrapper"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:hint="密码"
            android:inputType="textPassword"
            android:id="@+id/et_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </android.support.design.widget.TextInputLayout>

</LinearLayout>

七、BottomNavigationBar(导航控制)

效果图:

未设置mode:
这里写图片描述

mode:MODE_FIXED:
这里写图片描述

布局代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior="@string/appbar_scrolling_view_behavior"
               >

    <LinearLayout
        android:id="@+id/tb"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" />
    <com.ashokvarma.bottomnavigation.BottomNavigationBar
        android:id="@+id/bottom_navigation_bar"
        android:layout_width="match_parent"
        android:layout_alignParentBottom="true"
        android:layout_height="wrap_content"/>
</RelativeLayout>

主代码:

import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.ashokvarma.bottomnavigation.BottomNavigationBar;
import com.ashokvarma.bottomnavigation.BottomNavigationItem;


/**
 * BottomNavigationBar实现
 */
class MainActivity extends AppCompatActivity implements BottomNavigationBar.OnTabSelectedListener {

    private BottomNavigationBar bottomNavigationBar;
    int lastSelectedPosition = 0;
    private String TAG = MainActivity.class.getSimpleName();
    private LocationFragment mLocationFragment;
    private FindFragment mFindFragment;
    private FavoritesFragment mFavoritesFragment;
    private BookFragment mBookFragment;

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

        bottomNavigationBar = (BottomNavigationBar) findViewById(R.id.bottom_navigation_bar);

        bottomNavigationBar.setMode(BottomNavigationBar.MODE_FIXED);
        bottomNavigationBar.setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_RIPPLE);

        bottomNavigationBar
                .addItem(new BottomNavigationItem(R.mipmap.down_master_key, "位置").setActiveColor(Color.YELLOW))
                .addItem(new BottomNavigationItem(R.mipmap.down_param, "发现").setActiveColor(Color.BLUE))
                .addItem(new BottomNavigationItem(R.mipmap.login, "爱好").setActiveColor(Color.CYAN))
                .addItem(new BottomNavigationItem(R.mipmap.merch_info, "图书").setActiveColor(Color.DKGRAY))
                .setFirstSelectedPosition(lastSelectedPosition )
                .initialise();

        bottomNavigationBar.setTabSelectedListener(this);
        setDefaultFragment();
    }

    /**
     * 设置默认的
     */
    private void setDefaultFragment() {
        FragmentManager fm = getFragmentManager();
        FragmentTransaction transaction = fm.beginTransaction();
        mLocationFragment = LocationFragment.newInstance("位置");
        transaction.replace(R.id.tb, mLocationFragment);
        transaction.commit();
    }

    // 当第position个tab被选中时,调用此方法
    // 这里可以完成对Fragment的切换
    @Override
    public void onTabSelected(int position) {
        Log.d(TAG, "onTabSelected() called with: " + "position = [" + position + "]");
        FragmentManager fm = this.getFragmentManager();
        //开启事务
        FragmentTransaction transaction = fm.beginTransaction();
        switch (position) {
            case 0:
                if (mLocationFragment == null) {
                    mLocationFragment = LocationFragment.newInstance("位置");
                }
                transaction.replace(R.id.tb, mLocationFragment);
                break;
            case 1:
                if (mFindFragment == null) {
                    mFindFragment = FindFragment.newInstance("发现");
                }
                transaction.replace(R.id.tb, mFindFragment);
                break;
            case 2:
                if (mFavoritesFragment == null) {
                    mFavoritesFragment = FavoritesFragment.newInstance("爱好");
                }
                transaction.replace(R.id.tb, mFavoritesFragment);
                break;
            case 3:
                if (mBookFragment == null) {
                    mBookFragment = BookFragment.newInstance("图书");
                }
                transaction.replace(R.id.tb, mBookFragment);
                break;
            default:
                break;
        }
        // 事务提交
        transaction.commit();
    }

    // 对未被选择的tab进行处理,其中pisition仍然是被选中的tab
    @Override
    public void onTabUnselected(int position) {
        Log.d(TAG, "onTabUnselected() called with: " + "position = [" + position + "]");
    }

    // 当被选中的tab 再一次被点击时调用此方法
    @Override
    public void onTabReselected(int position) {

    }
}

注意: bottomNavigationBar.setMode(BottomNavigationBar.MODE_FIXED);这里将mode设置成了fixed所以有了图二的效果

关于mode:
Java: setMode():MODE_DEFAULT,MODE_FIXED,MODE_SHIFTING

xml属性:bnbMode:mode_default,mode_fixed,mode_shifting

注意,mode需要在添加BottomNavigationItem之前进行设置,否则设置无效

关于style:
设置导航栏背景样式

java:
setBackgroundStyle():BACKGROUND_STYLE_DEFAULT,
BACKGROUND_STYLE_STATIC,
BACKGROUND_STYLE_RIPPLE

xml属性:
bnbBackgroundStyle:background_style_default,
background_style_static,
background_style_riple

效果就自行去慢慢试了。

给出一个Fragment代码:


import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;


public class LocationFragment extends Fragment {


    public static LocationFragment newInstance(String param1) {
        LocationFragment fragment = new LocationFragment();
        Bundle args = new Bundle();
        args.putString("agrs1", param1);
        fragment.setArguments(args);
        return fragment;
    }

    public LocationFragment() {

    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_location, container, false);
        Bundle bundle = getArguments();
        String agrs1 = bundle.getString("agrs1");
        TextView tv = (TextView)view.findViewById(R.id.tv_location);
        tv.setText(agrs1);
        return view;
    }



}

八 .DrawerLayout和NavigationView实现侧滑:

对于前面已经写了单独用DrawerLayout实现侧滑,现在有了NavigationView使我们更加方便的实现侧滑了

先看一下效果图:
这里写图片描述

NavigationView和以前的控件一样,只是多了两个特殊的属性

1.headerLayout:头部布局,图中绿色部分

2.menu:菜单,图中选项栏

使用方法:
镶嵌在DrawerLayout控件中

代码布局

activity_main:

<?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:fitsSystemWindows="true"
              android:orientation="vertical">
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        />

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:openDrawer="start">

        <include layout="@layout/content_main" />

        <android.support.design.widget.NavigationView
            android:id="@+id/nav_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:headerLayout="@layout/nav_header_main"
            app:menu="@menu/activity_main_drawer" />
    </android.support.v4.widget.DrawerLayout>
</LinearLayout>

content_main就是一个HelloWolder,这里不再给出

看到NavigationView的headerLayout和menu属性,一个是layout,一个是menu,根据需求自定义

MainActivity:

import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) this.findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        
        DrawerLayout drawer = (DrawerLayout) this.findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    //menu属性item的监听事件
    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_camera) {
            // Handle the camera action
        } else if (id == R.id.nav_gallery) {

        } else if (id == R.id.nav_slideshow) {

        } else if (id == R.id.nav_manage) {

        } else if (id == R.id.nav_share) {

        } else if (id == R.id.nav_send) {

        }

        return true;
    }
}

九、CoordinatorLayout与CollapsingToolbarLayout

CollapsingToolbarLayout作用是提供了一个可以折叠的Toolbar,它继承至FrameLayout,给它设置layout_scrollFlags,它可以控制包含在CollapsingToolbarLayout中的控件(如:ImageView、Toolbar)在响应layout_behavior事件时作出相应的scrollFlags滚动事件(移除屏幕或固定在屏幕顶端)。

效果图:这里写图片描述

因为这个布局是根据滑动来突出效果的,所以这里我提供了一个RecyclerView

布局:

<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"
    tools:context=".MainActivity">
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="256dp"
        android:fitsSystemWindows="true">
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="#30469b"
            app:expandedTitleMarginStart="48dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:src="@drawable/banner2"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.7"  />
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin" />
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="none" />
    </LinearLayout>
</android.support.design.widget.CoordinatorLayout>

注意底部 LinearLayout我们加上了,表示在ToolBar下面显示

  app:layout_behavior="@string/appbar_scrolling_view_behavior">

在CollapsingToolbarLayout中:

我们设置了layout_scrollFlags:关于它的值我这里再说一下:

scroll - 想滚动就必须设置这个。

enterAlways - 实现quick return效果, 当向下移动时,立即显示View(比如Toolbar)。

exitUntilCollapsed - 向上滚动时收缩View,但可以固定Toolbar一直在上面。

enterAlwaysCollapsed - 当你的View已经设置minHeight属性又使用此标志时,你的View只能以最小高度进入,只有当滚动视图到达顶部时才扩大到完整高度。

其中还设置了一些属性,简要说明一下:

contentScrim - 设置当完全CollapsingToolbarLayout折叠(收缩)后的背景颜色。

expandedTitleMarginStart - 设置扩张时候(还没有收缩时)title向左填充的距离。

在ImageView控件中:

我们设置了:

layout_collapseMode (折叠模式) - 有两个值:

pin - 设置为这个模式时,当CollapsingToolbarLayout完全收缩后,Toolbar还可以保留在屏幕上。

parallax - 设置为这个模式时,在内容滚动时,CollapsingToolbarLayout中的View(比如ImageView)也可以同时滚动,实现视差滚动效果,通常和layout_collapseParallaxMultiplier(设置视差因子)搭配使用。

layout_collapseParallaxMultiplier(视差因子) - 设置视差滚动因子,值为:0~1。

在Toolbar控件中:

我们设置了layout_collapseMode(折叠模式):为pin。

综上分析:当设置了layout_behavior的控件响应起了CollapsingToolbarLayout中的layout_scrollFlags事件时,ImageView会有视差效果的向上滚动移除屏幕,当开始折叠时CollapsingToolbarLayout的背景色(也就是Toolbar的背景色)就会变为我们设置好的背景色,Toolbar也一直会固定在最顶端。

主代码,其中RecylerView自行配置,比较简单:

        Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
        //使用CollapsingToolbarLayout必须把title设置到CollapsingToolbarLayout上,设置到Toolbar上则不会显示
        CollapsingToolbarLayout mCollapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_layout);
        mCollapsingToolbarLayout.setTitle("CollapsingToolbarLayout");
        //通过CollapsingToolbarLayout修改字体颜色
        mCollapsingToolbarLayout.setExpandedTitleColor(Color.WHITE);//设置还没收缩时状态下字体颜色
        mCollapsingToolbarLayout.setCollapsedTitleTextColor(Color.GREEN);//设置收缩后Toolbar上字体的颜色
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有头发的猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值