Google I/O 2014 发布的 Material Design 势必将会成为统一 Android Mobile、Android Table、Desktop Chrome 等全平台设计语言规范。然而普及程度并没有想象中的那么好,于是Google提供了一个Design Support库方便开发者开发。在2015年I / O大会上,Google发布了一个新的设计支持库,该库有助于引入大量材料设计组件,包括导航抽屉视图,浮动标签,浮动动作按钮,Snackbars以及用于将运动和滚动事件。 该库支持Android 2.3及更高版本。
implementation 'com.android.support:design:27.1.1'
Toolbar可以理解升级版的Actionbar,由于Actionbar设计原因,只能位于Activity顶端,不能实现Material Design效果,因此官方推荐使用Toolbar来替代Actionbar。
注意:
直接上代码实现一个Toolbar,布局文件、Java代码如下:
.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_scrollFlags="scroll|snap|enterAlways"
app:popupTheme="@style/Theme.AppCompat.Light" />
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
material_design_layout.xml
"1.0" encoding="utf-8"?>
.support.v4.widget.DrawerLayout 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:id="@+id/drawer_layout"
android:orientation="vertical">
"match_parent"
android:layout_height="match_parent">
.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_scrollFlags="scroll|snap|enterAlways"
app:popupTheme="@style/Theme.AppCompat.Light" />
.support.design.widget.NavigationView
android:id="@+id/navigationView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/header_layout"
app:menu="@menu/drawer_layout_menu" />
.support.v4.widget.DrawerLayout>
header_layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="180dp"
android:background="?attr/colorPrimary"
android:padding="10dp">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/civ_icon"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_centerInParent="true"
android:src="@drawable/ic_account_circle_gray_24dp" />
<TextView
android:id="@+id/tv_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/civ_icon"
android:layout_centerInParent="true"
android:padding="2dp"
android:text="username"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_mail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_username"
android:layout_centerInParent="true"
android:padding="2dp"
android:text="[email protected]"
tools:ignore="HardcodedText" />
RelativeLayout>
drawer_layout_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_call"
android:icon="@drawable/ic_account_circle_black_24dp"
android:title="Profile"
tools:ignore="HardcodedText" />
<item
android:id="@+id/nav_friends"
android:icon="@drawable/ic_people_black_24dp"
android:title="Friends"
tools:ignore="HardcodedText" />
<item
android:id="@+id/nav_location"
android:icon="@drawable/ic_place_black_24dp"
android:title="Location"
tools:ignore="HardcodedText" />
<item
android:id="@+id/nav_mail"
android:icon="@drawable/ic_email_black_24dp"
android:title="Email"
tools:ignore="HardcodedText" />
<item
android:id="@+id/nav_task"
android:icon="@drawable/ic_assignment_black_24dp"
android:title="Tasks"
tools:ignore="HardcodedText" />
group>
menu>
TestMaterialDesign.java
public class TestMaterialDesign extends DefaultActivity implements NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout mDrawerLayout;
private NavigationView mNavigationView;
private CircleImageView mCivPic;
@Override
public void initView() {
setContentView(R.layout.material_design_layout2);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mDrawerLayout = findViewById(R.id.drawer_layout);
mNavigationView = findViewById(R.id.navigationView);
//导入header_layout布局,获取CircleImageView,并设置点击事件
View headerView = mNavigationView.inflateHeaderView(R.layout.header_layout);
mCivPic = headerView.findViewById(R.id.civ_icon);
}
@Override
public void initClickListener() {
mCivPic.setOnClickListener(this);
mNavigationView.setNavigationItemSelectedListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//圆形图片控件点击事件
case R.id.civ_icon:
Toast.makeText(this, "点击可换图像", Toast.LENGTH_SHORT).show();
mDrawerLayout.closeDrawers();
break;
}
}
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_call:
Toast.makeText(this, item.getTitle(), Toast.LENGTH_SHORT).show();
break;
case R.id.nav_friends:
Toast.makeText(this, item.getTitle(), Toast.LENGTH_SHORT).show();
break;
case R.id.nav_location:
Toast.makeText(this, item.getTitle(), Toast.LENGTH_SHORT).show();
break;
case R.id.nav_mail:
Toast.makeText(this, item.getTitle(), Toast.LENGTH_SHORT).show();
break;
case R.id.nav_task:
Toast.makeText(this, item.getTitle(), Toast.LENGTH_SHORT).show();
break;
}
//这里简单处理一下,调用closeDrawers()方法关闭侧滑菜单
mDrawerLayout.closeDrawers();
return false;
}
}
这时一个简单的侧滑菜单已经完成,可是主页面却空空如也,那么接下来就给主页面添加一些东西吧!
修改布局material_design_layout.xml,仅仅增加RecyclerView控件
<android.support.v4.widget.DrawerLayout 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:id="@+id/drawer_layout"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_scrollFlags="scroll|snap|enterAlways"
app:popupTheme="@style/Theme.AppCompat.Light" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
FrameLayout>
适配器HeroAdapter
public class HeroAdapter extends RecyclerView.Adapter<HeroAdapter.HeroViewHolder> {
private Context mContext;
private List mHeroDatas;
private LayoutInflater mInflate;
private ICardViewOnClickListener listener;
public HeroAdapter(Context context, List herosList) {
mHeroDatas = new ArrayList<>();
mInflate = LayoutInflater.from(context);
this.mContext = context;
this.mHeroDatas = herosList;
}
@NonNull
@Override
public HeroViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mInflate.inflate(R.layout.recyclerview_heros_item, parent, false);
return new HeroViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final HeroViewHolder holder, int position) {
final int adapterPosition = holder.getAdapterPosition();
Heros heros = mHeroDatas.get(adapterPosition);
holder.tv_name.setText(heros.getName());
//Github开源库Glide
Glide.with(mContext).load(heros.getImageUrl()).into(holder.iv_icon);
holder.cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.onCardViewClick(adapterPosition);
}
});
}
@Override
public int getItemCount() {
return mHeroDatas.size();
}
static class HeroViewHolder extends RecyclerView.ViewHolder {
ImageView iv_icon;
TextView tv_name;
CardView cardView;
HeroViewHolder(View itemView) {
super(itemView);
iv_icon = itemView.findViewById(R.id.iv_showIcon);
tv_name = itemView.findViewById(R.id.tv_name);
cardView = itemView.findViewById(R.id.card_view);
}
}
public interface ICardViewOnClickListener {
void onCardViewClick(int position);
}
public void setCardViewClickListener(ICardViewOnClickListener listener) {
this.listener = listener;
}
}
实体类Hero
public class Heros {
private String mHeroName;
private int mHeroImage;
public Heros(String name, int imageUrl) {
this.mHeroName = name;
this.mHeroImage = imageUrl;
}
public String getName() {
return mHeroName;
}
public int getImageUrl() {
return mHeroImage;
}
}
RecyclerView的Item布局文件 recyclerview_heros_item.xml
<android.support.v7.widget.CardView 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:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:elevation="12dp"
app:cardCornerRadius="6dp"
tools:targetApi="lollipop">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical"
android:padding="5dp">
<ImageView
android:id="@+id/iv_showIcon"
android:layout_width="196dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:src="@mipmap/ali" />
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:padding="5dp"
android:text="阿狸"
android:textColor="@color/colorAccent"
android:textSize="16sp"
tools:ignore="HardcodedText" />
LinearLayout>
android.support.v7.widget.CardView>
修改TestMaterialDesign.java代码 上面代码不变仅展示新增代码
public class TestMaterialDesign extends DefaultActivity implements NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout mDrawerLayout;
private NavigationView mNavigationView;
private CircleImageView mCivPic;
private List mHerosList;
private RecyclerView mRecyclerView;
private HeroAdapter mAdapter;
private Heros[] mHeros =
{
new Heros("艾希", R.mipmap.aixi), new Heros("阿狸", R.mipmap.ali),
new Heros("伊泽瑞尔", R.mipmap.ez), new Heros("盖伦", R.mipmap.gailun),
new Heros("孙悟空", R.mipmap.houzi), new Heros("剑姬", R.mipmap.jianji),
new Heros("剑圣", R.mipmap.jiansheng), new Heros("机器人", R.mipmap.jiqiren),
new Heros("蛮子", R.mipmap.manzi), new Heros("诺克", R.mipmap.nuoke),
new Heros("女枪", R.mipmap.nvqiang), new Heros("琴女", R.mipmap.qinnv),
new Heros("瑞文", R.mipmap.ruiwen), new Heros("螳螂", R.mipmap.tanglang),
new Heros("提莫", R.mipmap.timo), new Heros("武器", R.mipmap.wuqi),
new Heros("小炮", R.mipmap.xiaopao), new Heros("瞎子", R.mipmap.xiazi),
new Heros("妖姬", R.mipmap.yaoji), new Heros("亚索", R.mipmap.yasuo)
};
@Override
public void initView() {
setContentView(R.layout.material_design_layout);
mHerosList = new ArrayList<>();
mRecyclerView = findViewById(R.id.recyclerview);
}
@Override
public void initDatas() {
Collections.addAll(mHerosList, mHeros);
mAdapter = new HeroAdapter(this, mHerosList);
mRecyclerView.setAdapter(mAdapter);
GridLayoutManager layoutManager = new GridLayoutManager(this, 2);
mRecyclerView.setLayoutManager(layoutManager);
}
到现在为止主页面的内容已经有了,可是看着总有一点别扭,到底是哪块别扭呢?发现RecyclerView的Item盖住了Toolbar,还是有点不美观!相信广大猿友也是忍受不了这个缺陷的存在,那么就来解决这个缺陷。很简单,Google为我们提供了解决办法,那就是只需将主布局文件中的FramLayout改写成CoordinatorLayout,再使用AppBarLayout包裹Toolbar,然后在RecyclerView中Toolbar中分别增加如下属性重新运行程序,是不是这个缺陷已经完美的解决了?这里就不上图了。
app:layout_behavior=”@string/appbar_scrolling_view_behavior”
app:layout_scrollFlags=”scroll|snap|enterAlways”
先写到这里,会很快补上之后的内容,文末会附上完整的Demo链接,如有不准确的地方,欢迎指正~~~
完整Demo地址