Android重构菜单类

时间:2014-05-06 09:16:02

标签: java android

我有一个Android应用程序的菜单类,我觉得我可以重构它,因为我实际上有相同的方法4次,请看下面:

public abstract class MenuActivity extends SherlockActivity {

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ActionBar ab = getSherlock().getActionBar();
    SherlockHelper.setupActionBar(ab, this);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    return createMenu(this, menu);
}

public static boolean createMenu(SherlockActivity aActivity, Menu menu){

    MenuInflater inflater = ((SherlockActivity) aActivity).getSupportMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);

    Intent i = new Intent((Context) aActivity, InstructionsActivity.class);
    i.putExtra("Flag", "firstInstructions");

    menu.findItem(R.id.hearing_test).setIntent(i);
    menu.findItem(R.id.learn).setIntent(new Intent((Context) aActivity, LearnActivity.class));
    menu.findItem(R.id.share).setIntent(new Intent((Context) aActivity, ShareActivity.class));
    menu.findItem(R.id.locate).setIntent(new Intent((Context) aActivity, MapActivity.class));
    menu.findItem(R.id.saved).setIntent(new Intent((Context) aActivity, SavedResultsActivity.class));
    return true;
}   

public static boolean createMenu(SherlockListActivity aActivity, Menu menu){

    MenuInflater inflater = aActivity.getSupportMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);

    Intent i = new Intent((Context) aActivity, InstructionsActivity.class);
    i.putExtra("Flag", "firstInstructions");

    menu.findItem(R.id.hearing_test).setIntent(i);
    menu.findItem(R.id.learn).setIntent(new Intent(aActivity, LearnActivity.class));
    menu.findItem(R.id.share).setIntent(new Intent(aActivity, ShareActivity.class));
    menu.findItem(R.id.locate).setIntent(new Intent(aActivity, MapActivity.class));
    menu.findItem(R.id.saved).setIntent(new Intent(aActivity, SavedResultsActivity.class));
    return true;
} 

public static boolean createMenu(SherlockFragmentActivity aActivity, Menu menu){

    MenuInflater inflater = aActivity.getSupportMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);

    Intent i = new Intent((Context) aActivity, InstructionsActivity.class);
    i.putExtra("Flag", "firstInstructions");

    menu.findItem(R.id.hearing_test).setIntent(i);
    menu.findItem(R.id.learn).setIntent(new Intent(aActivity, LearnActivity.class));
    menu.findItem(R.id.share).setIntent(new Intent(aActivity, ShareActivity.class));
    menu.findItem(R.id.locate).setIntent(new Intent(aActivity, MapActivity.class));
    menu.findItem(R.id.saved).setIntent(new Intent(aActivity, SavedResultsActivity.class));
    return true;
} 

public static boolean createMenu(SherlockFragment aActivity, Menu menu){

    MenuInflater inflater = aActivity.getSherlockActivity().getSupportMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);

    Intent i = new Intent((Context) aActivity.getSherlockActivity(), InstructionsActivity.class);
    i.putExtra("Flag", "firstInstructions");

    menu.findItem(R.id.hearing_test).setIntent(i);
    menu.findItem(R.id.learn).setIntent(new Intent(aActivity.getSherlockActivity(), LearnActivity.class));
    menu.findItem(R.id.share).setIntent(new Intent(aActivity.getSherlockActivity(), ShareActivity.class));
    menu.findItem(R.id.locate).setIntent(new Intent(aActivity.getSherlockActivity(), MapActivity.class));
    menu.findItem(R.id.saved).setIntent(new Intent(aActivity.getSherlockActivity(), SavedResultsActivity.class));
    return true;
}    
}

我想改变这个,所以我只有一种方法而不是四种!要做到这一点,我假设我传入了一个通用对象,但我实际上并不知道要传递什么!我是否需要将方法更改为动态方法而不是静态方法?

对此的任何帮助将不胜感激。非常感谢

2 个答案:

答案 0 :(得分:-1)

您只需Context即可在所有方法的正文中创建所需内容。

在一个以Context为参数的方法中提取相同的comde,以便您可以根据需要多次调用此方法。

public static boolean createMenu(Context context, Menu menu) {
    // Here is your code that use context
}

public static boolean whateverMethodYouWant(WhatEverClass smth, Menu menu) {
    // Get/cast or smth else to get Context from smth.
    Context context = castOrExtractContext(smth);
    return createMenu(context, menu);
}

在这种情况下它是无错误的代码,因为你处理了有关用户传递给你的WhatEverClass的所有内容,而且他不知道你在方法中执行了什么。

答案 1 :(得分:-1)

好吧,既然你有两种不同的答案,我可以告诉你差异以及何时使用它。

首先,当您想要组合成多个方法时,您想要做的是想要找到公分母。也就是说,所有方法都有共同之处。

