转载请标明出处:
http://blog.csdn.net/lmj623565791/article/details/46405409;
本文出自:【张鸿洋的博客】
Google I/O 2015 给大家带来了Android Design Support Library,对于希望做md风格的app的来说,简直是天大的喜讯了~大家可以通过Android Design Support Library该文章对其进行了解,也可以直接在github上下载示例代码运行学习。为了表达我心中的喜悦,我决定针对该库写一系列的文章来分别介绍新增加的控件。
ok,那么首先介绍的就是NavigationView,本文将首先介绍该控件的使用,然后介绍如何自己去编写该控件。
注意下更新下as的SDK,然后在使用的过程中,在build.gradle中添加:
compile 'com.android.support:design:22.2.0'
在md风格的app中,例如如下风格的侧滑菜单非常常见:
在之前的设计中,你可能需要考虑如何去布局实现,例如使用ListView;再者还要去设计Item的选中状态之类~~
but,现在,google提供了NavigationView
,你只需要写写布局文件,这样的效果就ok了,并且兼容到Android 2.1,非常值得去体验一下。接下来我们来介绍如何去使用这个NavigationView
!
使用起来very simple ,主要就是写写布局文件~
<android.support.v4.widget.DrawerLayout
android:id="@+id/id_drawer_layout"
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="match_parent"
android:fitsSystemWindows="true"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/id_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
<TextView
android:id="@+id/id_tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="HelloWorld"
android:textSize="30sp"/>
RelativeLayout>
<android.support.design.widget.NavigationView
android:id="@+id/id_nv_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="left"
android:fitsSystemWindows="true"
app:headerLayout="@layout/header_just_username"
app:menu="@menu/menu_drawer"
/>
android.support.v4.widget.DrawerLayout>
可以看到我们的最外层是DrawerLayout
,里面一个content,一个作为drawer。我们的drawer为NavigationView
。
注意这个view的两个属性app:headerLayout="@layout/header_just_username"
和app:menu="@menu/menu_drawer"
,分别代表drawer布局中的header和menuitem区域,当然你可以根据自己的情况使用。
接下来看看header的布局文件和menu配置文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="192dp"
android:background="?attr/colorPrimaryDark"
android:orientation="vertical"
android:padding="16dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<TextView
android:id="@+id/id_link"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="16dp"
android:text="http://blog.csdn.net/lmj623565791"/>
<TextView
android:id="@+id/id_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/id_link"
android:text="Zhang Hongyang"/>
<ImageView
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_above="@id/id_username"
android:layout_marginBottom="16dp"
android:src="@mipmap/icon"/>
RelativeLayout>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_home"
android:icon="@drawable/ic_dashboard"
android:title="Home"/>
<item
android:id="@+id/nav_messages"
android:icon="@drawable/ic_event"
android:title="Messages"/>
<item
android:id="@+id/nav_friends"
android:icon="@drawable/ic_headset"
android:title="Friends"/>
<item
android:id="@+id/nav_discussion"
android:icon="@drawable/ic_forum"
android:title="Discussion"/>
group>
<item android:title="Sub items">
<menu>
<item
android:icon="@drawable/ic_dashboard"
android:title="Sub item 1"/>
<item
android:icon="@drawable/ic_forum"
android:title="Sub item 2"/>
menu>
item>
menu>
别放错文件夹哈~
布局文件写完了,基本就好了,是不是很爽~看似复杂的效果,写写布局文件就ok。
ps:默认的颜色很多是从当前的主题中提取的,比如icon的stateColor,当然你也可以通过以下属性修改部分样式:
app:itemIconTint=""
app:itemBackground=""
app:itemTextColor=""
最后是Activity:
package com.imooc.testandroid;
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
public class NavigationViewActivity extends ActionBarActivity
{
private DrawerLayout mDrawerLayout;
private NavigationView mNavigationView;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_navigation_view);
mDrawerLayout = (DrawerLayout) findViewById(R.id.id_drawer_layout);
mNavigationView = (NavigationView) findViewById(R.id.id_nv_menu);
Toolbar toolbar = (Toolbar) findViewById(R.id.id_toolbar);
setSupportActionBar(toolbar);
final ActionBar ab = getSupportActionBar();
ab.setHomeAsUpIndicator(R.drawable.ic_menu);
ab.setDisplayHomeAsUpEnabled(true);
setupDrawerContent(mNavigationView);
}
private void setupDrawerContent(NavigationView navigationView)
{
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener()
{
@Override
public boolean onNavigationItemSelected(MenuItem menuItem)
{
menuItem.setChecked(true);
mDrawerLayout.closeDrawers();
return true;
}
});
}
@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_navigation_view, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
if(item.getItemId() == android.R.id.home)
{
mDrawerLayout.openDrawer(GravityCompat.START);
return true ;
}
return super.onOptionsItemSelected(item);
}
}
我们在Activity里面可以通过navigationView去navigationView.setNavigationItemSelectedListener
,当selected的时候,menuItem去setChecked(true)。
别忘了设置theme~
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!<span class="hljs-tag">--</span> <span class="hljs-tag">Customize</span> <span class="hljs-tag">your</span> <span class="hljs-tag">theme</span> <span class="hljs-tag">here</span>. <span class="hljs-tag">--</span>>
</span><span class="hljs-tag"></<span class="hljs-title">style</span>></span>
<span class="hljs-tag"><<span class="hljs-title">style</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"Theme.DesignDemo"</span> <span class="hljs-attribute">parent</span>=<span class="hljs-value">"Base.Theme.DesignDemo"</span>></span><span class="css">
</span><span class="hljs-tag"></<span class="hljs-title">style</span>></span>
<span class="hljs-tag"><<span class="hljs-title">style</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"Base.Theme.DesignDemo"</span> <span class="hljs-attribute">parent</span>=<span class="hljs-value">"Theme.AppCompat.Light.NoActionBar"</span>></span><span class="css">
<<span class="hljs-tag">item</span> <span class="hljs-tag">name</span>="<span class="hljs-tag">colorPrimary</span>"><span class="hljs-id">#673AB7</span></<span class="hljs-tag">item</span>>
<<span class="hljs-tag">item</span> <span class="hljs-tag">name</span>="<span class="hljs-tag">colorPrimaryDark</span>"><span class="hljs-id">#512DA8</span></<span class="hljs-tag">item</span>>
<<span class="hljs-tag">item</span> <span class="hljs-tag">name</span>="<span class="hljs-tag">colorAccent</span>"><span class="hljs-id">#FF4081</span></<span class="hljs-tag">item</span>>
<<span class="hljs-tag">item</span> <span class="hljs-tag">name</span>="<span class="hljs-tag">android</span><span class="hljs-pseudo">:windowBackground"</span>><span class="hljs-at_rule">@<span class="hljs-keyword">color/window_background</item></span>
</span></span><span class="hljs-tag"></<span class="hljs-title">style</span>></span>
<span class="hljs-tag"></<span class="hljs-title">resources</span>></span>
<span class="hljs-tag"><<span class="hljs-title">color</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"window_background"</span>></span>#FFF5F5F5<span class="hljs-tag"></<span class="hljs-title">color</span>></span>
<span class="hljs-tag"><<span class="hljs-title">activity
</span> <span class="hljs-attribute">android:name</span>=<span class="hljs-value">".NavigationViewActivity"</span>
<span class="hljs-attribute">android:label</span>=<span class="hljs-value">"@string/title_activity_navigation_view"</span>
<span class="hljs-attribute">android:theme</span>=<span class="hljs-value">"@style/Theme.DesignDemo"</span>></span>
<span class="hljs-tag"></<span class="hljs-title">activity</span>></span>
</code></pre>
<p>ok,到此就搞定了~~</p>
<p>不过存在一个问题,此时你如果点击Sub items里面的Sub item,如果你期望当前选中应该是Sub item,你会发现不起作用。那怎么办呢?</p>
<h4 id="三sub-item支持cheable">(三)Sub Item支持Cheable</h4>
<p>这里可以修改menu的配置文件:</p>
<pre class="prettyprint"><code class=" hljs xml"><span class="hljs-pi"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-title">menu</span> <span class="hljs-attribute">xmlns:android</span>=<span class="hljs-value">"http://schemas.android.com/apk/res/android"</span>></span>
<span class="hljs-tag"><<span class="hljs-title">group</span>></span>
<span class="hljs-tag"><<span class="hljs-title">item
</span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/nav_home"</span>
<span class="hljs-attribute">android:checkable</span>=<span class="hljs-value">"true"</span>
<span class="hljs-attribute">android:icon</span>=<span class="hljs-value">"@drawable/ic_dashboard"</span>
<span class="hljs-attribute">android:title</span>=<span class="hljs-value">"Home"</span>/></span>
<span class="hljs-tag"><<span class="hljs-title">item
</span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/nav_messages"</span>
<span class="hljs-attribute">android:checkable</span>=<span class="hljs-value">"true"</span>
<span class="hljs-attribute">android:icon</span>=<span class="hljs-value">"@drawable/ic_event"</span>
<span class="hljs-attribute">android:title</span>=<span class="hljs-value">"Messages"</span>/></span>
<span class="hljs-tag"><<span class="hljs-title">item
</span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/nav_friends"</span>
<span class="hljs-attribute">android:checkable</span>=<span class="hljs-value">"true"</span>
<span class="hljs-attribute">android:icon</span>=<span class="hljs-value">"@drawable/ic_headset"</span>
<span class="hljs-attribute">android:title</span>=<span class="hljs-value">"Friends"</span>/></span>
<span class="hljs-tag"><<span class="hljs-title">item
</span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/nav_discussion"</span>
<span class="hljs-attribute">android:checkable</span>=<span class="hljs-value">"true"</span>
<span class="hljs-attribute">android:icon</span>=<span class="hljs-value">"@drawable/ic_forum"</span>
<span class="hljs-attribute">android:title</span>=<span class="hljs-value">"Discussion"</span>/></span>
<span class="hljs-tag"></<span class="hljs-title">group</span>></span>
<span class="hljs-tag"><<span class="hljs-title">item</span> <span class="hljs-attribute">android:title</span>=<span class="hljs-value">"Sub items"</span>></span>
<span class="hljs-tag"><<span class="hljs-title">menu</span>></span>
<span class="hljs-tag"><<span class="hljs-title">item
</span> <span class="hljs-attribute">android:checkable</span>=<span class="hljs-value">"true"</span>
<span class="hljs-attribute">android:icon</span>=<span class="hljs-value">"@drawable/ic_dashboard"</span>
<span class="hljs-attribute">android:title</span>=<span class="hljs-value">"Sub item 1"</span>/></span>
<span class="hljs-tag"><<span class="hljs-title">item
</span> <span class="hljs-attribute">android:checkable</span>=<span class="hljs-value">"true"</span>
<span class="hljs-attribute">android:icon</span>=<span class="hljs-value">"@drawable/ic_forum"</span>
<span class="hljs-attribute">android:title</span>=<span class="hljs-value">"Sub item 2"</span>/></span>
<span class="hljs-tag"></<span class="hljs-title">menu</span>></span>
<span class="hljs-tag"></<span class="hljs-title">item</span>></span>
<span class="hljs-tag"></<span class="hljs-title">menu</span>></span></code></pre>
<p>将<code>android:checkableBehavior="single"</code>去掉,然后给每个item项添加<code>android:checkable="true"</code>。</p>
<p>然后在代码中:</p>
<pre class="prettyprint"><code class=" hljs java">navigationView.setNavigationItemSelectedListener(
<span class="hljs-keyword">new</span> NavigationView.OnNavigationItemSelectedListener()
{
<span class="hljs-keyword">private</span> MenuItem mPreMenuItem;
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">onNavigationItemSelected</span>(MenuItem menuItem)
{
<span class="hljs-keyword">if</span> (mPreMenuItem != <span class="hljs-keyword">null</span>) mPreMenuItem.setChecked(<span class="hljs-keyword">false</span>);
menuItem.setChecked(<span class="hljs-keyword">true</span>);
mDrawerLayout.closeDrawers();
mPreMenuItem = menuItem;
<span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
}
});</code></pre>
<p>存一下preMenuItem,手动切换。</p>
<p>效果:</p>
<p><img src="http://img.blog.csdn.net/20150607224828449" width="320px" /></p>
<p>ok,哈~其实这个还是参考链接2里面的一个评论说的~~</p>
<p>到此用法就介绍完了~有木有一点小激动~ 但是还有个问题,对于app,就像ActionBar最初的出现,一开始大家都欢欣鼓舞,后来发现app中多数情况下需要去定制,尼玛,是不是忽然觉得ActionBar太死板了,恶心死了(当然了现在有了ToolBar灵活度上好多了,关于Toolbar可以参考<a href="http://blog.csdn.net/lmj623565791/article/details/45303349">Android 5.x Theme 与 ToolBar 实战</a>~对于上述<code>NavigationView</code>可能也会存在定制上的问题,比如我希望选中的Item左边有个高亮的竖线之类的效果。那么,针对于各种需求,想要能解决各种问题,最好的方式就是说对于<code>NavigationView</code>的效果自己可以实现。最好,我们就来看看<code>NavigationView</code>自己实现有多难?</p>
<h3 id="三自己实现navigationview效果">三、自己实现NavigationView效果</h3>
<p>其实<code>NavigationView</code>的实现非常简单,一个ListView就可以了,甚至都不需要去自定义,简单写一个Adapter就行了~~</p>
<p><img src="http://img.blog.csdn.net/20150607225010465" width="320px" /></p>
<p>首先观察该图,有没有发现神奇之处,恩,你肯定发现不了,因为我们做的太像了。</p>
<p>其实这个图就是我通过ListView写的一个~是不是和原版很像(~哈~参考了源码的实现,当然像。)</p>
<p>接下来分析,如果说是ListView,那么Item的type肯定不止一种,那我们数一数种类:</p>
<ul>
<li>带图标和文本的</li>
<li>仅仅是文本的 Sub Items</li>
<li>分割线</li>
</ul>
<p>你会说还有顶部那个,顶部是headview呀~~</p>
<p>这么分析完成,是不是瞬间觉得没有难度了~</p>
<h4 id="一首先布局文件">(一)首先布局文件</h4>
<pre class="prettyprint"><code class="language-xml hljs "><span class="hljs-pi"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-title">android.support.v4.widget.DrawerLayout
</span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/id_drawer_layout"</span>
<span class="hljs-attribute">xmlns:android</span>=<span class="hljs-value">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attribute">xmlns:app</span>=<span class="hljs-value">"http://schemas.android.com/apk/res-auto"</span>
<span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
<span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span>
<span class="hljs-attribute">android:fitsSystemWindows</span>=<span class="hljs-value">"true"</span>
></span>
<span class="hljs-tag"><<span class="hljs-title">RelativeLayout
</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
<span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span>></span>
<span class="hljs-tag"><<span class="hljs-title">android.support.v7.widget.Toolbar
</span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/id_toolbar"</span>
<span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
<span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"?attr/actionBarSize"</span>
<span class="hljs-attribute">android:background</span>=<span class="hljs-value">"?attr/colorPrimary"</span>
<span class="hljs-attribute">app:layout_scrollFlags</span>=<span class="hljs-value">"scroll|enterAlways"</span>
<span class="hljs-attribute">app:popupTheme</span>=<span class="hljs-value">"@style/ThemeOverlay.AppCompat.Light"</span>/></span>
<span class="hljs-tag"><<span class="hljs-title">TextView
</span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/id_tv_content"</span>
<span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"wrap_content"</span>
<span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span>
<span class="hljs-attribute">android:layout_centerInParent</span>=<span class="hljs-value">"true"</span>
<span class="hljs-attribute">android:text</span>=<span class="hljs-value">"HelloWorld"</span>
<span class="hljs-attribute">android:textSize</span>=<span class="hljs-value">"30sp"</span>/></span>
<span class="hljs-tag"></<span class="hljs-title">RelativeLayout</span>></span>
<span class="hljs-tag"><<span class="hljs-title">ListView
</span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/id_lv_left_menu"</span>
<span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
<span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span>
<span class="hljs-attribute">android:layout_gravity</span>=<span class="hljs-value">"start"</span>
<span class="hljs-attribute">android:paddingTop</span>=<span class="hljs-value">"0dp"</span>
<span class="hljs-attribute">android:background</span>=<span class="hljs-value">"#ffffffff"</span>
<span class="hljs-attribute">android:clipToPadding</span>=<span class="hljs-value">"false"</span>
<span class="hljs-attribute">android:divider</span>=<span class="hljs-value">"@null"</span>
<span class="hljs-attribute">android:listSelector</span>=<span class="hljs-value">"?attr/selectableItemBackground"</span>
/></span>
<span class="hljs-tag"></<span class="hljs-title">android.support.v4.widget.DrawerLayout</span>></span>
</code></pre>
<p>布局文件上:和上文对比,我们仅仅把NavigationView换成了ListView.</p>
<p>下面注意了,一大波代码来袭.</p>
<h4 id="二-activity">(二) Activity</h4>
<pre class="prettyprint"><code class="language-java hljs "><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NavListViewActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ActionBarActivity</span>
{</span>
<span class="hljs-keyword">private</span> ListView mLvLeftMenu;
<span class="hljs-keyword">private</span> DrawerLayout mDrawerLayout;
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span>(Bundle savedInstanceState)
{
<span class="hljs-keyword">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_nav_list_view);
mDrawerLayout = (DrawerLayout) findViewById(R.id.id_drawer_layout);
mLvLeftMenu = (ListView) findViewById(R.id.id_lv_left_menu);
Toolbar toolbar = (Toolbar) findViewById(R.id.id_toolbar);
setSupportActionBar(toolbar);
<span class="hljs-keyword">final</span> ActionBar ab = getSupportActionBar();
ab.setHomeAsUpIndicator(R.drawable.ic_menu);
ab.setDisplayHomeAsUpEnabled(<span class="hljs-keyword">true</span>);
setUpDrawer();
}
<span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setUpDrawer</span>()
{
LayoutInflater inflater = LayoutInflater.from(<span class="hljs-keyword">this</span>);
mLvLeftMenu.addHeaderView(inflater.inflate(R.layout.header_just_username, mLvLeftMenu, <span class="hljs-keyword">false</span>));
mLvLeftMenu.setAdapter(<span class="hljs-keyword">new</span> MenuItemAdapter(<span class="hljs-keyword">this</span>));
}
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">onCreateOptionsMenu</span>(Menu menu)
{
<span class="hljs-comment">// Inflate the menu; this adds items to the action bar if it is present.</span>
getMenuInflater().inflate(R.menu.menu_nav_list_view, menu);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
}
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">onOptionsItemSelected</span>(MenuItem item)
{
<span class="hljs-comment">// Handle action bar item clicks here. The action bar will</span>
<span class="hljs-comment">// automatically handle clicks on the Home/Up button, so long</span>
<span class="hljs-comment">// as you specify a parent activity in AndroidManifest.xml.</span>
<span class="hljs-keyword">int</span> id = item.getItemId();
<span class="hljs-comment">//noinspection SimplifiableIfStatement</span>
<span class="hljs-keyword">if</span> (id == android.R.id.home)
{
mDrawerLayout.openDrawer(GravityCompat.START);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
}
<span class="hljs-keyword">return</span> <span class="hljs-keyword">super</span>.onOptionsItemSelected(item);
}
}
</code></pre>
<p>直接看onCreate中的<code>setUpDrawer()</code>,可以看到我们首先去addHeadView,然后去setAdapter。</p>
<p>那么核心代码就是我们的Adapter了~~</p>
<h4 id="三menuitemadapter">(三)MenuItemAdapter</h4>
<pre class="prettyprint"><code class="language-java hljs "><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LvMenuItem</span>
{</span>
<span class="hljs-keyword">public</span> <span class="hljs-title">LvMenuItem</span>(<span class="hljs-keyword">int</span> icon, String name)
{
<span class="hljs-keyword">this</span>.icon = icon;
<span class="hljs-keyword">this</span>.name = name;
<span class="hljs-keyword">if</span> (icon == NO_ICON && TextUtils.isEmpty(name))
{
type = TYPE_SEPARATOR;
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (icon == NO_ICON)
{
type = TYPE_NO_ICON;
} <span class="hljs-keyword">else</span>
{
type = TYPE_NORMAL;
}
<span class="hljs-keyword">if</span> (type != TYPE_SEPARATOR && TextUtils.isEmpty(name))
{
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"you need set a name for a non-SEPARATOR item"</span>);
}
L.e(type + <span class="hljs-string">""</span>);
}
<span class="hljs-keyword">public</span> <span class="hljs-title">LvMenuItem</span>(String name)
{
<span class="hljs-keyword">this</span>(NO_ICON, name);
}
<span class="hljs-keyword">public</span> <span class="hljs-title">LvMenuItem</span>()
{
<span class="hljs-keyword">this</span>(<span class="hljs-keyword">null</span>);
}
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> NO_ICON = <span class="hljs-number">0</span>;
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> TYPE_NORMAL = <span class="hljs-number">0</span>;
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> TYPE_NO_ICON = <span class="hljs-number">1</span>;
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> TYPE_SEPARATOR = <span class="hljs-number">2</span>;
<span class="hljs-keyword">int</span> type;
String name;
<span class="hljs-keyword">int</span> icon;
}
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MenuItemAdapter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">BaseAdapter</span>
{</span>
<span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> mIconSize;
<span class="hljs-keyword">private</span> LayoutInflater mInflater;
<span class="hljs-keyword">private</span> Context mContext;
<span class="hljs-keyword">public</span> <span class="hljs-title">MenuItemAdapter</span>(Context context)
{
mInflater = LayoutInflater.from(context);
mContext = context;
mIconSize = context.getResources().getDimensionPixelSize(R.dimen.drawer_icon_size);<span class="hljs-comment">//24dp</span>
}
<span class="hljs-keyword">private</span> List<LvMenuItem> mItems = <span class="hljs-keyword">new</span> ArrayList<LvMenuItem>(
Arrays.asList(
<span class="hljs-keyword">new</span> LvMenuItem(R.drawable.ic_dashboard, <span class="hljs-string">"Home"</span>),
<span class="hljs-keyword">new</span> LvMenuItem(R.drawable.ic_event, <span class="hljs-string">"Messages"</span>),
<span class="hljs-keyword">new</span> LvMenuItem(R.drawable.ic_headset, <span class="hljs-string">"Friends"</span>),
<span class="hljs-keyword">new</span> LvMenuItem(R.drawable.ic_forum, <span class="hljs-string">"Discussion"</span>),
<span class="hljs-keyword">new</span> LvMenuItem(),
<span class="hljs-keyword">new</span> LvMenuItem(<span class="hljs-string">"Sub Items"</span>),
<span class="hljs-keyword">new</span> LvMenuItem(R.drawable.ic_dashboard, <span class="hljs-string">"Sub Item 1"</span>),
<span class="hljs-keyword">new</span> LvMenuItem(R.drawable.ic_forum, <span class="hljs-string">"Sub Item 2"</span>)
));
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getCount</span>()
{
<span class="hljs-keyword">return</span> mItems.size();
}
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> Object <span class="hljs-title">getItem</span>(<span class="hljs-keyword">int</span> position)
{
<span class="hljs-keyword">return</span> mItems.get(position);
}
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">long</span> <span class="hljs-title">getItemId</span>(<span class="hljs-keyword">int</span> position)
{
<span class="hljs-keyword">return</span> position;
}
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getViewTypeCount</span>()
{
<span class="hljs-keyword">return</span> <span class="hljs-number">3</span>;
}
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getItemViewType</span>(<span class="hljs-keyword">int</span> position)
{
<span class="hljs-keyword">return</span> mItems.get(position).type;
}
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> View <span class="hljs-title">getView</span>(<span class="hljs-keyword">int</span> position, View convertView, ViewGroup parent)
{
LvMenuItem item = mItems.get(position);
<span class="hljs-keyword">switch</span> (item.type)
{
<span class="hljs-keyword">case</span> LvMenuItem.TYPE_NORMAL:
<span class="hljs-keyword">if</span> (convertView == <span class="hljs-keyword">null</span>)
{
convertView = mInflater.inflate(R.layout.design_drawer_item, parent,
<span class="hljs-keyword">false</span>);
}
TextView itemView = (TextView) convertView;
itemView.setText(item.name);
Drawable icon = mContext.getResources().getDrawable(item.icon);
setIconColor(icon);
<span class="hljs-keyword">if</span> (icon != <span class="hljs-keyword">null</span>)
{
icon.setBounds(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, mIconSize, mIconSize);
TextViewCompat.setCompoundDrawablesRelative(itemView, icon, <span class="hljs-keyword">null</span>, <span class="hljs-keyword">null</span>, <span class="hljs-keyword">null</span>);
}
<span class="hljs-keyword">break</span>;
<span class="hljs-keyword">case</span> LvMenuItem.TYPE_NO_ICON:
<span class="hljs-keyword">if</span> (convertView == <span class="hljs-keyword">null</span>)
{
convertView = mInflater.inflate(R.layout.design_drawer_item_subheader,
parent, <span class="hljs-keyword">false</span>);
}
TextView subHeader = (TextView) convertView;
subHeader.setText(item.name);
<span class="hljs-keyword">break</span>;
<span class="hljs-keyword">case</span> LvMenuItem.TYPE_SEPARATOR:
<span class="hljs-keyword">if</span> (convertView == <span class="hljs-keyword">null</span>)
{
convertView = mInflater.inflate(R.layout.design_drawer_item_separator,
parent, <span class="hljs-keyword">false</span>);
}
<span class="hljs-keyword">break</span>;
}
<span class="hljs-keyword">return</span> convertView;
}
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setIconColor</span>(Drawable icon)
{
<span class="hljs-keyword">int</span> textColorSecondary = android.R.attr.textColorSecondary;
TypedValue value = <span class="hljs-keyword">new</span> TypedValue();
<span class="hljs-keyword">if</span> (!mContext.getTheme().resolveAttribute(textColorSecondary, value, <span class="hljs-keyword">true</span>))
{
<span class="hljs-keyword">return</span>;
}
<span class="hljs-keyword">int</span> baseColor = mContext.getResources().getColor(value.resourceId);
icon.setColorFilter(baseColor, PorterDuff.Mode.MULTIPLY);
}
}</code></pre>
<p>首先我们的每个Item对应于一个LvMenuItem,包含icon、name、type,可以看到我们的type分为3类。</p>
<p>那么adapter中代码就很简单了,多Item布局的写法。</p>
<p>这样就完成了,我们自己去书写<code>NavigationView</code>,是不是很简单~~如果你的app需要类似效果,但是又与<code>NavigationView</code>的效果并非一模一样,可以考虑按照上面的思路自己写一个。</p>
<p>最后贴一下用到的Item的布局文件:</p>
<ul>
<li>design_drawer_item_subheader.xml</li>
</ul>
<pre class="prettyprint"><code class="language-xml hljs "><span class="hljs-pi"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-title">TextView</span> <span class="hljs-attribute">xmlns:android</span>=<span class="hljs-value">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
<span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"?attr/listPreferredItemHeightSmall"</span>
<span class="hljs-attribute">android:gravity</span>=<span class="hljs-value">"center_vertical|start"</span>
<span class="hljs-attribute">android:maxLines</span>=<span class="hljs-value">"1"</span>
<span class="hljs-attribute">android:paddingLeft</span>=<span class="hljs-value">"?attr/listPreferredItemPaddingLeft"</span>
<span class="hljs-attribute">android:paddingRight</span>=<span class="hljs-value">"?attr/listPreferredItemPaddingRight"</span>
<span class="hljs-attribute">android:textAppearance</span>=<span class="hljs-value">"?attr/textAppearanceListItem"</span>
<span class="hljs-attribute">android:textColor</span>=<span class="hljs-value">"?android:textColorSecondary"</span>/></span>
</code></pre>
<ul>
<li>design_drawer_item_separator.xml</li>
</ul>
<pre class="prettyprint"><code class="language-xml hljs ">
<span class="hljs-pi"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-title">FrameLayout</span> <span class="hljs-attribute">xmlns:android</span>=<span class="hljs-value">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
<span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span>></span>
<span class="hljs-tag"><<span class="hljs-title">View</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
<span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"1dp"</span>
<span class="hljs-attribute">android:background</span>=<span class="hljs-value">"?android:attr/listDivider"</span>/></span>
<span class="hljs-tag"></<span class="hljs-title">FrameLayout</span>></span>
</code></pre>
<ul>
<li>design_drawer_item,xml:</li>
</ul>
<pre class="prettyprint"><code class="language-xml hljs "><span class="hljs-pi"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-title">TextView
</span> <span class="hljs-attribute">xmlns:android</span>=<span class="hljs-value">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
<span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"?attr/listPreferredItemHeightSmall"</span>
<span class="hljs-attribute">android:paddingLeft</span>=<span class="hljs-value">"?attr/listPreferredItemPaddingLeft"</span>
<span class="hljs-attribute">android:paddingRight</span>=<span class="hljs-value">"?attr/listPreferredItemPaddingRight"</span>
<span class="hljs-attribute">android:drawablePadding</span>=<span class="hljs-value">"32dp"</span>
<span class="hljs-attribute">android:gravity</span>=<span class="hljs-value">"center_vertical|start"</span>
<span class="hljs-attribute">android:maxLines</span>=<span class="hljs-value">"1"</span>
<span class="hljs-attribute">android:textAppearance</span>=<span class="hljs-value">"?attr/textAppearanceListItem"</span>
<span class="hljs-attribute">android:textColor</span>=<span class="hljs-value">"?android:attr/textColorPrimary"</span>/></span></code></pre>
<p>ok,其实上述ListView的写法也正是<code>NavigationView</code>的源码实现,item的布局文件直接从源码中拖出来的,还是爽爽哒~~</p>
<p>~~ hava a nice day ~~</p>
<h3 id="参考链接">参考链接</h3>
<ul>
<li><a href="https://guides.codepath.com/android/Fragment-Navigation-Drawer">https://guides.codepath.com/android/Fragment-Navigation-Drawer</a></li>
<li><a href="http://antonioleiva.com/navigation-view/">http://antonioleiva.com/navigation-view/</a></li>
<li><a href="http://android-developers.blogspot.com/2015/05/android-design-support-library.html">http://android-developers.blogspot.com/2015/05/android-design-support-library.html</a></li>
</ul>
<p>ok~</p>
<p><a href="https://github.com/hongyangAndroid/Android_Blog_Demos">源码点击下载</a></p>
<blockquote>
<p>微信公众号:hongyangAndroid <br />
(欢迎关注,第一时间推送博文信息) <br />
<img src="http://img.my.csdn.net/uploads/201501/30/1422600516_2905.jpg" width="200px" /></p>
</blockquote>
<div>
作者:lmj623565791 发表于2015/6/8 9:25:17 <a href="http://blog.csdn.net/lmj623565791/article/details/46405409">原文链接</a>
</div>
<div>
阅读:6402 评论:56 <a href="http://blog.csdn.net/lmj623565791/article/details/46405409#comments" target="_blank">查看评论</a>
</div>