我的代码中有这样的内容:
switch (item.getItemId()) {
case R.id.search:
if (currentFragment == null || !(currentFragment instanceof ClipsFragment)) {
ClipsFragment clipsFragment = new ClipsFragment();
fragmentTransaction.replace(R.id.container,
clipsFragment).commit();
currentFragment = clipsFragment;
} else {
fragmentTransaction.replace(R.id.container,
currentFragment).commit();
}
currentDrawerItem = R.id.search;
return true;
case R.id.download_managers:
if (currentFragment == null || !(currentFragment instanceof DownloadFragment)) {
DownloadFragment downloadFragment = new DownloadFragment();
fragmentTransaction.replace(R.id.container,
downloadFragment).commit();
currentFragment = downloadFragment;
} else {
fragmentTransaction.replace(R.id.container,
currentFragment).commit();
}
currentDrawerItem = R.id.search;
return true;
default:
return false;
}
正如您所看到的,有两种类似的开关情况
有没有办法将它们转换为使用Java 7的方法?
我尝试了一下,但instanceof
很棘手
我的所有尝试都不值得在这里发布。
注意:Fragment
和DownloadFragment
延长Fragment
。
答案 0 :(得分:1)
他们都扩展了片段
好的,那么除了创建实例之外,您还需要使用特定的子类。只需将当前的Fragment声明为那些新实例。
这对你来说更干净吗?
boolean handled = true;
switch (item.getItemId()) {
case R.id.search:
if (currentFragment == null || !(currentFragment instanceof ClipsFragment)) {
currentFragment = new ClipsFragment();
}
break;
case R.id.download_managers:
if (currentFragment == null || !(currentFragment instanceof DownloadFragment)) {
currentFragment = new DownloadFragment();
}
break;
default:
handled = false;
}
if (currentFragment != null) {
fragmentTransaction.replace(R.id.container,
currentFragment).commit();
}
if (handled) {
currentDrawerItem = item.getItemId();
}
return handled;
答案 1 :(得分:0)
正如您所看到的,有两种类似的开关案例。我能以任何方式 将它们转换为使用Java 7的方法?我尝试了一下但是 instanceof很棘手。
为了避免切换案例并通过直接方法调用替换它们,您可以使用对象和多态。 在您的情况下,您可以使用方法引入接口:
public interface Processing{
Fragment doProcess();
}
你可以有两个这样的实现(根据代码中的项目ID):
DownloadManagerProcessing
ReadProcessing
然后,您可以使用返回方便Processing
实例的工厂:
public ProcessingFactory{
..
Map<Integer, Processing> processingByItemId;
..
public Processing getProcessing(int itemId){
return processingByItemId.get(itemId);
}
..
}
你切换案例:
switch (item.getItemId()) {
case R.id.search:
...
case R.id.download_managers:
...
default:
return false;
}
将替换为:
Processing processing = ProcessingFactory.getProcessing(itemId);
if (processing==null){
return false;
}
Fragment fragment = processing.doProcess();
return true;
在这个解决方案中,我们总是依赖于itemId,但是将它们与处理相关联的工作是孤立的 因此,如果需要,您可以依赖itemId在工厂中添加其他类型的处理,而无需担心其映射。
编辑(从清洁代码开始实施)
从cricket_007没有强重复的代码开始,你可以再次使用方法来避免切换案例。 在此版本中,您可以使用工厂检索ItemId的匹配实例:
public FragmentFactory{
..
..
public Fragment createInstanceIfNeeded(Fragment currentFragment, int itemId){
if(itemId ==...){
if (!(currentFragment instanceof ClipsFragment)) {
return new ClipsFragment();
}
}
else if(itemId == ..){
if (!(currentFragment instanceof DownloadFragment)) {
return new DownloadFragment();
}
}
return currentFragment;
}
..
}
在您的情况下需要instanceof
,因为如果不符合您的预期,您希望更改实施。如果你想避免它,你应该在Fragment中有一个公共方法getType()
,它返回一个String或一个Enum,它将由每个子类实现。
但在某种程度上它是instanceof
之类的。
并在您的客户端代码中执行:
currentFragment = FragmentFactory.createInstanceIfNeeded(item.getItemId());
if (currentFragment==null){
return false;
}
fragmentTransaction.replace(R.id.container,
currentFragment).commit();
currentDrawerItem = item.getItemId();
return true;
就个人而言,我不喜欢使用开关盒。我发现它容易出错。