先说一下几个引用的库
dependencies {
compile "com.jakewharton:butterknife:$rootProject.butterKnifeVersion"
都知道绑定用的
compile "uk.co.chrisjenx:calligraphy:$rootProject.calligraphyVersion"
这个是导入一些字体 后面有方法
compile "com.android.support:design:$rootProject.supportLibraryVersion"这个就要引用的这个抽屉
}
项目的build
ext {
// Sdk and toolsbutterKnifeVersion = '8.5.1' calligraphyVersion = '2.2.0' supportLibraryVersion = '26.+'
}
先说一个坑的地方 版本号。
compile 'com.android.support:appcompat-v7:26.+'
buildToolsVersion "26.0.0" 这个属于要对应的
所以 你引用的supportLibraryVersion 的也要是26以上的 如果你不知道版本号 就用 '26.+' 很便捷
先来说第一步CalligraphyConfig 对这个不感兴趣的可以跳过
public class App extends Application {
CalligraphyConfig mCalligraphyConfig;@Override public void onCreate() { super.onCreate(); CalligraphyConfig.initDefault(new CalligraphyConfig.Builder() .setDefaultFontPath("fonts/source-sans-pro/SourceSansPro-Regular.ttf") .setFontAttrId(R.attr.fontPath) .build()); }
}
再学要的activity中加入
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}
自己下载好资源就可以
在你想要使用的时候
style="@style/TextStyle.Title.Sub" />
下面是在value文件夹下的style
这个就完成了 字体的调用
下面是 xml页面
activity_main
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
需要注意的地方是两个方面
整体结构两层 下面的这个就是你展开的部分
app:menu="@menu/drawer"
app:headerLayout="@layout/drawer_header" 这两个属性 来定义你展开的页面
drawer_header
android:layout_width="match_parent"
android:layout_height="250dp"
android:background="@drawable/bg_design"
android:orientation="vertical"
android:padding="16dp">
drawer
上面这个就是效果图
建立关系activity
public class MainActivity extends BaseActivity implements MainMvpView {@Inject MainMvpPresenter
mPresenter; @BindView(R.id.toolbar) Toolbar mToolbar; @BindView(R.id.drawer_view) DrawerLayout mDrawer; @BindView(R.id.navigation_view) NavigationView mNavigationView; @BindView(R.id.tv_app_version) TextView mAppVersionTextView; @BindView(R.id.cards_container) SwipePlaceHolderView mCardsContainerView; private TextView mNameTextView; private TextView mEmailTextView; private RoundedImageView mProfileImageView; private ActionBarDrawerToggle mDrawerToggle; public static Intent getStartIntent(Context context) { Intent intent = new Intent(context, MainActivity.class); return intent; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getActivityComponent().inject(this); setUnBinder(ButterKnife.bind(this)); mPresenter.onAttach(this); setUp(); } @Override public void onBackPressed() { FragmentManager fragmentManager = getSupportFragmentManager(); Fragment fragment = fragmentManager.findFragmentByTag(AboutFragment.TAG); if (fragment == null) { super.onBackPressed(); } else { onFragmentDetached(AboutFragment.TAG); } } @Override public void refreshQuestionnaire(List questionList) { for (Question question : questionList) { if (question != null && question.getOptionList() != null && question.getOptionList().size() == 3) { mCardsContainerView.addView(new QuestionCard(question)); } } } @Override public void reloadQuestionnaire(List questionList) { refreshQuestionnaire(questionList); ScaleAnimation animation = new ScaleAnimation( 1.15f, 1, 1.15f, 1, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); mCardsContainerView.setAnimation(animation); animation.setDuration(100); animation.start(); } @Override public void updateAppVersion() { String version = getString(R.string.version) + " " + BuildConfig.VERSION_NAME; mAppVersionTextView.setText(version); } @Override public void updateUserName(String currentUserName) { mNameTextView.setText(currentUserName); } @Override public void updateUserEmail(String currentUserEmail) { mEmailTextView.setText(currentUserEmail); } @Override public void updateUserProfilePic(String currentUserProfilePicUrl) { //load profile pic url into ANImageView } @Override protected void onResume() { super.onResume(); if (mDrawer != null) mDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); } @Override protected void onDestroy() { mPresenter.onDetach(); super.onDestroy(); } @Override public void onFragmentAttached() { } @Override public void onFragmentDetached(String tag) { FragmentManager fragmentManager = getSupportFragmentManager(); Fragment fragment = fragmentManager.findFragmentByTag(tag); if (fragment != null) { fragmentManager .beginTransaction() .disallowAddToBackStack() .setCustomAnimations(R.anim.slide_left, R.anim.slide_right) .remove(fragment) .commitNow(); unlockDrawer(); } } @Override public void showAboutFragment() { lockDrawer(); getSupportFragmentManager() .beginTransaction() .disallowAddToBackStack() .setCustomAnimations(R.anim.slide_left, R.anim.slide_right) .add(R.id.cl_root_view, AboutFragment.newInstance(), AboutFragment.TAG) .commit(); } @Override public void lockDrawer() { if (mDrawer != null) mDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); } @Override public void unlockDrawer() { if (mDrawer != null) mDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { Drawable drawable = item.getIcon(); if (drawable instanceof Animatable) { ((Animatable) drawable).start(); } switch (item.getItemId()) { case R.id.action_cut: return true; case R.id.action_copy: return true; case R.id.action_share: return true; case R.id.action_delete: return true; default: return super.onOptionsItemSelected(item); } } @Override protected void setUp() { setSupportActionBar(mToolbar);//设置toobar //创建一个和侧滑相关的效果 mDrawerToggle = new ActionBarDrawerToggle( this, mDrawer, mToolbar, R.string.open_drawer, R.string.close_drawer) { @Override public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); hideKeyboard(); } @Override public void onDrawerClosed(View drawerView) { super.onDrawerClosed(drawerView); } }; mDrawer.addDrawerListener(mDrawerToggle); mDrawerToggle.syncState(); //这个方法是 同步;表示actionbar 和ActionBarDrawerToggle HOME 同步 setupNavMenu(); //这个方法就是设计策划菜单的样式 mPresenter.onNavMenuCreated(); // 这个是更新样式的 setupCardContainerView(); mPresenter.onViewInitialized(); //初始化 显示初始化数据 } private void setupCardContainerView() { int screenWidth = ScreenUtils.getScreenWidth(this); int screenHeight = ScreenUtils.getScreenHeight(this); mCardsContainerView.getBuilder() .setDisplayViewCount(3) .setHeightSwipeDistFactor(10) .setWidthSwipeDistFactor(5) .setSwipeDecor(new SwipeDecor() .setViewWidth((int) (0.90 * screenWidth)) .setViewHeight((int) (0.75 * screenHeight)) .setPaddingTop(20) .setSwipeRotationAngle(10) .setRelativeScale(0.01f)); mCardsContainerView.addItemRemoveListener(new ItemRemovedListener() { @Override public void onItemRemoved(int count) { if (count == 0) { // reload the contents again after 1 sec delay new Handler(getMainLooper()).postDelayed(new Runnable() { @Override public void run() { mPresenter.onCardExhausted(); } }, 800); } } }); } void setupNavMenu() { View headerLayout = mNavigationView.getHeaderView(0); mProfileImageView = (RoundedImageView) headerLayout.findViewById(R.id.iv_profile_pic); mNameTextView = (TextView) headerLayout.findViewById(R.id.tv_name); mEmailTextView = (TextView) headerLayout.findViewById(R.id.tv_email); mNavigationView.setNavigationItemSelectedListener( new NavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { mDrawer.closeDrawer(GravityCompat.START); switch (item.getItemId()) { case R.id.nav_item_about: mPresenter.onDrawerOptionAboutClick(); return true; case R.id.nav_item_rate_us: mPresenter.onDrawerRateUsClick(); return true; case R.id.nav_item_feed: mPresenter.onDrawerMyFeedClick(); return true; case R.id.nav_item_logout: mPresenter.onDrawerOptionLogoutClick(); return true; default: return false; } } }); } @Override public void openLoginActivity() { startActivity(LoginActivity.getStartIntent(this)); finish(); } @Override public void showRateUsDialog() { RateUsDialog.newInstance().show(getSupportFragmentManager()); } @Override public void openMyFeedActivity() { startActivity(FeedActivity.getStartIntent(this)); } @Override public void closeNavigationDrawer() { if (mDrawer != null) { mDrawer.closeDrawer(Gravity.START); } } }
用toolbar的时候必须noactionbar 下面解释几个小属性
- @null
应用都是一开始就是显示背景图片 而没有白色背景 就是上面这个功劳
1.colorPrimary 应用的主要色调,actionBar默认使用该颜色,Toolbar导航栏的底色
2.colorPrimaryDark 应用的主要暗色调,statusBarColor默认使用该颜色
3.statusBarColor 状态栏颜色,默认使用colorPrimaryDark
4.windowBackground 窗口背景颜色
5.navigationBarColor 底部栏颜色
6.colorForeground 应用的前景色,ListView的分割线,switch滑动区默认使用该颜色
7.colorBackground 应用的背景色,popMenu的背景默认使用该颜色
8.colorAccent CheckBox,RadioButton,SwitchCompat等一般控件的选中效果默认采用该颜色
9.colorControlNormal CheckBox,RadioButton,SwitchCompat等默认状态的颜色。
10.colorControlHighlight 控件按压时的色调
11.colorControlActivated 控件选中时的颜色,默认使用colorAccent
12.colorButtonNormal 默认按钮的背景颜色
13.editTextColor:默认EditView输入框字体的颜色。
14.textColor Button,textView的文字颜色
15.textColorPrimaryDisableOnly RadioButton checkbox等控件的文字
16.textColorPrimary 应用的主要文字颜色,actionBar的标题文字默认使用该颜色
17.colorSwitchThumbNormal: switch thumbs 默认状态的颜色. (switch off)
这样是不是更清晰理解了这些Color的作用,更多分享敬请下回分析。
主要的几点
NavigationView.setItemIconTintList(null);//设置菜单图标恢复本来的颜色 你图片有系统默认的时候
借鉴一下 别人的图
NavigationView 基本已经规定设置好了大小距离,留给我们可以改动的空间并不多。如果你想调整一下菜单的布局宽高之类的,基本是不可能的了(即使可能,也估计非常蛋疼)。所以,目前我基本还没见过国内哪个 app 是直接使用了 NavigationView 来做导航(如果有的话,欢迎告知一下)。
这一段是 是引用 这个 兄弟的 一段话。
链接:http://www.jianshu.com/p/c8cbeb7ea43a
这之后 引出了新的一个控件。 就是当你对这个布局有很大要求 并且 还要求 有这种泡沫显示未读数的时候
MaterialDrawer 我们来看看这个控件
前面提到 NavigationView 的不实用性,如果你真的要实现 NavigationView那样的效果,又渴望比较高的自由度。这个功能强大且自由度很高的开源库 MaterialDrawer 应该是个很不错的选择。
MaterialDrawer 效果图二
gitup地址
https://github.com/mikepenz/MaterialDrawer
new DrawerBuilder().withActivity(this).build(); 这个就是流程性的东西 告诉你这个方法就是构建了 一个侧滑。
下面我们开点干货 开始构建 我们的策划
首先 我们要声明
private AccountHeader headerResult = null;
private Drawer result = null;
Drawer 这个你可以理解这个是策划的主类 你建任何东西都是在上面添加
result = new DrawerBuilder()
.withActivity(this)
.withToolbar(toolbar)
.withHasStableIds(true)
.withItemAnimator(new AlphaInAnimator())
.withAccountHeader(headerResult)
headerResult 这个就是添加的头部
headerResult = new AccountHeaderBuilder()
.withActivity(this)
.withTranslucentStatusBar(true)
.withHeaderBackground(R.drawable.header)
这个就是被动图片
.addProfiles(
profile,
profile2,
profile3,
profile4,
profile5,
profile6,
//don't ask but google uses 14dp for the add account icon in gmail but 20dp for the normal icons (like manage account)
new ProfileSettingDrawerItem().withName("Add Account").withDescription("Add new GitHub Account").withIcon(new IconicsDrawable(this, GoogleMaterial.Icon.gmd_plus).actionBar().paddingDp(5).colorRes(R.color.material_drawer_primary_text)).withIdentifier(PROFILE_SETTING),
new ProfileSettingDrawerItem().withName("Manage Account").withIcon(GoogleMaterial.Icon.gmd_settings).withIdentifier(100001)
)
.withOnAccountHeaderListener(new AccountHeader.OnAccountHeaderListener() {
@Override
public boolean onProfileChanged(View view, IProfile profile, boolean current) {
//sample usage of the onProfileChanged listener
//if the clicked item has the identifier 1 add a new profile ;)
if (profile instanceof IDrawerItem && profile.getIdentifier() == PROFILE_SETTING) {
int count = 100 + headerResult.getProfiles().size() + 1;
IProfile newProfile = new ProfileDrawerItem().withNameShown(true).withName("Batman" + count).withEmail("batman" + count + "@gmail.com").withIcon(R.drawable.profile5).withIdentifier(count);
if (headerResult.getProfiles() != null) {
//we know that there are 2 setting elements. set the new profile above them ;)
headerResult.addProfile(newProfile, headerResult.getProfiles().size() - 2);
} else {
headerResult.addProfiles(newProfile);
}
}//false if you have not consumed the event and it should close the drawer return false; } }) .withSavedInstance(savedInstanceState) .build();
final IProfile profile = new ProfileDrawerItem().withName("Mike Penz").withEmail("[email protected]").withIcon("https://avatars3.githubusercontent.com/u/1476232?v=3&s=460").withIdentifier(100);
final IProfile profile2 = new ProfileDrawerItem().withName("Demo User").withEmail("[email protected]").withIcon("https://avatars2.githubusercontent.com/u/3597376?v=3&s=460").withIdentifier(101);
final IProfile profile3 = new ProfileDrawerItem().withName("Max Muster").withEmail("[email protected]").withIcon(R.drawable.profile2).withIdentifier(102);
final IProfile profile4 = new ProfileDrawerItem().withName("Felix House").withEmail("[email protected]").withIcon(R.drawable.profile3).withIdentifier(103);
final IProfile profile5 = new ProfileDrawerItem().withName("Mr. X").withEmail("[email protected]").withIcon(R.drawable.profile4).withIdentifier(104);
final IProfile profile6 = new ProfileDrawerItem().withName("Batman").withEmail("[email protected]").withIcon(R.drawable.profile5).withIdentifier(105);
上面的就是
点击
的
下面的怎么实现的呢
就是下面的代码部分
new ProfileSettingDrawerItem().withName("Add Account").withDescription("Add new GitHub Account").withIcon(new IconicsDrawable(this, GoogleMaterial.Icon.gmd_plus).actionBar().paddingDp(5).colorRes(R.color.material_drawer_primary_text)).withIdentifier(PROFILE_SETTING),
new ProfileSettingDrawerItem().withName("Manage Account").withIcon(GoogleMaterial.Icon.gmd_settings).withIdentifier(100001)
下面我们来分析一下上面的点击事件、
.withOnAccountHeaderListener(new AccountHeader.OnAccountHeaderListener() {
@Override
public boolean onProfileChanged(View view, IProfile profile, boolean current) {
//sample usage of the onProfileChanged listener
//if the clicked item has the identifier 1 add a new profile ;)
if (profile instanceof IDrawerItem && profile.getIdentifier() == PROFILE_SETTING) {
设置点击时间在这里设置 跳转的位置
}
好了下面开始分析
这三部分怎么去实现
result = new DrawerBuilder()
.withActivity(this)
.withToolbar(toolbar)
.withHasStableIds(true)
.withItemAnimator(new AlphaInAnimator())
.withAccountHeader(headerResult) //set the AccountHeader we created earlier for the header
.addDrawerItems(
new PrimaryDrawerItem().withName(R.string.drawer_item_compact_header).withDescription(R.string.drawer_item_compact_header_desc).withIcon(GoogleMaterial.Icon.gmd_sun).withIdentifier(1).withSelectable(false),
这是第一部分也是最常用的部分new SecondaryDrawerItem().withName(R.string.drawer_item_open_source).withIcon(FontAwesome.Icon.faw_github).withIdentifier(20).withSelectable(false),
这是第二部分 和第一部分比就是少了第二行
new ExpandableBadgeDrawerItem().withName("Collapsable Badge").withIcon(GoogleMaterial.Icon.gmd_collection_case_play).withIdentifier(18).withSelectable(false).withBadgeStyle(new BadgeStyle().withTextColor(Color.WHITE).withColorRes(R.color.md_red_700)).withBadge("100").withSubItems(
new SecondaryDrawerItem().withName("CollapsableItem").withLevel(2).withIcon(GoogleMaterial.Icon.gmd_8tracks).withIdentifier(2000),
new SecondaryDrawerItem().withName("CollapsableItem 2").withLevel(2).withIcon(GoogleMaterial.Icon.gmd_8tracks).withIdentifier(2001)
),上面是展开部分 可以展开
new SwitchDrawerItem().withName("Switch").withIcon(Octicons.Icon.oct_tools).withChecked(true).withOnCheckedChangeListener(null),new SecondarySwitchDrawerItem().withName("Secondary switch").withIcon(Octicons.Icon.oct_tools).withChecked(true).withOnCheckedChangeListener(null),
这是 剩下的两种方式
剩下的是重点了哦
我怎么吧这些分开呢
new DividerDrawerItem(), 这句话就是加上横线
好吧 到了下面的点击事件了
.withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
@Override
public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
//check if the drawerItem is set.
//there are different reasons for the drawerItem to be null
//--> click on the header
//--> click on the footer
//those items don't contain a drawerItemif (drawerItem != null) { Intent intent = null; if (drawerItem.getIdentifier() == 1) { intent = new Intent(DrawerActivity.this, CompactHeaderDrawerActivity.class); } else if (drawerItem.getIdentifier() == 2) { intent = new Intent(DrawerActivity.this, ActionBarActivity.class); } else if (drawerItem.getIdentifier() == 3) { intent = new Intent(DrawerActivity.this, MultiDrawerActivity.class); } else if (drawerItem.getIdentifier() == 4) { intent = new Intent(DrawerActivity.this, NonTranslucentDrawerActivity.class); } else if (drawerItem.getIdentifier() == 5) { intent = new Intent(DrawerActivity.this, AdvancedActivity.class); } else if (drawerItem.getIdentifier() == 7) { intent = new Intent(DrawerActivity.this, EmbeddedDrawerActivity.class); } else if (drawerItem.getIdentifier() == 8) { intent = new Intent(DrawerActivity.this, FullscreenDrawerActivity.class); } else if (drawerItem.getIdentifier() == 9) { intent = new Intent(DrawerActivity.this, CustomContainerActivity.class); } else if (drawerItem.getIdentifier() == 10) { intent = new Intent(DrawerActivity.this, MenuDrawerActivity.class); } else if (drawerItem.getIdentifier() == 11) { intent = new Intent(DrawerActivity.this, MiniDrawerActivity.class); } else if (drawerItem.getIdentifier() == 12) { intent = new Intent(DrawerActivity.this, FragmentActivity.class); } else if (drawerItem.getIdentifier() == 13) { intent = new Intent(DrawerActivity.this, CollapsingToolbarActivity.class); } else if (drawerItem.getIdentifier() == 14) { intent = new Intent(DrawerActivity.this, PersistentDrawerActivity.class); } else if (drawerItem.getIdentifier() == 15) { intent = new Intent(DrawerActivity.this, CrossfadeDrawerLayoutActvitiy.class); } else if (drawerItem.getIdentifier() == 20) { intent = new LibsBuilder() .withFields(R.string.class.getFields()) .withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR) .intent(DrawerActivity.this); } if (intent != null) { DrawerActivity.this.startActivity(intent); } } return false; } }) .withSavedInstance(savedInstanceState) .withShowDrawerOnFirstLaunch(true)
// .withShowDrawerUntilDraggedOpened(true)
.build();
相信大家可以看出来了 根据(drawerItem.getIdentifier() 来区别 你点击那个item
说说几个精髓的方法。 当你们有需求的时候会很管用
<pre>
result.setSelection(21, false);
//set the active profile
headerResult.setActiveProfile(profile3);
}
result.updateBadge(4, new StringHolder(100 + ""));
上面是设置默认的方法。下面的未读数据
这就是最后一个方法的红色部分
</pre>
另外加上一个方法 回退按钮的是关闭侧滑
@Override
public void onBackPressed() {
//handle the back press :D close the drawer first and if the drawer is closed close the activity
if (result != null && result.isDrawerOpen()) {
result.closeDrawer();
} else {
super.onBackPressed();
}
}
小小各种方式介绍
new PrimaryDrawerItem().withName(R.string.drawer_item_home).withIcon(FontAwesome.Icon.faw_home).withIdentifier(1),
new PrimaryDrawerItem().withName(R.string.drawer_item_free_play).withIcon(FontAwesome.Icon.faw_gamepad),
new PrimaryDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye).withIdentifier(5),
new SectionDrawerItem().withName(R.string.drawer_item_section_header),
这句话也是有加入横线的效果
new SecondaryDrawerItem().withName(R.string.drawer_item_settings).withIcon(FontAwesome.Icon.faw_cog).withEnabled(false),
new SecondaryDrawerItem().withName(R.string.drawer_item_help).withIcon(FontAwesome.Icon.faw_question).withEnabled(false),
new SecondaryDrawerItem().withName(R.string.drawer_item_open_source).withIcon(FontAwesome.Icon.faw_github),
new SecondaryDrawerItem().withName(R.string.drawer_item_contact).withIcon(FontAwesome.Icon.faw_bullhorn)