DrawerLayout、CoordinatorLayout、CollapsingToolbarLayout的使用--AndroidSupportDesign练手
先po一张效果图
PS:原谅题主的懒惰吧..
看着是不是很酷炫,那是因为5.0的动画做得好,代码其实没有多少,搞清楚这个布局的层次关系很重要。
废话不多说了,先来看布局文件
最外层是一个DrawerLayout,它里面可以嵌套(一个?)container和多个drawer
在这个demo中DrawerLayout包含了一个CoordinatorLayout , ListView , NavigationView
CoordinatorLayout 作为 container的根布局
listView和navigationview作为DarwerLayout中的darwer
在container中用CoordinatorLayout目的是为了我们在滑动recyclerview时,让顶部的appbarlayout中的组件产生响应
appbarlayout中的CollapsingToolbarLayout是用来控制toolbar和banner图片的响应效果
特别注意:为了使得Toolbar可以滑动,我们必须还得有个条件,就是CoordinatorLayout布局下包裹一个可以滑动的布局,比如 RecyclerView,NestedScrollView(经过测试,ListView,ScrollView不支持)具有滑动效果的组件。
下面的就是drawerLayout的使用注意事项了:
按情理来说,一个drawerLayout添加一个drawer就够了,可是脑洞一开,想着多加一个会怎样,尝试之后发现很好玩,以后可以各种乱入drawer了,哈哈哈。
因为做毕设的时候用的DrawerLayout还不是这样方便的,那会使用这个布局,设置起来麻烦很多,而现在的实现这个布局,布局文件设置好之后,只用三句话就搞定了,简单的可怕。
下面贴上源码,各位看官就自行分析吧:
主布局文件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <android.support.design.widget.CoordinatorLayout
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="@android:color/transparent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"> <ImageView
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="banner"
android:scaleType="fitXY"
android:src="@mipmap/banner"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.5" /> <android.support.v7.widget.Toolbar
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@android:color/transparent"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout> <android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior" /> <android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_vertical_margin"
android:src="@mipmap/ic_action_web_site"
app:borderWidth="0dp"
app:elevation="@dimen/fab_elevation"
app:layout_anchor="@id/app_bar_layout"
app:layout_anchorGravity="end|bottom"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7"
app:pressedTranslationZ="@dimen/fab_translation_z_pressed"
app:rippleColor="?attr/colorPrimary" />
</android.support.design.widget.CoordinatorLayout> <ListView
android:id="@+id/id_lv_left_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="end"
android:paddingTop="0dp"
android:background="#ffffffff"
android:clipToPadding="false"
android:divider="@null"
android:listSelector="?attr/selectableItemBackground"
/> <!--<include-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:layout_gravity="start"-->
<!--android:paddingTop="0dp"-->
<!--android:background="#ffffffff"-->
<!--android:clipToPadding="false"-->
<!--android:id="@+id/custom_drawer"-->
<!--layout="@layout/layout_listview_drawer" />--> <android.support.design.widget.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/drawer_header"
app:menu="@menu/menu_navigation_items" /> </android.support.v4.widget.DrawerLayout>
Activity文件:
package com.anhry.hcol.support.design.activity; import android.os.Bundle;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
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.Gravity;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView; import com.anhry.hcol.support.design.adapter.LeftMenuListAdapter;
import com.anhry.hcol.support.design.adapter.MenuItemAdapter;
import com.anhry.hcol.support.design.module.LvMenuItem;
import com.yanbober.support_library_demo.R;
import com.yanbober.support_library_demo.RecyclerViewAdapter; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; /**
* @author HCol
* @email 282386589@qq.com
* @create 2015/8/25
* @modify 2015年8月29日17:29:04
*/
public class DesignDemoActivity extends AppCompatActivity { /**
* views
*/
private DrawerLayout mDrawerLayout;
private CoordinatorLayout mCoordinatorLayout;
private AppBarLayout mAppBarLayout;
private CollapsingToolbarLayout mCollapsingToolbarLayout;
private ImageView mImageView;
private Toolbar mToolbar;
private RecyclerView mRecyclerView;
private NavigationView mNavigationView;
private FloatingActionButton mFloatingActionButton;
private ImageView mRightNavigationBtn; private CoordinatorLayout mCustomDrawer;
private RecyclerView leftMenuList; private ListView mLvLeftMenu;
/**
* members
*/
private RecyclerViewAdapter mAdapter;
private LinearLayoutManager mRecyclerLayoutManager;
private LeftMenuListAdapter mLeftMenuListAdapter;
private List<LvMenuItem> dataSource;
private static final String BTN_RIGHT_MENU_TAG = "tag"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); initViews();
} /**
* init views
*/
private void initViews() {
setContentView(R.layout.activity_my_design);
/* 抽屉形式界面的的两个布局控件
*
* DrawerLayout 做根布局使用
* 因为要显示的内容界面和抽屉视图(NavigationView)是包含在此layout之下的
*
* NavigationView 抽屉布局中的抽屉视图,有源码分析他的实现其实就是一个ListView
* 而这里用的是原生的组件,所以在Menu目录下配置好要显示的条目,引用即可,非常方便.
*
* ref:http://blog.csdn.net/lmj623565791/article/details/46405409
*
* */
// 原生DrawerLayout
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); // 利用ListView仿制的Drawer
mLvLeftMenu = (ListView) findViewById(R.id.id_lv_left_menu);
setUpDrawer(); // 不用在意这一块
// mCustomDrawer = (CoordinatorLayout) findViewById(R.id.custom_drawer);
// leftMenuList = (RecyclerView) findViewById(R.id.rv_left_menu);
// dataSource = new ArrayList<>(
// Arrays.asList(
// new LvMenuItem(R.mipmap.ic_action_web_site, "Home"),
// new LvMenuItem(R.mipmap.ic_action_web_site, "Messages"),
// new LvMenuItem(R.mipmap.ic_action_web_site, "Friends"),
// new LvMenuItem(R.mipmap.ic_action_web_site, "Discussion"),
// new LvMenuItem(R.mipmap.ic_action_web_site, "Discussion"),
// new LvMenuItem(R.mipmap.ic_action_web_site, "Discussion"),
// new LvMenuItem(R.mipmap.ic_action_web_site, "Discussion"),
// new LvMenuItem(R.mipmap.ic_action_web_site, "Discussion"),
// new LvMenuItem(),
// new LvMenuItem("Sub Items"),
// new LvMenuItem(R.mipmap.ic_action_web_site, "Sub Item 1"),
// new LvMenuItem(R.mipmap.ic_action_web_site, "Sub Item 2")
// ));
// mLeftMenuListAdapter = new LeftMenuListAdapter(this, dataSource);
// mRecyclerLayoutManager = new LinearLayoutManager(this);
// leftMenuList.setAdapter(mLeftMenuListAdapter);
// leftMenuList.setLayoutManager(mRecyclerLayoutManager); mNavigationView = (NavigationView) findViewById(R.id.navigation_view);
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
mDrawerLayout.closeDrawers();
return true;
}
});
/* 下面就是抽屉布局中[内容布局]的重点了
*
* CoordinatorLayout 协调者布局
* AppBarLayout 导航栏布局
* CollapsingToolbarLayout ToolBar的可坍塌布局
*
* 首先,这三个布局有什么用呢?
*
* CoordinatorLayout
* 官方文档介绍说是一个增强版的FrameLayout
* 有两种主要的用途:
* 1. 作为一个顶层布局文件来使用
* 2. 作为一个有[多个互动视图]的容器
* 就是当某一视图有特殊行为动作时,其他子视图会进行相应的动作反应。INTERACTION
*
* AppBarLayout
* 一个模块化的布局文件,可以用来装载一切属于AppBar的组件
*
* CollapsingToolbarLayout
*
* CollapsingToolbarLayout is a wrapper for Toolbar which implements a collapsing app bar.
* It is designed to be used as a direct child of a AppBarLayout.
*
* 官方说,它的诞生主要是用来为toolbar锦上添花用的
* 被设计来作为AppBarLayout的亲儿子来使用
*
* */
mCoordinatorLayout = (CoordinatorLayout) findViewById(R.id.main_content);
mAppBarLayout = (AppBarLayout) findViewById(R.id.app_bar_layout);
mCollapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_layout);
mImageView = (ImageView) findViewById(R.id.banner);
mToolbar = (Toolbar) findViewById(R.id.tool_bar); // 创建右边导航按钮
ensureRightButtonView();
mToolbar.setNavigationIcon(R.mipmap.ic_drawer);
mToolbar.addView(mRightNavigationBtn);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mDrawerLayout.openDrawer(GravityCompat.START);
}
});
mCollapsingToolbarLayout.setTitle("CollapsingTitle");
/* init RecyclerView */
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mAdapter = new RecyclerViewAdapter(this);
mRecyclerView.setAdapter(mAdapter);
mRecyclerLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mRecyclerLayoutManager); mFloatingActionButton = (FloatingActionButton)findViewById(R.id.fab);
mFloatingActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Snackbar.make(mRecyclerView , "papa i'm here" , Snackbar.LENGTH_LONG).show();
}
});
} private void setUpDrawer() {
LayoutInflater inflater = LayoutInflater.from(this);
mLvLeftMenu.addHeaderView(inflater.inflate(R.layout.drawer_header, mLvLeftMenu, false));
mLvLeftMenu.setAdapter(new MenuItemAdapter(this));
mLvLeftMenu.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mDrawerLayout.closeDrawers();
}
});
} private void ensureRightButtonView() {
if (mRightNavigationBtn == null) {
mRightNavigationBtn = new ImageButton(this, null,
android.support.v7.appcompat.R.attr.toolbarNavigationButtonStyle);
final Toolbar.LayoutParams lp = generateDefaultLayoutParams();
lp.gravity = GravityCompat.END | (Gravity.TOP & Gravity.VERTICAL_GRAVITY_MASK);
mRightNavigationBtn.setImageResource(R.mipmap.ic_drawer);
mRightNavigationBtn.setLayoutParams(lp);
mRightNavigationBtn.setTag(BTN_RIGHT_MENU_TAG);
mRightNavigationBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mDrawerLayout.openDrawer(GravityCompat.END);
}
});
}
} private Toolbar.LayoutParams generateDefaultLayoutParams() {
return new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.WRAP_CONTENT);
}
}
drawer head:
<?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="wrap_content"
android:background="#000000"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="13dp"> <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon_people" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="UserName"
android:textColor="?attr/colorAccent"
android:textSize="24sp" />
</LinearLayout>
ListViewAdapter:
public class MenuItemAdapter extends BaseAdapter {
private final int mIconSize;
private LayoutInflater mInflater;
private Context mContext; public MenuItemAdapter(Context context) {
mInflater = LayoutInflater.from(context);
mContext = context; mIconSize = context.getResources().getDimensionPixelSize(R.dimen.abc_dialog_padding_material);//24dp
} private List<LvMenuItem> mItems = new ArrayList<LvMenuItem>(
Arrays.asList(
new LvMenuItem(R.mipmap.ic_action_web_site, "Home"),
new LvMenuItem(R.mipmap.ic_action_web_site, "Messages"),
new LvMenuItem(R.mipmap.ic_action_web_site, "Friends"),
new LvMenuItem(R.mipmap.ic_action_web_site, "Discussion"),
new LvMenuItem(),
new LvMenuItem("Sub Items"),
new LvMenuItem(R.mipmap.ic_action_web_site, "Sub Item 1"),
new LvMenuItem(R.mipmap.ic_action_web_site, "Sub Item 2")
)); @Override
public int getCount() {
return mItems.size();
} @Override
public Object getItem(int position) {
return mItems.get(position);
} @Override
public long getItemId(int position) {
return position;
} @Override
public int getViewTypeCount() {
return 3;
} @Override
public int getItemViewType(int position) {
return mItems.get(position).type;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
LvMenuItem item = mItems.get(position);
switch (item.type) {
case LvMenuItem.TYPE_NORMAL:
if (convertView == null) {
convertView = mInflater.inflate(R.layout.design_drawer_item, parent,
false);
}
TextView itemView = (TextView) convertView;
itemView.setText(item.name);
Drawable icon = mContext.getResources().getDrawable(item.icon);
setIconColor(icon);
if (icon != null) {
icon.setBounds(0, 0, mIconSize, mIconSize);
TextViewCompat.setCompoundDrawablesRelative(itemView, icon, null, null, null);
} break;
case LvMenuItem.TYPE_NO_ICON:
if (convertView == null) {
convertView = mInflater.inflate(R.layout.design_drawer_item_subheader,
parent, false);
}
TextView subHeader = (TextView) convertView;
subHeader.setText(item.name);
break;
case LvMenuItem.TYPE_SEPARATOR:
if (convertView == null) {
convertView = mInflater.inflate(R.layout.design_drawer_item_separator,
parent, false);
}
break;
} return convertView;
} public void setIconColor(Drawable icon) {
int textColorSecondary = android.R.attr.textColorSecondary;
TypedValue value = new TypedValue();
if (!mContext.getTheme().resolveAttribute(textColorSecondary, value, true)) {
return;
}
int baseColor = mContext.getResources().getColor(value.resourceId);
icon.setColorFilter(baseColor, PorterDuff.Mode.MULTIPLY);
}
}
Item:
public class LvMenuItem { public LvMenuItem(int icon, String name) {
this.icon = icon;
this.name = name; if (icon == NO_ICON && TextUtils.isEmpty(name)) {
type = TYPE_SEPARATOR;
} else if (icon == NO_ICON) {
type = TYPE_NO_ICON;
} else {
type = TYPE_NORMAL;
} if (type != TYPE_SEPARATOR && TextUtils.isEmpty(name)) {
throw new IllegalArgumentException("you need set a name for a non-SEPARATOR item");
}
} public LvMenuItem(String name) {
this(NO_ICON, name);
} public LvMenuItem() {
this(null);
} public static final int NO_ICON = 0;
public static final int TYPE_NORMAL = 0;
public static final int TYPE_NO_ICON = 1;
public static final int TYPE_SEPARATOR = 2; public int type;
public String name;
public int icon;
}
Item的资源文件:
design_drawer_item_separator:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"> <View android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:attr/listDivider"/> </FrameLayout>
design_drawer_item_subheader:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeightSmall"
android:gravity="center_vertical|start"
android:maxLines="1"
android:paddingLeft="?attr/listPreferredItemPaddingLeft"
android:paddingRight="?attr/listPreferredItemPaddingRight"
android:textAppearance="?attr/textAppearanceListItem"
android:textColor="?android:textColorSecondary"/>
design_drawer_item:
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeightSmall"
android:paddingLeft="?attr/listPreferredItemPaddingLeft"
android:paddingRight="?attr/listPreferredItemPaddingRight"
android:drawablePadding="32dp"
android:gravity="center_vertical|start"
android:maxLines="1"
android:textAppearance="?attr/textAppearanceListItem"
android:textColor="?android:attr/textColorPrimary"/>
参考资料:
http://www.2cto.com/kf/201506/409067.html
http://www.open-open.com/lib/view/open1433385856119.html#_label8
http://blog.csdn.net/lmj623565791/article/details/46405409
PS:为什么放多个drawer,而drawerLayout打开drawer的时候不会混乱呢?
没事就看看源码,反正又不要钱..
DrawerLayout、CoordinatorLayout、CollapsingToolbarLayout的使用--AndroidSupportDesign练手的更多相关文章
- Python学习路径及练手项目合集
Python学习路径及练手项目合集 https://zhuanlan.zhihu.com/p/23561159
- Cocos2d-Lua (练手) 微信打飞机
学习下lua,目前入门级,使用版本为 v3.3 Final For Win,空闲时间不足,只能断断续续写点东西. 一.子弹效果 子弹只做了一种,扇形发射,可以增加扇形大小,子弹的 ...
- web前端学习部落22群分享给需要前端练手项目
前端学习还是很有趣的,可以较快的上手然后自己开发一些好玩的项目来练手,网上也可以一抓一大把关于前端开发的小项目,可是还是有新手在学习的时候不知道可以做什么,以及怎么做,因此,就整理了一些前端项目教程, ...
- webpack练手项目之easySlide(三):commonChunks(转)
Hello,大家好. 在之前两篇文章中: webpack练手项目之easySlide(一):初探webpack webpack练手项目之easySlide(二):代码分割 与大家分享了webpack的 ...
- webpack练手项目之easySlide(二):代码分割(转)
在上一篇 webpack练手项目之easySlide(一):初探webpack 中我们一起为大家介绍了webpack的基本用法,使用webpack对前端代码进行模块化打包. 但是乍一看webpack ...
- webpack练手项目之easySlide(一):初探webpack (转)
最近在学习webpack,正好拿了之前做的一个小组件,图片轮播来做了下练手,让我们一起来初步感受下webpack的神奇魅力. webpack是一个前端的打包管理工具,大家可以前往:http:/ ...
- JAVA大数类练手
今天突然看到了OJ上的大数类题目,由于学习了一点大数类的知识.果断水了6道题......都是非常基础的.就当的练手的吧. 学到的只是一些大数类的基本操作.以后多做点这样的题,争取熟练运用水大数题... ...
- Python之路【第二十四篇】:Python学习路径及练手项目合集
Python学习路径及练手项目合集 Wayne Shi· 2 个月前 参照:https://zhuanlan.zhihu.com/p/23561159 更多文章欢迎关注专栏:学习编程. 本系列Py ...
- node论坛练手
当时学node,自己写了个论坛练手,现在看还是有很多问题,有时间好好改改 https://github.com/hitbs228/countdown
随机推荐
- <转>eclipse如何修改dynamic web module version .
--------------------------------------------------------------------------------------------- 原 ...
- Windows下bat命令
一.简单批处理内部命令简介 1.Echo 命令 打开回显或关闭请求回显功能,或显示消息.如果没有任何参数,echo 命令将显示当前回显设置. 语法 echo [{on│off}] [mess ...
- 点语法、property、self注意
1.点语法(找出不合理的地方)#import <Foundation/Foundation.h>@interface Person : NSObject{ int _age;}- ( ...
- 概率法求解三阶幻方[C语言]
#include <stdio.h> #include <string.h> ]={,,,,,,,,}; ]; ][]; int sum(int su[]) { ; ;su[i ...
- sql CAST用法
(1).CAST()函数的参数是一个表达式,它包括用AS关键字分隔的源值和目标数据类型.以下例子用于将文本字符串'12'转换为整型: ' AS int) (2).返回值是整型值12.如果试图将一个代表 ...
- 修改SlidingMenu,使其能够完美运行
今天想给项目添加一个侧边栏的效果,使用到了https://github.com/jfeinstein10/SlidingMenu这个开源项目.项目本身可以通过github下载.此项目同时又依赖于一个名 ...
- 这才是正确删除 office 的方式
https://support.office.com/zh-cn/article/%E9%80%9A%E8%BF%87%E5%9C%A8%E9%87%8D%E6%96%B0%E5%AE%89%E8%A ...
- 使用WinSetupFromUSB来U盘安装windowsXP(不使用win PE系统)
目前用U盘安装XP的多数方法都要借助WINPE,比较麻烦.使用WinSetupFromUSB只需要下载一个6.5MB的绿色软件就可以制作好windows xp的安装U盘,方便简捷. WinSetupF ...
- Unix/Linux环境C编程入门教程(1) Solaris 11 64bit环境搭建
Unix/Linux版本众多,我们推荐Unix/Linux初学者选用几款典型的Unix/Linux操作系统进行学习. 本文就带大家来安装Solaris 11 64位并且配置好C/C++开发环境 本文所 ...
- &&与||的用法总结
a() && b() :如果执行a()后返回true,则执行b()并返回b的值:如果执行a()后返回false,则整个表达式返回a()的值,b()不执行: a() || b() :如果 ...