要查找公分母,请检查要转换为一个方法的方法。

public static boolean createMenu(SherlockActivity aActivity, Menu menu){

    MenuInflater inflater = ((SherlockActivity) aActivity).getSupportMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);

    Intent i = new Intent((Context) aActivity, InstructionsActivity.class);
    i.putExtra("Flag", "firstInstructions");

    menu.findItem(R.id.hearing_test).setIntent(i);
    menu.findItem(R.id.learn).setIntent(new Intent((Context) aActivity, LearnActivity.class));
    menu.findItem(R.id.share).setIntent(new Intent((Context) aActivity, ShareActivity.class));
    menu.findItem(R.id.locate).setIntent(new Intent((Context) aActivity, MapActivity.class));
    menu.findItem(R.id.saved).setIntent(new Intent((Context) aActivity, SavedResultsActivity.class));
    return true;
}

从这个方法中有两个从参数创建的对象; MenuInflater inflater (上下文)aActivity 。可以从Activity中的方法访问MenuInflater,并从Activity中转换Context。因此,为活动提供新的(组合)方法将为新方法提供足够的信息,以便能够完成其他四个方法所做的工作。

当你找到共同点时,有两种情况:

  1. 参数已经包含所有公分母
  2. 参数没有所有公分母
  3. 第一种情况的解决方案:

    您知道所有课程都可以访问活动。因此,您让新方法将一个Activity和一个Menu作为参数:

    public static boolean createMenu(Activity aActivity, Menu menu){
    
        MenuInflater inflater = aActivity.getSupportMenuInflater();
        inflater.inflate(R.menu.main_menu, menu);
    
        Intent i = new Intent((Context) aActivity, InstructionsActivity.class);
        i.putExtra("Flag", "firstInstructions");
    
        menu.findItem(R.id.hearing_test).setIntent(i);
        menu.findItem(R.id.learn).setIntent(new Intent((Context) aActivity, LearnActivity.class));
        menu.findItem(R.id.share).setIntent(new Intent((Context) aActivity, ShareActivity.class));
        menu.findItem(R.id.locate).setIntent(new Intent((Context) aActivity, MapActivity.class));
        menu.findItem(R.id.saved).setIntent(new Intent((Context) aActivity, SavedResultsActivity.class));
        return true;
    }
    

    现在其他四种方法可以调用这个方法。

    public static boolean createMenu(SherlockActivity aActivity, Menu menu){
        return createMenu((Activity) aActivity, menu); // Explicitly call method with Activity as argument
    }
    
    public static boolean createMenu(SherlockListActivity aActivity, Menu menu){
        return createMenu((Activity) aActivity, menu); // Explicitly call method with Activity as argument
    } 
    
    public static boolean createMenu(SherlockFragmentActivity aActivity, Menu menu){
        return createMenu((Activity) aActivity, menu); // Explicitly call method with Activity as argument
    } 
    
    public static boolean createMenu(SherlockFragment aActivity, Menu menu){
            return createMenu(aActivity.getSherlockActivity(), menu); // Explicitly call method with Activity as argument
    }     
    

    第二种情况的解决方案:

    假设并非所有四个类都扩展Activity或者可以转换为Context。然后我们需要一种方法来告诉新方法如何从我们提供的类访问Activity和Context。为此,我们使用接口。该接口有许多方法,它们明确告诉实现此接口的类可以提供接口所承诺的信息(当然,只要类实现是正确的)。

    public interface SherlockInterface {
        public Activity getActivity();
    }
    

    现在,您让所有类都实现此接口如何类实现接口方法取决于它们,但不知何故,它们必须提供这些方法。

    您的新方法知道它可以使用SherlockInterface(因为它提供了一个Activity)。

    public static boolean createMenu(SherlockInterface iface, Menu menu){
    
        Activity aActivity = iface.getActivity();
        MenuInflater inflater = aActivity.getSupportMenuInflater();
        inflater.inflate(R.menu.main_menu, menu);
    
        Intent i = new Intent((Context) aActivity, InstructionsActivity.class);
        i.putExtra("Flag", "firstInstructions");
    
        menu.findItem(R.id.hearing_test).setIntent(i);
        menu.findItem(R.id.learn).setIntent(new Intent((Context) aActivity, LearnActivity.class));
        menu.findItem(R.id.share).setIntent(new Intent((Context) aActivity, ShareActivity.class));
        menu.findItem(R.id.locate).setIntent(new Intent((Context) aActivity, MapActivity.class));
        menu.findItem(R.id.saved).setIntent(new Intent((Context) aActivity, SavedResultsActivity.class));
        return true;
    }
    

    由于所有类都实现了接口,因此java将调用此方法,并且只有一个方法而不是四个方法。

    希望这个解释有所帮助!