UI设计—Material Design实战(2)之滑动菜单
上一节:UI设计—Material Design实战之Toolbar
https://blog.csdn.net/qq_43468891/article/details/90582267
DrawerLayout
本节效果:
滑动菜单可以说是Material Design中最经常见到的效果之一了,许多应用中都有滑动菜单的功能。谷歌提供了DrawerLayout控件就可以实现滑动菜单的功能。DrawerLayout的用法,首先它是一个布局,在布局中允许放入两个直接子控件,第一个控件是主屏幕中显示的内容,第二个子控件是滑动菜单中显示的内容。因此对activity_main.xml中的代码进行修改(在第一节UI设计—Material Design实战(1)之Toolbar中的代码进行修改):
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<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="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
</FrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:text="This is menu"
android:textSize="30sp"
android:background="#FFF"/>
</android.support.v4.widget.DrawerLayout>
这里最外层的控件使用了DrawerLayout,这个控件是由support-v4库提供的。第二个子控件需要注意,android:layout_gravity这个属性是必须指定的,,因为我们要告诉DrawerLayou滑动菜单是在屏幕的左边还是右边,left是左边,right是右边,start表示根据系统语言进行判断。
Material Design建议是在Toolbar的最左边加入一个导航按钮点击了按钮也会将滑动菜单的按钮展示出来。
在MainActivity中的代码,首先要添加一张导航按钮图标
package com.example.materialtext;
import android.os.Bundle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
/**
* @author J.Min
*/
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mDrawerLayout=findViewById(R.id.drawer_layout);
ActionBar actionBar = getSupportActionBar();
if(actionBar !=null){
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.toolbar,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
switch (item.getItemId()) {
case android.R.id.home:
mDrawerLayout.openDrawer(GravityCompat.START);
break;
case R.id.backup:
Toast.makeText(this, "You clicked Backup", Toast.LENGTH_LONG).show();
case R.id.delete:
Toast.makeText(this, "You clicked Delete", Toast.LENGTH_LONG).show();
case R.id.settings:
Toast.makeText(this, "You clicked Settings", Toast.LENGTH_LONG).show();
break;
default:
}
return true;
}
}
这里首先调用了findViewById()方法得到了DrawerLayout的是例,然后调用了getSupprtAtionBar()方法得到了ActionBar的实例。接着调用ActionBar的setDisplayHomeAsUpEnabled()方法让导航按钮显示出来,又调用了setHomeAsUpIndicator()方法来设置一个导航按钮。
接下来在onOptionsItemSelected()方法中对HomeAsUp按钮进行点击事件处理,HomeAsUp按钮的id永远都是android.R.id.home。
NavigationView
这一部分就是优化我们的滑动菜单,这里我们要使用的控件是NavigationView,它是Desigh Support库提供的一个控件,既然是Desigh Support库提供的,我们就需要将这个库引用到我们的项目中。打开app/build.dradle文件,在dependencies闭包中添加以下内容:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
implementation 'com.android.support:design:28.0.0'
implementation 'de.hdodenhof:circleimageview:2.1.0'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
这里添加了两行依赖关系,第一行是Design Support 库,第二行是一个开源项目CircleImageView。CircleImageView的项目地址是:http://github.com/hdodenhof/CircleImageView。
在开始NavigationView之前,我们先准备准备好两个东西,headerLayout和menu。我们先来准备menu,它是用来在NavigationView中显示具体的菜单项的。这里需要准备好几张图片作为按钮的图标,并将他们放在drawable目录下。然后右击menu文件夹→New→Mew resourc file,创建一个nav_menu.xml文件,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/nac_call"
android:icon="@drawable/nav_call"
android:title="Call"/>
<item
android:id="@+id/nac_friends"
android:icon="@drawable/nav_friends"
android:title="Friends"/>
<item
android:id="@+id/nac_location"
android:icon="@drawable/nav_location"
android:title="Location"/>
<item
android:id="@+id/nac_mail"
android:icon="@drawable/nav_mail"
android:title="Mail"/>
<item
android:id="@+id/nac_task"
android:icon="@drawable/nav_task"
android:title="Tasks"/>
</group>
</menu>
我们首先在
headerLayout是一个可以随意定制的布局,我们就在这里放置头像,用户名,邮箱地址。这里要准备一张图片把它放在drawable目录下。这里我把格式设置为200*200。让后右击layout文件夹→New→Layout resource file,创建一个nav_headr.xml文件。修改其中代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="180dp"
android:padding="10dp"
android:background="?attr/colorPrimary">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/icon_image"
android:layout_width="70dp"
android:layout_height="70dp"
android:src="@drawable/main"
android:layout_centerInParent="true"/>
<TextView
android:id="@+id/mail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="MaterialText@QQ.com"
android:textColor="#FFF"
android:textSize="14sp"/>
<TextView
android:id="@+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/mail"
android:text="JMin"
android:textColor="#FFF"
android:textSize="14sp"/>
</RelativeLayout>
其中最外层是一个RelaitiyeLayout,我们将它的宽度为match_parent,高度为180dp,CircleImageView是一个用于将图片圆形化的控件。
现在使用NavigationView控件修改activity_main.xml的代码:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<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="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/nav_menu"
app:headerLayout="@layout/nav_header">
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
这里我们把之前的TextView换成了NavigationView,通过app:menu和app:headerLayout属性将我们准备好的menu和headerLayou设置进去,这样我们的NavigationView定义就完成了。不过我们还要去处理菜单项的点击事件,修改MainActivity中的代码:
package com.example.materialtext;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
/**
* @author J.Min
*/
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mDrawerLayout=findViewById(R.id.drawer_layout);
NavigationView navView= (NavigationView) findViewById(R.id.nav_view);
ActionBar actionBar = getSupportActionBar();
if(actionBar !=null){
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
navView.setCheckedItem(R.id.nac_call);
navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected( MenuItem item) {
mDrawerLayout.closeDrawers();
return false;
}
});
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.toolbar,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
switch (item.getItemId()) {
case android.R.id.home:
mDrawerLayout.openDrawer(GravityCompat.START);
break;
case R.id.backup:
Toast.makeText(this, "You clicked Backup", Toast.LENGTH_LONG).show();
case R.id.delete:
Toast.makeText(this, "You clicked Delete", Toast.LENGTH_LONG).show();
case R.id.settings:
Toast.makeText(this, "You clicked Settings", Toast.LENGTH_LONG).show();
break;
default:
}
return true;
}
}
这里先获取到了NavigationView的实例,让后调用它的setCheckedItem()方法将Call菜单设置为默认选中。接着调用了setNavigationItemSelectedListener()方法来设置一个菜单选中事件的监听器,当点击任意菜单选项时就会回调到onNavigationItemSelected()方法中。
这节的内容就到这里了,下一节讲UI设计—Material Design实战(3)之悬浮按钮和可交互提示。
https://blog.csdn.net/qq_43468891/article/details/91878100