Android带侧滑菜单和ToolBar的BaseActivity
写Android的时候,可能有多个界面。在风格统一的软件中,写Activity时会有很多重复。例如我所在软工课程小组的项目:Github链接 ,里面的TaskListActivity和TeacherListActivity就在Navigation的处理上有重复。还有一个双击退出APP的方法onBackPressed()
也重复实现了。之前让负责界面的同学把这些代码放到一个BaseActivity里面,让其他Activity继承它。他说不好做,他尝试过,但失败了。
于是这次我独自做 英语词典APP 的时候 ,经过在Google上的一番搜索和实践探索,写出一个还可以的BaseActivity。现在做个记录,以后还会用得到。
BaseActivity项目的Github链接
这个BaseActivity包括侧滑菜单(Navigation Drawer)和工具栏(Tool Bar)。
先看最终效果:
一、Navigation Drawer
由于Navigation Drawer涉及到BaseActivity的主要布局,所以先说明。
Activity的布局文件
先看Android官方Navigation Drawer说明:Creating a Navigation Drawer
根据说明,将layout/activity_base.xml
设置为以下内容:<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 主内容布局 -->
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!-- 侧滑菜单 -->
<ListView
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#111"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"/>
</android.support.v4.widget.DrawerLayout>
Android Studio不会提示android:layout_gravity这一项,但是整行敲完之后,可以正常运行。
侧滑菜单列表布局
这里只做简单的布局,所以侧滑菜单项都是TextView。
创建layout/list_item_drawer.xml
:<?xml version="1.0" encoding="utf-8"?> <TextView
android:id="@+id/tv_na_draw"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30sp"
android:textColor="#fff"/>
因为等会儿要用ArrayAdapter,所以这里最外层一定要是TextView。
侧滑菜单项的文本
StringArray
创建values/string_array_test.xml
:<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="planets_array">
<item>主界面</item>
<item>关于</item>
<item>设置</item>
<item>退出</item>
</string-array>
</resources>
Activity初始化
Initialize the Drawer List
这里由于要将Activity做成BaseActivity,所以和官方文档上的代码不太一样。public class BaseActivity extends AppCompatActivity {
protected String[] planetTitles;
protected DrawerLayout drawerLayout;
protected ListView drawerList;
protected FrameLayout frameLayout; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
} /**
* 重写setContentView,以便于在保留侧滑菜单的同时,让子Activity根据需要加载不同的界面布局
*/
@Override
public void setContentView(@LayoutRes int layoutResID) {
drawerLayout = (DrawerLayout) getLayoutInflater().inflate(R.layout.activity_base, null);
frameLayout = (FrameLayout) drawerLayout.findViewById(R.id.content_frame);
// 将传入的layout加载到activity_base的content_frame里面
getLayoutInflater().inflate(layoutResID, frameLayout, true);
super.setContentView(drawerLayout); setUpNavigation();
} private void setUpNavigation() {
planetTitles = getResources().getStringArray(R.array.planets_array);
drawerList = (ListView) findViewById(R.id.left_drawer);
drawerList.setAdapter(new ArrayAdapter<>(BaseActivity.this,
R.layout.list_item_drawer, planetTitles));
}
}
MainActivity
先创建个Activity查看效果。
创建MainActivity继承BaseActivity :public class MainActivity extends BaseActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
layout_main用的是默认布局。
在启动前要更改AndroidManifest.xml
,将MainActivity设置成Launcher:<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
启动后,手指从最左往右划,打开侧滑菜单。
添加侧滑菜单点击事件
Handle Navigation Click Events
先创建ClickListener,这里简单地设置点击后显示所点击的文本。
在BaseActivity中添加:private class DrawerItemClickListener implements ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
} private void selectItem(int position) {
Toast.makeText(BaseActivity.this, planetTitles[position], Toast.LENGTH_SHORT).show();
}
在BaseActivity的
setUpNavigation()
中添加:drawerList.setOnItemClickListener(new DrawerItemClickListener());
二、ToolBar
ToolBar 布局
ToolBar的各个成分:
Setting Up the App Bar
打开AndroidManifest.xml,将里面的android:theme="@style/AppTheme"
替换成android:theme="@style/Theme.AppCompat.Light.NoActionBar"
,如下:<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
...(三点表示省略,下同)
创建
layout/toolbar.xml
:<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"> <android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/> </merge>
ToolBar 初始化
在BaseActivity里添加:public class BaseActivity extends AppCompatActivity {
...
private Toolbar toolbar; ...
private void setUpToolBar() {
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
}
在BaseActivity的
setContentView()
里的setUpNavigation();
下面添加setUpToolBar();
,如下:@Override
public void setContentView(@LayoutRes int layoutResID) {
...
setUpNavigation();
setUpToolBar();
}
如果想要在MainActivity里显示ToolBar,还需要在
activity_main.xml
里include一个ToolBar的布局:<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout ...> <include layout="@layout/toolbar"/> </RelativeLayout>
显示的效果如下:
加入侧滑菜单打开键
到 Material Design Icons 下载图标。搜索menu,下载PNG版本。
解压后,将ic_menu_black_24dp/android
文件夹下面的所有文件夹复制到res/
里面。
在BaseActivity的setUpToolBar()
中添加:toolbar.setNavigationIcon(R.drawable.ic_menu_black_24dp);
虽然有图标,但是还没设置点击事件,所以点击的时候没有任何反应。点击ToolBar的home按钮打开Navigation Drawer
在BaseActivity里添加:@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
drawerLayout.openDrawer(GravityCompat.START);
return true;
default:
break;
}
return super.onOptionsItemSelected(item);
}
这里就省略ActionBarDrawerToggle的部分了,影响不是特别大。实际应用中再去添加。
添加Option Menu
在values/strings.xml
里添加等会儿会用到的字符串:<resources>
...
<string name="edit">编辑</string>
<string name="search">搜索</string>
<string name="change_history">变更记录</string>
</resources>
去 Material Design Icons 下载相关图标。
创建res/menu/menu_main.xml
:<?xml version="1.0" encoding="utf-8"?>
<menu android:id="@+id/expanded_menu"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> <item
android:id="@+id/menu_edit"
android:icon="@drawable/ic_mode_edit_black_24dp"
android:title="@string/edit"
app:showAsAction="ifRoom"/> <item
android:id="@+id/menu_search"
android:icon="@drawable/ic_search_black_24dp"
android:title="@string/search"
app:showAsAction="ifRoom"/> <item
android:id="@+id/menu_change_history"
android:icon="@drawable/ic_change_history_black_24dp"
android:title="@string/change_history"
app:showAsAction="never"/> </menu>
其中ifRoom表示如果ToolBar空间足够,则将其图标显示在ToolBar上面。never表示永不显示在ToolBar上面,只有当点击option menu按钮的时候,才会出现。
在BaseActivity中添加:@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
super.onCreateOptionsMenu(menu);
return true;
}
启动APP:
点击menu按钮后:
Option Menu的点击事件
在BaseActivity里的onOptionsItemSelected()
增加case即可。隐藏ActionBar的Option Menu
有时候不想在某个Activity中显示Option Menu,于是修改BaseActivity:public class BaseActivity extends AppCompatActivity {
...
private boolean showOptionMenu = true; ...
protected void hideOptionMenu() {
showOptionMenu = false;
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
if (showOptionMenu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
}
super.onCreateOptionsMenu(menu);
return true;
} }
三、参考链接
ToolBar
https://developer.android.com/training/appbar/setting-up.html
https://developer.android.com/training/appbar/actions.html
http://stackoverflow.com/questions/32367041/calling-toolbar-on-each-activity
http://stackoverflow.com/questions/30824324/clicking-hamburger-icon-on-toolbar-does-not-open-navigation-drawer
http://stackoverflow.com/questions/19724567/how-to-add-menu-indicator-next-to-action-bars-app-icon
http://stackoverflow.com/questions/26582075/cannot-catch-toolbar-home-button-click-eventNavigation Drawer
https://developer.android.com/training/implementing-navigation/nav-drawer.html
http://stackoverflow.com/questions/33009469/baseactivity-for-navigation
http://stackoverflow.com/questions/22652556/creating-base-activity-with-navigation-drawer-in-androidArrayAdapter
http://stackoverflow.com/questions/9280965/arrayadapter-requires-the-resource-id-to-be-a-textview-xml-problems
http://stackoverflow.com/questions/29591546/unable-to-use-layout-gravity-for-listview-inside-drawerlayoutString Array
https://developer.android.com/guide/topics/resources/string-resource.html#StringArrayMaterial icons
https://design.google.com/icons/
Android带侧滑菜单和ToolBar的BaseActivity的更多相关文章
- Android SlidingMenu侧滑菜单使用
把下载的侧滑菜单压缩包打开,会有一个library文件夹,在eclipse中import existing android code into workspace,导入library文件夹,并且选择作 ...
- no drawer view found with gravity RIGHT(Android实现侧滑菜单从右面滑出) 解决办法
代码如下: <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width ...
- 【转】android官方侧滑菜单DrawerLayout详解
原文网址:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0925/1713.html drawerLayout是Support ...
- android官方侧滑菜单DrawerLayout详解
drawerLayout是Support Library包中实现了侧滑菜单效果的控件,可以说drawerLayout是因为第三方控件如MenuDrawer等的出现之后,google借鉴而出现的产物.d ...
- Android之侧滑菜单DrawerLayout的使用
在android support.v4 中有一个抽屉视图控件DrawerLayout.使用这个控件,可以生成通过在屏幕上水平滑动打开或者关闭菜单,能给用户一个不错的体验效果. DrawerLayout ...
- Android DrawerLayout侧滑菜单
本教程已经录制视频,欢迎大家观看我在CSDN学院录制的课程:http://edu.csdn.net/lecturer/944
- Android组件——使用DrawerLayout仿网易新闻v4.4侧滑菜单
摘要: 转载请注明出处:http://blog.csdn.net/allen315410/article/details/42914501 概述 今天这篇博客将记录一些关于DrawerL ...
- Android-自定义侧滑菜单
效果图: 需要继承ViewGroup,因为包含了子控件,菜单子控件 与 主页面子控件 Activity Xml布局相关: <!-- 自定义侧滑菜单 SlideMenu --> <Li ...
- android 应用架构随笔五(ActionBar与侧滑菜单DrawerLayout)
ActionBar(V7)的添加非常简单,只需要在AndroidManifest.xml中指定Application或Activity的theme是Theme.Holo或其子类就可以了,在Androi ...
随机推荐
- Node.js 究竟是什么?
Node.js 究竟是什么? 一个 "编码就绪" 服务器 Node 是一个服务器端 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸 ...
- 基于ZigBee的家居控制系统的设计与应用
基于ZigBee的家居控制系统的设计与应用 PPT简介:http://pan.baidu.com/s/1i38PC6D 摘 要 智能家居是未来家居的发展方向,其利用先进的网络技术.计算机技术和无线通 ...
- Codeforces Round #248 (Div. 2) C. Ryouko's Memory Note
题目链接:http://codeforces.com/contest/433/problem/C 思路:可以想到,要把某一个数字变成他的相邻中的数字的其中一个,这样总和才会减少,于是我们可以把每个数的 ...
- LoadRunner录制图片验证码
LoadRunner录制图片验证码 LoadRunner自身是无法捕获到图片验证码的,但是我们可以帮助LoadRunner来实现验证码的捕获. 1.图片验证码 图片验证码的产生来自服务器端,由服务器生 ...
- ubuntu安装中文支持
sudo apt-get install language-pack-zh-hant language-pack-zh-hans
- jQuery事件和JavaScript事件
1.JavaScript事件: 属性 当以下情况发生时,出现此事件 FF N IE onabort 图像加载被中断 1 3 4 onblur 元素失去焦点 1 2 3 onchange 用户改变域的内 ...
- AOP静态代理解析1-标签解析
AOP静态代理使用示例见Spring的LoadTimeWeaver(代码织入) Instrumentation使用示例见java.lang.instrument使用 AOP的静态代理主要是在虚拟机启动 ...
- Spring的Lifecycle
Lifecycle接口定义了每个对象的重要方法,每个对象都有自己的生命周期需求,如下: public interface Lifecycle { void start(); void stop(); ...
- js小例子(多字溢出,省略号表示)
实现了div中字数较多,显示不下的时候,用省略号来表示,并且可以展开和收起: <html> <head> <meta http-equiv="Content-T ...
- 解决:未能加载文件或程序集“EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”
使用nuget管理程序包,有可能在不同时间安装不同版本的Entity Framework:在项目创建初期安装的是6.0.0.0版本,后来添加的类库,安装了6.1.1版本,所以出现这个问题. 解决办法: ...