Xamarin.Android中使用ResideMenu实现侧滑菜单
2014-12-28 22:45
686 查看
上次使用Xamarin.Android实现了一个比较常用的功能PullToRefresh,详情见:Xamarin. Android实现下拉刷新功能
这次将实现另外一个手机App中比较常用的功能:侧滑菜单。通过搜索,发现有很多侧滑菜单,有仿手机QQ的侧滑菜单,有折叠的侧滑菜单,有SlidingMenu等,不过我还是比较喜欢 ResideMenu实现的效果,所以想通过Xamarin.Android的绑定实现该效果。这次实现该菜单遇到的问题比较多,花的时间也较多,花了三四个晚上才解决所有的问题。下面是详细的实现步骤:
作者:loyldg 出处:http://www.cnblogs.com/loyldg/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。如有问题,可以邮件:loyldg@126.com 联系我,非常感谢。
一、生成ResideMenu.dll
从网上下载ResideMenu的源代码,我是下载的master分支的代码,如果有需要可以下载其他分支的代码。
导入到MyEclispe中,编译一下(默认情况导入后会自动编译)。
打开ResideMenu所在的目录,将res目录和生成的bin目录里的内容打包成residemenu.zip。
在Visual Studio中新建一个Android Binding 项目,命名为ResideMenuLib。
在ResideMenuLib项目的Jars目录里添加residemenu.zip和nineoldandroids-library-2.4.0.jar(在ResideMenu项目的libs目录里),将residemenu.zip的生成操作设置为LibraryProjectZip,nineoldandroids-library-2.4.0.jar的生成操作设置为ReferenceJar,注意是ReferenceJar而不是EmbeddedReferenceJar。
编译ResideMenuLib项目。
二、使用ResideMenu
普通方式使用就不贴代码了,简单描述一下使用步骤,详细的代码请看Mvvmcross中使用ResideMenu
在Visual Studio中新建ResideMenuDemo项目。
分别添加对ResideMenuLib和NineOldAndroids的引用,NineOldAndroids直接引用Nuget里面的就ok,否则需要重新绑定NineOldAndroids,然后添加引用。
将Java的ResideMenuDemo(与ResideMenu在同一目录)转换为C#的即可。
编译C#版的ResideMenuDemo,然后运行。
三、MvvmCross中使用ResideMenu
其实在MvvmCross中使用ResideMenu和普通方式使用差不多,只是MvvmCross中需要设置对应的ViewModel。需要注意的是,使用低版本SDK时需要引用Xamarin.Android.Support.v4.dll,下面是具体的步骤:
新建一个可以移植的类库项目MvxResideMenu.Core,通过Nuget添加对MvvmCross的引用
添加ViewModel的代码
新建Android项目MvxResideMenu.Droid,删除自动生成的MainActivity,通过Nuget添加对MvvmCross和NineOldAndroids的引用
编写对应的View和相关布局代码
编译并运行
下面是代码:
ViewModel的代码:
View Code
运行效果如下:
四、遇到的问题以及总结
1.现象:绑定的ResideMenu对象的MenuListener属性只有get方法,没有set方法,不能设置值。
原因:不太清楚,知道的朋友可以说一下。我的理解是set方法引用了R.java里的内容,而R.java生成的时间晚于绑定代码的生成,所以导致了找不到引用的问题。
解决方法:在Metadata.xml文件里增加下面的代码,手动增加一个方法。
2.现象:编译能够通过,运行时报Java.Lang.NullPointerException异常
at com.special.ResideMenu.ResideMenu.setBackground(ResideMenu.java:143),通过跟踪发现要设置背景的对象为空,所以导致了空引用异常。
原因:residemenu.jar文件内包含了R.java的代码,最开始我是手动导出的residemenu.jar,将R.java的代码一起导出了。这样会导致ResideMenu类里的所有findViewById方法返回null,解决这个问题花的时间最长,差不多过了两天才发现。
解决方法:residemenu.jar文件里不要包含R.java的代码。
3.现象:编译能够通过,运行时报Java.Lang.NoClassDefFoundError: com.special.ResideMenu.ResideMenu$2异常
原因:查看Visual Studio的Output窗口,可以发现如下信息:
Failed resolving Lcom/special/ResideMenu/ResideMenu$2; interface 264 'Lcom/nineoldandroids/animation/Animator$AnimatorListener;',通过提示,我们发现错误原因是不能解析nineoldandroids.jar里的Animator.AnimatorListener接口
解决方法:在Nuget里添加NineOldAndroids的引用。这里有一点还没弄明白,ResideMenuLib项目已经包含了引用的NineOldAndroids.jar,正常情况下应该不需要再次添加引用了。
4.现象:运行时滑动界面无法显示侧滑菜单
原因:未重写DispatchTouchEvent方法
解决方法:添加如下代码即可
5.MvvmCross中使用ResideMenu稍微有一点问题,每次切换Fragment时需要手动指定Fragment的ViewModel。如果需要实现ViewModel的单例,还需要额外处理,并且ViewModel的构造函数带有注入参数时,处理起来更麻烦。
6.网上也有ResideMenu的绑定,见https://github.com/nishanil/XResideMenu ,本来我是想直接用这个绑定好的ResideMenu的,但是我用最新的java版residemenu生成的代码替换此绑定里ResideMenu.aar对应的文件后,重新生成后的dll还是有问题,所以就重新绑定了一个。网上这个库也说了绑定的时候有点问题,他给出了两种解决方案:
1)将java库的package从大写修改为小写,并将AndroidManifest.xml文件里的名称也修改为小写,然后重新编译
2)手动修改VS生成的R.java文件里的package名称,然后重新运行就可以了,修改之后不能重新生成和清理解决方案
上面说的问题只存在于monodroid-4.18以前的版本,4.18之后已修复了大小写问题的BUG
7.最近绑定了一些java的库,有时间我整理一下发出来。
作者:loyldg 出处:http://www.cnblogs.com/loyldg/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。如有问题,可以邮件:loyldg@126.com 联系我,非常感谢。
这次将实现另外一个手机App中比较常用的功能:侧滑菜单。通过搜索,发现有很多侧滑菜单,有仿手机QQ的侧滑菜单,有折叠的侧滑菜单,有SlidingMenu等,不过我还是比较喜欢 ResideMenu实现的效果,所以想通过Xamarin.Android的绑定实现该效果。这次实现该菜单遇到的问题比较多,花的时间也较多,花了三四个晚上才解决所有的问题。下面是详细的实现步骤:
作者:loyldg 出处:http://www.cnblogs.com/loyldg/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。如有问题,可以邮件:loyldg@126.com 联系我,非常感谢。
一、生成ResideMenu.dll
从网上下载ResideMenu的源代码,我是下载的master分支的代码,如果有需要可以下载其他分支的代码。
导入到MyEclispe中,编译一下(默认情况导入后会自动编译)。
打开ResideMenu所在的目录,将res目录和生成的bin目录里的内容打包成residemenu.zip。
在Visual Studio中新建一个Android Binding 项目,命名为ResideMenuLib。
在ResideMenuLib项目的Jars目录里添加residemenu.zip和nineoldandroids-library-2.4.0.jar(在ResideMenu项目的libs目录里),将residemenu.zip的生成操作设置为LibraryProjectZip,nineoldandroids-library-2.4.0.jar的生成操作设置为ReferenceJar,注意是ReferenceJar而不是EmbeddedReferenceJar。
编译ResideMenuLib项目。
二、使用ResideMenu
普通方式使用就不贴代码了,简单描述一下使用步骤,详细的代码请看Mvvmcross中使用ResideMenu
在Visual Studio中新建ResideMenuDemo项目。
分别添加对ResideMenuLib和NineOldAndroids的引用,NineOldAndroids直接引用Nuget里面的就ok,否则需要重新绑定NineOldAndroids,然后添加引用。
将Java的ResideMenuDemo(与ResideMenu在同一目录)转换为C#的即可。
编译C#版的ResideMenuDemo,然后运行。
三、MvvmCross中使用ResideMenu
其实在MvvmCross中使用ResideMenu和普通方式使用差不多,只是MvvmCross中需要设置对应的ViewModel。需要注意的是,使用低版本SDK时需要引用Xamarin.Android.Support.v4.dll,下面是具体的步骤:
新建一个可以移植的类库项目MvxResideMenu.Core,通过Nuget添加对MvvmCross的引用
添加ViewModel的代码
新建Android项目MvxResideMenu.Droid,删除自动生成的MainActivity,通过Nuget添加对MvvmCross和NineOldAndroids的引用
编写对应的View和相关布局代码
编译并运行
下面是代码:
ViewModel的代码:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:local="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="40dp" local:MvxBind="Text Hello" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="40dp" local:MvxBind="Text Hello" /> </LinearLayout>
View Code
运行效果如下:
四、遇到的问题以及总结
1.现象:绑定的ResideMenu对象的MenuListener属性只有get方法,没有set方法,不能设置值。
原因:不太清楚,知道的朋友可以说一下。我的理解是set方法引用了R.java里的内容,而R.java生成的时间晚于绑定代码的生成,所以导致了找不到引用的问题。
解决方法:在Metadata.xml文件里增加下面的代码,手动增加一个方法。
<add-node path="/api/package[@name='com.special.ResideMenu']/class[@name='ResideMenu']"> <method name="setMenuListener" return="void" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="listener" type="com.special.ResideMenu.ResideMenu.OnMenuListener"/> </method> </add-node>
2.现象:编译能够通过,运行时报Java.Lang.NullPointerException异常
at com.special.ResideMenu.ResideMenu.setBackground(ResideMenu.java:143),通过跟踪发现要设置背景的对象为空,所以导致了空引用异常。
原因:residemenu.jar文件内包含了R.java的代码,最开始我是手动导出的residemenu.jar,将R.java的代码一起导出了。这样会导致ResideMenu类里的所有findViewById方法返回null,解决这个问题花的时间最长,差不多过了两天才发现。
解决方法:residemenu.jar文件里不要包含R.java的代码。
3.现象:编译能够通过,运行时报Java.Lang.NoClassDefFoundError: com.special.ResideMenu.ResideMenu$2异常
原因:查看Visual Studio的Output窗口,可以发现如下信息:
Failed resolving Lcom/special/ResideMenu/ResideMenu$2; interface 264 'Lcom/nineoldandroids/animation/Animator$AnimatorListener;',通过提示,我们发现错误原因是不能解析nineoldandroids.jar里的Animator.AnimatorListener接口
解决方法:在Nuget里添加NineOldAndroids的引用。这里有一点还没弄明白,ResideMenuLib项目已经包含了引用的NineOldAndroids.jar,正常情况下应该不需要再次添加引用了。
4.现象:运行时滑动界面无法显示侧滑菜单
原因:未重写DispatchTouchEvent方法
解决方法:添加如下代码即可
public override bool DispatchTouchEvent(MotionEvent ev) { return _resideMenu.DispatchTouchEvent(ev); }
5.MvvmCross中使用ResideMenu稍微有一点问题,每次切换Fragment时需要手动指定Fragment的ViewModel。如果需要实现ViewModel的单例,还需要额外处理,并且ViewModel的构造函数带有注入参数时,处理起来更麻烦。
6.网上也有ResideMenu的绑定,见https://github.com/nishanil/XResideMenu ,本来我是想直接用这个绑定好的ResideMenu的,但是我用最新的java版residemenu生成的代码替换此绑定里ResideMenu.aar对应的文件后,重新生成后的dll还是有问题,所以就重新绑定了一个。网上这个库也说了绑定的时候有点问题,他给出了两种解决方案:
1)将java库的package从大写修改为小写,并将AndroidManifest.xml文件里的名称也修改为小写,然后重新编译
2)手动修改VS生成的R.java文件里的package名称,然后重新运行就可以了,修改之后不能重新生成和清理解决方案
上面说的问题只存在于monodroid-4.18以前的版本,4.18之后已修复了大小写问题的BUG
7.最近绑定了一些java的库,有时间我整理一下发出来。
作者:loyldg 出处:http://www.cnblogs.com/loyldg/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。如有问题,可以邮件:loyldg@126.com 联系我,非常感谢。
相关文章推荐
- 使用AndroidResideMenu开源框架实现QQ5.0侧滑菜单
- Android 使用DrawerLayout快速实现侧滑菜单
- Android使用ViewDragHelper实现侧滑菜单(一)
- Android程序开发之使用Design包实现QQ动画侧滑效果和滑动菜单导航
- [AndroidUI]使用DrawerLayout实现侧滑菜单
- android 使用drawerLayout实现侧滑菜单
- Android开发——使用高级的RecyclerView实现侧滑菜单删除功能(SwipeRecyclerView)
- Android使用DrawerLayout实现仿QQ双向侧滑菜单
- Android使用DrawerLayout实现侧滑菜单效果
- Android使用DrawerLayout实现双向侧滑菜单
- Android Material Design系列之使用Toolbar + DrawerLayout实现高侧滑菜单
- Android新手轻松学知乎日报开发(四)使用Toolbar + DrawerLayout实现菜单侧滑
- Android使用DrawerLayout实现抽屉式侧滑菜单
- Android使用DrawerLayout和ToolBar实现仿知乎侧滑菜单
- android 使用DrawerLayout实现侧滑菜单
- Android:使用Toolbar + DrawerLayout快速实现菜单侧滑
- Android 侧滑菜单实现
- Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现
- Android高手进阶篇4-实现侧滑菜单框架,一分钟集成到项目中
- Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现