转载请标明出处:

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 ,主要就是写写布局文件~

(一)布局文件

<?xml version="1.0" encoding="utf-8"?

>
<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配置文件:


<?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="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>
<?

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/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

最后是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>

    <!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style> <style name="Theme.DesignDemo" parent="Base.Theme.DesignDemo">
</style> <style name="Base.Theme.DesignDemo" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#673AB7</item>
<item name="colorPrimaryDark">#512DA8</item>
<item name="colorAccent">#FF4081</item>
<item name="android:windowBackground">@color/window_background</item>
</style> </resources> <color name="window_background">#FFF5F5F5</color> <activity
android:name=".NavigationViewActivity"
android:label="@string/title_activity_navigation_view"
android:theme="@style/Theme.DesignDemo">
</activity>

ok。到此就搞定了~~

不过存在一个问题,此时你假设点击Sub items里面的Sub item,假设你期望当前选中应该是Sub item。你会发现不起作用。那怎么办呢?

(三)Sub Item支持Cheable

这里能够改动menu的配置文件:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <group>
<item
android:id="@+id/nav_home"
android:checkable="true"
android:icon="@drawable/ic_dashboard"
android:title="Home"/>
<item
android:id="@+id/nav_messages"
android:checkable="true"
android:icon="@drawable/ic_event"
android:title="Messages"/>
<item
android:id="@+id/nav_friends"
android:checkable="true"
android:icon="@drawable/ic_headset"
android:title="Friends"/>
<item
android:id="@+id/nav_discussion"
android:checkable="true"
android:icon="@drawable/ic_forum"
android:title="Discussion"/>
</group> <item android:title="Sub items">
<menu>
<item
android:checkable="true"
android:icon="@drawable/ic_dashboard"
android:title="Sub item 1"/>
<item
android:checkable="true"
android:icon="@drawable/ic_forum"
android:title="Sub item 2"/>
</menu>
</item> </menu>

android:checkableBehavior="single"去掉,然后给每一个item项加入android:checkable="true"

然后在代码中:

navigationView.setNavigationItemSelectedListener(

                new NavigationView.OnNavigationItemSelectedListener()
{ private MenuItem mPreMenuItem; @Override
public boolean onNavigationItemSelected(MenuItem menuItem)
{
if (mPreMenuItem != null) mPreMenuItem.setChecked(false);
menuItem.setChecked(true);
mDrawerLayout.closeDrawers();
mPreMenuItem = menuItem;
return true;
}
});

存一下preMenuItem。手动切换。

效果:

ok,哈~事实上这个还是參考链接2里面的一个评论说的~~

到此使用方法就介绍完了有木有一点小激动~ 可是还有个问题。对于app,就像ActionBar最初的出现,一開始大家都欢欣鼓励,后来发现app中多数情况下须要去定制,尼玛。是不是忽然认为ActionBar太死板了,恶心死了(当然了如今有了ToolBar灵活度上好多了)对于上述NavigationView可能也会存在定制上的问题。比方我希望选中的Item左边有个高亮的竖线之类的效果。

那么,针对于各种需求,想要能解决各种问题,最好的方式就是说对于NavigationView的效果自己能够实现。

最好,我们就来看看NavigationView自己实现有多难?

三、自己实现NavigationView效果

事实上NavigationView的实现非常easy,一个ListView就能够了。甚至都不须要去自己定义,简单写一个Adapter即可了~~

首先观察该图,有没有发现奇妙之处。恩,你肯定发现不了,由于我们做的太像了。

事实上这个图就是我通过ListView写的一个~是不是和原版非常像(~哈~參考了源代码的实现,当然像。)

接下来分析。假设说是ListView,那么Item的type肯定不止一种,那我们数一数种类:

  • 带图标和文本的
  • 不过文本的 Sub Items
  • 切割线

你会说还有顶部那个。顶部是headview呀~~

这么分析完毕,是不是瞬间认为没有难度了~

(一)首先布局文件

<?xml version="1.0" encoding="utf-8"?>
<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> <ListView
android:id="@+id/id_lv_left_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:paddingTop="0dp"
android:background="#ffffffff"
android:clipToPadding="false"
android:divider="@null"
android:listSelector="?attr/selectableItemBackground"
/> </android.support.v4.widget.DrawerLayout>

布局文件上:和上文对照,我们只把NavigationView换成了ListView.

以下注意了,一大波代码来袭.

(二) Activity

package com.imooc.testandroid;

public class NavListViewActivity extends ActionBarActivity
{
private ListView mLvLeftMenu;
private DrawerLayout mDrawerLayout; @Override
protected void onCreate(Bundle savedInstanceState)
{
super.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); final ActionBar ab = getSupportActionBar();
ab.setHomeAsUpIndicator(R.drawable.ic_menu);
ab.setDisplayHomeAsUpEnabled(true); setUpDrawer();
} private void setUpDrawer()
{
LayoutInflater inflater = LayoutInflater.from(this);
mLvLeftMenu.addHeaderView(inflater.inflate(R.layout.header_just_username, mLvLeftMenu, false));
mLvLeftMenu.setAdapter(new MenuItemAdapter(this));
} @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_nav_list_view, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId(); //noinspection SimplifiableIfStatement
if (id == android.R.id.home)
{
mDrawerLayout.openDrawer(GravityCompat.START);
return true;
} return super.onOptionsItemSelected(item);
} }

直接看onCreate中的setUpDrawer(),能够看到我们首先去addHeadView。然后去setAdapter。

那么核心代码就是我们的Adapter了~~

(三)MenuItemAdapter



    public class LvMenuItem
{
public LvMenuItem(int icon, String name)
{
this.icon = icon;
this.name = name; if (icon == NO_ICON && TextUtils.isEmpty(name))
{
type = TYPE_SEPARATOR;
} else if (icon == NO_ICON)
{
type = TYPE_NO_ICON;
} else
{
type = TYPE_NORMAL;
} if (type != TYPE_SEPARATOR && TextUtils.isEmpty(name))
{
throw new IllegalArgumentException("you need set a name for a non-SEPARATOR item");
} L.e(type + ""); } public LvMenuItem(String name)
{
this(NO_ICON, name);
} public LvMenuItem()
{
this(null);
} private static final int NO_ICON = 0;
public static final int TYPE_NORMAL = 0;
public static final int TYPE_NO_ICON = 1;
public static final int TYPE_SEPARATOR = 2; int type;
String name;
int icon; } public class MenuItemAdapter extends BaseAdapter
{
private final int mIconSize;
private LayoutInflater mInflater;
private Context mContext; public MenuItemAdapter(Context context)
{
mInflater = LayoutInflater.from(context);
mContext = context; mIconSize = context.getResources().getDimensionPixelSize(R.dimen.drawer_icon_size);//24dp
} private List<LvMenuItem> mItems = new ArrayList<LvMenuItem>(
Arrays.asList(
new LvMenuItem(R.drawable.ic_dashboard, "Home"),
new LvMenuItem(R.drawable.ic_event, "Messages"),
new LvMenuItem(R.drawable.ic_headset, "Friends"),
new LvMenuItem(R.drawable.ic_forum, "Discussion"),
new LvMenuItem(),
new LvMenuItem("Sub Items"),
new LvMenuItem(R.drawable.ic_dashboard, "Sub Item 1"),
new LvMenuItem(R.drawable.ic_forum, "Sub Item 2")
)); @Override
public int getCount()
{
return mItems.size();
} @Override
public Object getItem(int position)
{
return mItems.get(position);
} @Override
public long getItemId(int position)
{
return position;
} @Override
public int getViewTypeCount()
{
return 3;
} @Override
public int getItemViewType(int position)
{
return mItems.get(position).type;
} @Override
public View getView(int position, View convertView, ViewGroup parent)
{
LvMenuItem item = mItems.get(position);
switch (item.type)
{
case LvMenuItem.TYPE_NORMAL:
if (convertView == null)
{
convertView = mInflater.inflate(R.layout.design_drawer_item, parent,
false);
}
TextView itemView = (TextView) convertView;
itemView.setText(item.name);
Drawable icon = mContext.getResources().getDrawable(item.icon);
setIconColor(icon);
if (icon != null)
{
icon.setBounds(0, 0, mIconSize, mIconSize);
TextViewCompat.setCompoundDrawablesRelative(itemView, icon, null, null, null);
} break;
case LvMenuItem.TYPE_NO_ICON:
if (convertView == null)
{
convertView = mInflater.inflate(R.layout.design_drawer_item_subheader,
parent, false);
}
TextView subHeader = (TextView) convertView;
subHeader.setText(item.name);
break;
case LvMenuItem.TYPE_SEPARATOR:
if (convertView == null)
{
convertView = mInflater.inflate(R.layout.design_drawer_item_separator,
parent, false);
}
break;
} return convertView;
} public void setIconColor(Drawable icon)
{
int textColorSecondary = android.R.attr.textColorSecondary;
TypedValue value = new TypedValue();
if (!mContext.getTheme().resolveAttribute(textColorSecondary, value, true))
{
return;
}
int baseColor = mContext.getResources().getColor(value.resourceId);
icon.setColorFilter(baseColor, PorterDuff.Mode.MULTIPLY);
}
}

