简体   繁体   中英

How to use switch case with string resources

How can I use the switch case scenario with string resources rather than hard coded names? My strings are exactly the same names used for the spellings of them.

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            MainListAdapter adapter = (MainListAdapter) parent.getAdapter();
            Main continent = adapter.getItem(position);
               if (mTwoPane) {
                    View rowView = view;
                    setItemSelected(continent, rowView);

                    Fragment newFragment;
                    switch (stringRes) {
                        case R.id.africa:
                            newFragment = new FragmentAfrica();
                            break;
                        case R.id.asia:
                            newFragment = new FragmentAsia();
                            break;
                        case R.id.europe:
                            newFragment = new FragmentEurope();
                            break;
                        default:
                            newFragment = new FragmentAfrica();
                    }

                    MainActivity activity = (MainActivity) view.getContext();
                    FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
                    transaction.replace(R.id.detail_container, newFragment);
                    transaction.commit();
                } else {
              }

Switch labels (that's the "africa" in case "africa": ) must be constant expressions according to JLS § 14.12 . So if you want to use switch , you'll have to store the string resource value in a constant variable and then use that constant as the switch label.

Example (use either class constants or local constants):

class Example {
  public static final String CONTINENT_EUROPE =
      getResources().getString(R.string.europe);  // Option 1: class constants
  public static final String CONTINENT_NORTHERN_AMERICA =
      getResources().getString(R.string.northernAmerica);

  public void foo() {
    final String continentAfrica =
        getResources().getString(R.string.africa);  // Option 2: local constants
    final String continentAsia =
        getResources().getString(R.string.asia);
    switch (continent) {
    // Option 1:
    case continentAfrica:
      newFragment = new FragmentAfrica();
      break;
    case continentAsia:
      newFragment = new FragmentAsia();
      break;
    // Option 2:
    case CONTINENT_EUROPE:
      newFragment = new FragmentEurope();
      break;
    case CONTINENT_NORTHERN_AMERICA:
      newFragment = new FragmentNorthernAmerica();
      break;
    // ...
  }
}

Looks like this could work.. use integers.

public void switchFragments(int stringRes){
    if (mTwoPane) {
                View rowView = view;
                setItemSelected(continent, rowView);

                Fragment newFragment;
                switch (stringRes) {
                    case R.id.africa:
                        newFragment = new FragmentAfrica();
                        break;
                    case R.id.asia:
                        newFragment = new FragmentAsia();
                        break;
                    case R.id.europe:
                        newFragment = new FragmentEurope();
                        break;
                    default:
                        newFragment = new FragmentAfrica();
                }

                MainActivity activity = (MainActivity) view.getContext();
                FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
                transaction.replace(R.id.detail_container, newFragment);
                transaction.commit();
            }
}

Now all you have to do is call it like this

switchFragments(R.id.africa);

This will go to the case labeled R.id.africa and switch the fragment. It will also work with different languages, because its just an ID of a resource.

I think in this scenario the simplest way is you can just use "simple if else statement" to avoid declaring extra static variables. And also to add support on locale changes.

private String[] titles;

void initialize(){
    titles = new String[]{getString(R.string.europe),getString(R.string.africa)};
}

@Override
public Fragment getItem(int position) {

    String title = titles[position];

    if (title.equals(getString(R.string.europe))) {
        return new EuropeFragment();
    } else if (title.equals(getString(R.string.africa))) {
        return new AfricaFragment();
    } else {
        return new DefaultFragment();
    }
}

Just declare them as constants like this:

public static final String COUNTRY_AFRICA = "africa";
public static final String COUNTRY_ASIA = "asia";

switch (country.toLowerCase()) {
    case COUNTRY_AFRICA:
         newFragment = new FragmentAfrica();
         break;
    // etc..

This is better than hardcoding because you will be able to reuse these constants across the app.

If those are UI strings you can declare them in strings.xml

You should declare it as an enum:

public enum Continent{
    africa, asia, europe
}

public Fragment getFragment(String continentKey){
    Continent continent = Continent.valueOf(continentKey);
    return getFragment(continent);
}

public Fragment getFragment(Continent aContinent){
    Fragment newFragment;
    switch(aContinent){
        case asia:
            newFragment = new FragmentAsia();
            break;
        case europe:
            newFragment = new FragmentEurope();
            break;
        case africa: default:
            newFragment = new FragmentAfrica();
            break;
    }
    return newFragment;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM