此為第一個製作側滑選單的實踐 。
此部分僅僅為部分實踐:
僅缺menu的字串佈局,以及需要修改的MainActivity.java檔案,也是需要主要修改的地方。
從使用MD設計-進行側滑選單的製作(activity_main.xml部分)仍然可看。
當中為了向前相容以及使用Material Design,參考了約10個連結。
檔案路徑、參考連結為文章末尾,為了更好的閱讀體驗,增加了檔案原始碼展示(部分程式碼有刪改)。
使用MD設計
設定向前相容
進行4.0系統的一些工作
參考連結-向前相容-1
首先準備新增MD設計包,但考慮到Android Icecream(4.0)僅為14,參考連結中得知Appcomat為21,所以先做以下調整:
- build.gradle:
android {
compileSdkVersion 21
defaultConfig {
applicationId "product.felixxiong.com.MyPackgeName"
minSdkVersion 14
targetSdkVersion 21
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
...
dependencies {
implementation fileTree(dir: `libs`, include: [`*.jar`])
implementation `com.android.support:appcompat-v7:21.0.+` //匯入Appcompat依賴5.0的21並隨時獲取可用新版本
implementation `com.android.support.v7.widget.SwichCompat`//匯入支援MD的switch控制元件
implementation `com.android.support:design.21` //匯入21設計庫:參考連結:
複製程式碼
values相關xml檔案
- 新建values/themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="AppTheme.Base"/>
<style name="AppTheme.Base" parent="Theme.AppCompat">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimary</item>
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
</style>
</resources>
複製程式碼
- 新建values-v21/themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="AppTheme.Base">
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
<item name="android:windowSharedElementExitTransition">@android:transition/move</item>
</style>
</resources>
複製程式碼
新增依賴
參考連結:向前相容
apply plugin: `com.android.application`
allprojects {
repositories {
google()
jcenter()
}
}
...
dependencies {
implementation fileTree(dir: `libs`, include: [`*.jar`])
implementation `com.android.support:appcompat-v7:21.0.+` //匯入Appcompat依賴5.0的21並隨時獲取可用新版本
implementation `com.android.support.v7.widget.SwichCompat`//匯入支援MD的switch控制元件
implementation `com.android.support:design.21` //匯入21設計庫
implementation `com.android.support.constraint:constraint-layout:1.1.2`
//implementation `com.google.android.material:material:1.0.0-rc01`
複製程式碼
使用Toolbar替換Action Bar
參考連結-向前相容-1
- active_main.xml:
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.AppCompat.NoActionBar" />
<!--參考連結:關於toolbar-4-->
<!--android:background="?attr/colorPrimaryDark"-->
android:background="#3F51B5"> <!--Toolbar可自定義顏色-->
</android.support.v7.widget.Toolbar>
複製程式碼
- MainActivity.java:
@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutResource());
//getLayoutResource()此處需要獲取佈局檔案R.layout.……
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); //主要關於Toolbar的程式碼
if(toolbar != null) {
setSupportActionBar(toolbar);
}
}
複製程式碼
進行側滑選單的製作
佈局檔案
導航欄佈局
activity_main.xml
- 設定material.navigation.NavigationView
參考連結:Material Design
<com.google.android.material.navigation.NavigationView
android:id="@+id/left_navigation_drawer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start" <!--layout_gravity指定重力-->
app:headerLayout="@layout/navigation_header" <!--設定navigation頭佈局-->
app:menu="@menu/my_navigation_items"> <!--設定navigation導航佈局-->
<!--android:dividerHeight="0dp"
android:background="#111"--/>
</com.google.android.material.navigation.NavigationView>
</android.support.v4.widget.DrawerLayout>
複製程式碼
設定佈局,在相應目錄下新建檔案:
layout
avigation_header.xml
menumy_navigation_items
android:dividerHeight="0dp"
複製程式碼
此處程式碼連結為開發者文件,MD可能不需要兩行程式碼。
- 新增Framelayout
此處連結為開發者文件。
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/decor_content_frame">
<!--主內容檢視必須為第一個檢視,抽屜式導航必須位於內容頂部-->
<android.support.v7.widget.Toolbar
... />
</FrameLayout>
複製程式碼
選單頭部佈局
navigation_header.xml
參考連結:側滑選單-1
<?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="match_parent"
android:background="?attr/colorPrimary"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="50dp"
android:paddingTop="50dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<com.google.android.material.internal.VisibilityAwareImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
<android.support.v7.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="demo"/>
</LinearLayout>
複製程式碼
選單項佈局
my_navigation_items
此處參考連結:側滑選單-1,因為開發者文件中使用Adpter方法實現填充,需要深入瞭解Adpter,故未加入。
JAVA檔案()
Main Activity.java
參考連結:側滑選單-1
- 初始化抽屜導航欄列表
public class MainActivity extends AppCompatActivity {
@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private Toolbar toolbar; //此處Toolbar修改為自己習慣的寫法,為變數
private String[] mTitles; //建立標題變數
private DrawerLayout mDrawerLayout; //建立抽屜檢視變數
private NavigationView mDrawerNavgation; //建立側滑選單檢視變數
//private ActionBarDrawerToggle mDrawerToggle; 在後文中出現
//建立Toobar的子類作為監聽器,需要在生命週期中呼叫togge
//private CharSequence mDrawerTitle;
//private CharSequence mTitle;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//mTitles = R.layout.activity_main.getStringArray(R.array.Titles_array); //初始化介面
//此處Toolbar修改為自己習慣的寫法,例項化Toolbar寫一起
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
onCreateOptionsMenu(R.layout.activity_main);
toolbar.setTitle("My Title");
setSupportActionBar(toolbar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerNavgation = (NavigationView) findViewById(R.id.left_navigation_drawer);
mDrawerNavgation.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_layout, mTitles)); //為列表檢視設定介面卡
mDrawerNavgation.setOnItemClickListener(new DrawerItemClickListener()); //呼叫接收點選事件,設定點選監聽器
}
...
}
}
複製程式碼
- 處理導航點選事件
private class DrawerItemClickListener implements NavigationView.OnItemClickListener { //開始處理導航事件:在使用者選擇某一項時實現介面更改內容檢視
@Override //這裡開始呼叫onItemClick
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
private void selectItem(int position) {
Fragment fragment = new Fragment(); //封裝一個新片段並指定要根據位置顯示的
Bundle args = new Bundle();
args.putInt(Fragment.ARG_LIST_NUMBER, position);
fragment.setArguments(args);
FragmentManager fragmentManager = getFragmentManager(); //通過替換任何現有片段插入片段
fragmentManager.beginTransaction()
//將不同的FrameLayout插入內容主檢視
.replace(R.id.decor_content_frame, fragment)
.commit();
// Highlight the selected item, update the title, and close the drawer
mDrawerNavgation.setItemChecked(position, true);
setTitle(mTitles[position]);
mDrawerLayout.closeDrawer(mDrawerNavgation);
}
@Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
複製程式碼
3.偵聽開啟和關閉事件
public class MainActivity extends AppCompatActivity {
private ActionBarDrawerToggle mDrawerToggle;
//建立Toobar的子類作為監聽器,需要在生命週期中呼叫togge
private CharSequence mDrawerTitle;
private CharSequence mTitle;
...
@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
...
mTitle = mDrawerTitle = getTitle();
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
getActionBar().setTitle(mTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle); //將抽屜切換設定為DrawerListener
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
}
/* Called whenever we call invalidateOptionsMenu() */
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
// If the nav drawer is open, hide action items related to the content view
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerNavgation);
menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
}
複製程式碼
- 通過應用圖示開啟和關閉
mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
//通過應用圖示開啟或關閉抽屜導航欄
mDrawerToggle = new ActionBarDrawerToggle(this,mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer icon to replace `Up` caret */
R.string.drawer_open, /* "open drawer" description */
R.string.drawer_close /* "close drawer" description */
) {
public void onDrawerClosed(View view) { //當抽屜處於完全關閉狀態時呼叫。
super.onDrawerClosed(view);
//getActionBar().setTitle(mTitle); //設定標題
}
public void onDrawerOpened(View drawerView) { //當抽屜處於完全狀態時呼叫。
super.onDrawerOpened(drawerView);
//getToolBar().setTitle(mDrawerTitle); //設定標題
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle); ////將抽屜切換設定為DrawerListener
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
//每當我們呼叫invalidateOptionsMenu()時呼叫
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerNavgation);
//如果導航抽屜已開啟,請隱藏與內容檢視相關的操作項
menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
}
@Override
protected void onPostCreate(Bundle savedInstanceState) { //在生命週期中呼叫ActionBarDrawerToggle
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState(); ////在onRestoreInstanceState發生後同步切換狀態。
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Pass the event to ActionBarDrawerToggle, if it returns
// true, then it has handled the app icon touch event
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle your other action bar items...
return super.onOptionsItemSelected(item);
}
複製程式碼
檔案全部程式碼
build.gradle
allprojects {
repositories {
google()
jcenter()
}
}
android {
compileSdkVersion 21
defaultConfig {
applicationId "product.penghaoxiong.com.androidquickcheck"
minSdkVersion 14
targetSdkVersion 21
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile(`proguard-android.txt`), `proguard-rules.pro`
}
}
}
dependencies {
implementation fileTree(dir: `libs`, include: [`*.jar`])
implementation `com.android.support:appcompat-v7:21.0.+` //匯入Appcompat依賴5.0的21並隨時獲取可用新版本
implementation `com.android.support.v7.widget.SwichCompat`//匯入支援MD的switch控制元件
implementation `com.android.support:design.21` //匯入21設計庫
implementation `com.android.support.constraint:constraint-layout:1.1.2`
//implementation `com.google.android.material:material:1.0.0-rc01`
testImplementation `junit:junit:4.12`
androidTestImplementation `com.android.support.test:runner:1.0.2`
androidTestImplementation `com.android.support.test.espresso:espresso-core:3.0.2`
}
複製程式碼
參考連結
關於向前相容
- AppCompat 21實現低版本手機使用Material Design
- 在低版本Android上使用Material Design——AppCompat v21
- 如何選擇 compileSdkVersion, minSdkVersion 和 targetSdkVersion
關於Toolbar
Material Design
側滑選單
路徑
-
build.gradle:appuild.gradle
-
MainActivity.java:appsrcmainjavaproductfelixxiongcomcheckMainActivityMainActivity.java
-
active_main.xml:appsrcmain
eslayoutactive_main.xml -
layout:
layout
avigation_header.xml -
values:appsrcmain
esvaluesvalues/themes.xml
values-v21/themes.xml