首先我们的每一个Item相应于一个LvMenuItem。包括icon、name、type。能够看到我们的type分为3类。

那么adapter中代码就非常easy了,多Item布局的写法。

这样就完毕了,我们自己去书写NavigationView,是不是非常easy~~假设你的app须要相似效果,可是又与NavigationView的效果并不是一模一样。能够考虑依照上面的思路自己写一个。

最后贴一下用到的Item的布局文件:

  • design_drawer_item_subheader.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="? attr/listPreferredItemHeightSmall"
android:gravity="center_vertical|start"
android:maxLines="1"
android:paddingLeft="?attr/listPreferredItemPaddingLeft"
android:paddingRight="? attr/listPreferredItemPaddingRight"
android:textAppearance="? attr/textAppearanceListItem"
android:textColor="?android:textColorSecondary"/>
  • design_drawer_item_separator.xml

<? xml version="1.0" encoding="utf-8"? >
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"> <View android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:attr/listDivider"/> </FrameLayout>
  • design_drawer_item,xml:
<?

xml version="1.0" encoding="utf-8"?

>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeightSmall"
android:paddingLeft="?attr/listPreferredItemPaddingLeft"
android:paddingRight="?attr/listPreferredItemPaddingRight"
android:drawablePadding="32dp"
android:gravity="center_vertical|start"
android:maxLines="1"
android:textAppearance="?attr/textAppearanceListItem"
android:textColor="? android:attr/textColorPrimary"/>

ok。事实上上述ListView的写法也正是NavigationView的源代码实现~~item的布局文件直接从源代码中拖出来的,还是爽爽哒~

源代码点击下载

~~hava a nice day ~~

新浪微博

微信公众号:hongyangAndroid

(欢迎关注,第一时间推送博文信息)

參考链接

