这次的任务对我来说并不容易,因为这是对软件的一小部分结构进行更改:
在原版的Seadroid里左侧有一个抽屉栏,用来切换文件(Files)、上传任务(UploadTasks)以及账户(Accounts)。而现在要做的就是把抽屉去掉,把上传任务(UploadTasks)和账户(Accounts)放入ActionBar的menu里。为了能有一个清晰地层级,和林导师商量后决定把上传任务(UploadTasks)和账户(Accounts)都设成Activity,当用户选择时弹出一个新的界面,并在左侧的ActionBar加入返回键。
账户(Accounts)最初就是用Activity写的,所以改动的基本上就是在左上角添加ActionBar的返回按钮即可。代码也很简单,如下:
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
同时还要记得重写onOptionsItemSelected():
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
this.finish();
default:
return super.onOptionsItemSelected(item);
}
}
但是这样并不能解决所有问题。Google是在Android 3.0之后才提出的ActionBar,也就意味着在3.0以下的版本直接这样写是不行的。好在有前辈们写的开源项目 actionbarsherlock使得这么方便的工具得以在Android 2+上使用。当然除了要把actionbarsherlock(ABS)当做Library import外,代码也有所改动:
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
这样就会万事大吉了吗?只能说还差一些,下面就是把我折腾很久的元凶:
因为需求,在Accounts里加了两个函数:onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)和onContextItemSelected(MenuItem item)
所以要import安卓原生的一些library
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
但是,因为我们使用了ActionBarSherlock,为了能让它完全运行,必须要import ABS的一些library
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
简单比较就会发现,*.view.MenuInflater和*.view.MenuItem会起冲突。
虽然ABS也提供了onCreateContextMenu和onContextItemSelected函数,参数类型基本上一样或是可以转换,但是鱼唇的Android竟相互之间无法识别(捂脸...
举个栗子:
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.account_menu, menu);
}
这是段错误的代码。因为我们import了ABS的library,所以MenuInflater是ABS的MenuInflater,而getMenuInflater()返回值是安卓原生的MenuInflater,报错..
在网上搜了下解决办法,可以把getMenuInflater();变为ABS提供的类似的函数getSupportMenuInflater(); 如下:
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.account_menu, menu);
}
这样会解决问题吗..报错:最后一句的menu不能从ContextMenu转换为Menu
因为我们用了ABS的函数,所以inflater是ABS中的MenuInflater。 这是函数原型:inflater.inflate(int menuRes, Menu menu);。在整个函数段中,menu是ContextMenu类型,而inflate(int menuRes, Menu menu)需要的是Menu类型,若是安卓原生的MenuInflater可以强制转换,但如果是ABS的MenuInflater,对不起,Android不认!(捂脸...
不过好在国外有一些前辈替我们躺了浑水,经过一下午的努力终于在stackoverflow的一个角落里找到了解决办法:
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
android.view.MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.account_menu, menu);
}
相似的还有一些,再比如这样写..
public boolean onContextItemSelected(android.view.MenuItem item)
原来还可以这样,小白吓傻了...
最后:虽然ABS目前还存在一些BUG,导致像我这样的小白生不如死,但还是衷心地感谢这些为开源工作的大前辈们!(嗯..我也在为开源工作 = =||