本文转自:https://github.com/mutsinghua/androidLClass#material-design-实现之主题使用theme
Material Design 是Google在Android L推出来的一套新的设计规范, 有着鲜明的色彩,极致的用户体验,酷炫的动画。
本系例将带给大家一套完整的Material实现方案。 预计本系例将覆盖以下几个主题:
这是本系例的第一篇,主题的使用。
在Android 5.0中,新引入了以Material为关键字的主题。
@android:style/Theme.Material
@android:style/Theme.Material.Light
@android:style/Theme.Material.Light.DarkActionBar
使用方式都是在styles.xml的定义中,
但注意,这个定义不能放在values中,只能放在values-v21中。因为低版本的机型不识别这个主题。
因此,为了兼容低于androidL的机型,通常的做法,需要在values中,添加一个中间主题CustomCompactTheme。
对于values-21(高于5.0的版本), CustomCompactTheme可继承android.Theme.Material,
对于values(低于5.0的版本),CustomCompactTheme可继承Holo。
完整代码如下: values-v21/styles.xml
values/styles.xml
幸运的是在android-support-v7包(21版以上)已经为我们实现了兼容方案,只要引入相关的主题即可。
加入v7包,在gradle.build文件的dependencies节点中加入
compile 'com.android.support:appcompat-v7:23.0.0'
则styles.xml可以精简为
在theme中,我们可以为系统界面自定义一些配色,见下图。
这些配色,可以在主题中进行设置如
- #675634
- #993309
- #7767ff
- #ffff33
- #44ef54
效果图:
同样,在代码设置如下方式
getWindow().setStatusBarColor(0xff873434);
getWindow().setNavigationBarColor(0xff345644);
效果图
通常情况下,主题只能应用到全局,粒度最低只能到Activity这一层次, 那如果说只想把界面中的某一个布局使用主题,怎么办?这在以前是行不通的,但现在新引入Overlay系列主题就能使用到某一个ViewGroup上面,如:
这样LinearLayout所有的子元素都将继承ThemeOverlay.AppCompat.Dark的风格。
为了与保持整个应用程序的统一,有时我们需要使用系统预定义的值,比如不同的主题下,ActionBar的高度或不一样,则为了兼容各种主题,则我们在代码中不需要把高度写死,应该使用引用的方式的设置高度,如
如上所示,同样的,在必要的时候,我们也需要引用主题的颜色,这样当换一个主题的时候,UI的颜色就随着变改,增强代码的灵活性。
源码下载: https://github.com/mutsinghua/androidLClass
在Android5.0中,Google推出了更加灵活的Toolbar来取代ActionBar。Toolbar的优点是更加灵活,比如以前一个界面只能设置一个ActionBAR,但可以有多个Toolbar。而Toolbar同样可以设置菜单,颜色图标等,可以自定义的元素比ActionBAR多。因此,在Android应用程序中使用toolbar是一种趋势。
为了提高程序的兼容性,我们通常都使用V7包中的Toolbar(当然如果你的应用只需要在Android5.0上运行,则可以直接使用android.widget.Toolbar),要在程序中使用toolbar,则需要在gradle脚本中加上依赖项:
compile 'com.android.support:appcompat-v7:23.0.0'
如果是使用eclipse开发,则需要加入appcompat的库工程。
使用Toolbar的注意事项, 1. 由于Actionbar和Toolbar本身是有冲突的,因此,如果使用了Toolbar,则需要使用不带Actionbar的主题 如:Theme.AppCompat.NoActionBar。 2. 由于使用的v7中的toolbar,因此,activity的基类也需要是v7中的AppCompatActivity。 3. 由于使用了AppCompatActivity对应的主题也需要是v7中的Theme.AppCompat.Light.NoActionBar
先看简单的效果图.
布局文件:
MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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);
}
}
这里要介绍的是setSupportActionBar(对应Activity的setActionBar)这个方法,它是在AppCompatActivity 中的,我们需要调用它,把布局中的Toolbar设置为actionbar。
如此简单的,就完成了一个toolbar的实现。如果你需要对Toolbar进行自定义,比如修改背景色,只需要在对应的属性上修改就好,如
android:background="?attr/colorPrimary"
当然,目前的实现仅仅是框架的一部分。我们继续添加常见的侧滑菜单,即android.support.v4.widget.DrawerLayout。
Drawerlayout包括两个子元素,第一个是主界面,即正常显示的界面,第二元素是侧滑菜单的布局。 我们要实现的界面如下,当菜单展开: 当菜单关闭
我们的布局文件如下:
对于主界面
public class MaterialActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
mDrawerToggle =
new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.open, R.string.close) {
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
}
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerToggle.syncState();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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);
}
}
这里除了DrawerLayout, 还引入了ActionBarDrawerToggle,它其实是一个DrawerListener,映应菜单展开和关闭的事件,还有一点,它实现了菜单图标的动画过渡。有兴趣的同学可以看看它的源码,这个动画图标主要是v7包中的DrawerArrowDrawable这个类来实现的。
一个通用的框架到这里理论就差不多了。但这里在深入扩展下,对于测滑菜单,除了自已实现之外,可以使用google为我们提供的Desgin包中的控件NavigationView,使用方法非常简单,如下:
app:menu中写入你自定义的菜单项,在headerLayout定义你的菜单头部,通常侧滑菜单看起来像
详细使用方法可以参考: http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0608/3011.html
本文中的源码可在github上下载: https://github.com/mutsinghua/androidLClass