Android 自己实现 NavigationView [Design Support Library(1)]的更多相关文章

  1. Android Design Support Library(二)用NavigationView实现抽屉菜单界面

    NavigationView在MD设计中非常重要,之前Google也提出了使用DrawerLayout来实现导航抽屉.这次,在Android Design Support Library中,Googl ...

  2. Android Design Support Library初探,NavigationView实践

    前言 在前几天的IO大会上,Google带来了Android M,同时还有Android支持库的新一轮更新,其中更是增加一个全新的支持库Android Design Support Library,包 ...

  3. Android Design Support Library使用详解

    Android Design Support Library使用详解 Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的And ...

  4. 【转】【翻】Android Design Support Library 的 代码实验——几行代码,让你的 APP 变得花俏

    转自:http://mrfufufu.github.io/android/2015/07/01/Codelab_Android_Design_Support_Library.html [翻]Andro ...

  5. 【转】Android的材料设计兼容库(Design Support Library)

    转自:http://www.jcodecraeer.com/a/anzhuokaifa/developer/2015/0531/2958.html?mType=Group Android的材料设计兼容 ...

  6. Android应用Design Support Library完全使用实例

    阅读目录 2-1 综述 2-2 TextInputLayout控件 2-3 FloatingActionButton控件 2-4 Snackbar控件 2-5 TabLayout控件 2-6 Navi ...

  7. Android Design Support Library 的 代码实验——几行代码,让你的 APP 变得花俏

    原文:Codelab for Android Design Support Library used in I/O Rewind Bangkok session--Make your app fanc ...

  8. Codelab for Android Design Support Library used in I/O Rewind Bangkok session

    At the moment I believe that there is no any Android Developer who doesn't know about Material Desig ...

  9. Material Design 开发利器:Android Design Support Library 介绍

    转自:https://blog.leancloud.cn/3306/ Android 5.0 Lollipop 是迄今为止最重大的一次发布,很大程度上是因为 material design —— 这是 ...

随机推荐

  1. CDialogBar(对话条)和CReBar(伸缩条)的编程

    对话条是工具栏和无模式对话框相结合的产物,对话条和对话框类似,包含有标准的Windows控件,并且可以通过创建对话框模板来表示对话条. 伸缩条功能很强大,我们可以在伸缩条中直接增加CToolBar,C ...

  2. Swift - 给表格添加Cell的显示动画(3D缩放)

    下面的一个样例是让tableView显示数据的时候具有一个很炫的3D缩放效果. 我们只需要实现tableView的willDisplayCell方法.看方法名就知道这是在Cell将要显示的时候执行的方 ...

  3. [知识库分享系列] 二、Web(高性能Web站点建设)

    知识库分享系列: [知识库分享系列] 二..NET(ASP.NET) [知识库分享系列] 一.开篇 分享介绍 此知识库之所以为 Web 系列,因为和 .NET 没有完全的关系,其中的技术和实践实用于各 ...

  4. 终于懂了:Delphi消息的Result域出现的原因——要代替回调函数的返回值!(MakeObjectInstance不会帮助处理(接收)消息回调函数的返回值)

    MakeObjectInstance应该不会帮助处理(接收)消息回调函数的返回值,可是有时候又确实需要这个返回值,这可怎么办呢?我是看到这段文字的时候,想到这个问题的: 当WM_PAINT不是由Inv ...

  5. adb 之android的神器am

    am命令,am全称activity manager,你能使用am去模拟各种系统的行为,例如去启动一个activity,强制停止进程,发送广播进程,修改设备屏幕属性等等 命令窗口通过adb shell ...

  6. 【Demo 0006】iOS常用控件

    本章学习要点       1.  了解iOS中控件继承关系:       2.  掌握UIControl基础知识;       3.  掌握UIButton基本用法:       4.  掌握UILa ...

  7. drupal进入不了后台时候的解决办法,作者使用drush方案,已验证

    drupal把正在用的主题不小心删了,怎么进后台? 方法一: 去variable表里把默认主题换了 方法二: ?q=user 登录到管理区,开启简洁连接使用user(网站根目录下面) admin/ap ...

  8. eclipse Maven plugin 配置

    1. eclipse -> help -> marketpalce -> search 在输入框中输入Maven,回车. 在搜索结果列表中往下拉几个安装 Maven Integrat ...

  9. xcode6 cocos2dx开玩笑git和github学习记录

    1. git Xcode4开始,它一直Git作为一个内置的源代码控制(Source Control)工具,所以对于新项目的用途git要管理非常方便.在新建项目向导.可以直接选择Git作为源控制工具.项 ...

  10. 所有CN_消息的说明

    Notification Message Corresponding WindowsConstant Message Description cn_CharToItem wm_CharToItem T ...