Using ActionBarSherlock With the New SupportMapFragment

前端 未结 6 462
闹比i
闹比i 2020-11-28 03:30

I am looking at using ActionbarSherlock but have one query that\'s holding me back.

So my application needs to be fully backwards compatible to API Level 7.

相关标签:
6条回答
  • 2020-11-28 03:50

    It all works like a charm, mainly thanks to Jake's great work on ActionBarSherlock

    Here are the steps I followed:

    1. Create a SherlockMapFragment class in your actiobarsherlock library project. I simply made a copy of SherlockFragment because I also needed support for setHasOptionsMenu(true)
    2. The activity extends SherlockFragmentActivity (as usual)
    3. The fragment extends the newly created SherlockMapFragment
    4. ActionBarSherlock requires the new google-play-services_lib library
    5. Your project requires the ActionBarSherlock library. No need to include the google-play-services again, or to build against Google API.
    6. As mentionned by Graham, you have to drop support for API 7 devices: <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />

    And here's some code for a more detailed explanation:

    SherlockMapFragment

    package com.actionbarsherlock.app;
    
    import com.actionbarsherlock.internal.view.menu.MenuItemWrapper;
    import com.actionbarsherlock.internal.view.menu.MenuWrapper;
    import com.actionbarsherlock.view.Menu;
    import com.actionbarsherlock.view.MenuInflater;
    import com.actionbarsherlock.view.MenuItem;
    import com.google.android.gms.maps.SupportMapFragment;
    
    import android.app.Activity;
    import android.support.v4.app.Watson.OnCreateOptionsMenuListener;
    import android.support.v4.app.Watson.OnOptionsItemSelectedListener;
    import android.support.v4.app.Watson.OnPrepareOptionsMenuListener;
    
    public class SherlockMapFragment extends SupportMapFragment
            implements OnCreateOptionsMenuListener,
            OnPrepareOptionsMenuListener,
            OnOptionsItemSelectedListener {
        private SherlockFragmentActivity mActivity;
    
        public SherlockFragmentActivity getSherlockActivity() {
            return mActivity;
        }
    
        @Override
        public void onAttach(Activity activity) {
            if (!(activity instanceof SherlockFragmentActivity)) {
                throw new IllegalStateException(getClass().getSimpleName()
                        + " must be attached to a SherlockFragmentActivity.");
            }
            mActivity = (SherlockFragmentActivity) activity;
    
            super.onAttach(activity);
        }
    
        @Override
        public void onDetach() {
            mActivity = null;
            super.onDetach();
        }
    
        @Override
        public final void onCreateOptionsMenu(android.view.Menu menu, android.view.MenuInflater inflater) {
            onCreateOptionsMenu(new MenuWrapper(menu), mActivity.getSupportMenuInflater());
        }
    
        @Override
        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
            // Nothing to see here.
        }
    
        @Override
        public final void onPrepareOptionsMenu(android.view.Menu menu) {
            onPrepareOptionsMenu(new MenuWrapper(menu));
        }
    
        @Override
        public void onPrepareOptionsMenu(Menu menu) {
            // Nothing to see here.
        }
    
        @Override
        public final boolean onOptionsItemSelected(android.view.MenuItem item) {
            return onOptionsItemSelected(new MenuItemWrapper(item));
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Nothing to see here.
            return false;
        }
    }
    

    The activity:

    public class MainActivity extends SherlockFragmentActivity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    }
    

    The activity XML layout:

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/root"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >
    
        <fragment
            android:id="@+id/fragment_map"
            android:name=".ui.fragments.MapFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:tag="tag_fragment_map" />
    
        <fragment
            android:id="@+id/fragment_help"
            android:name=".ui.fragments.HelpFragment"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:tag="tag_fragment_help" />
    </FrameLayout>
    

    The map fragment:

    public class MapFragment extends SherlockMapFragment {
        private GoogleMap mMap;
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View root = super.onCreateView(inflater, container, savedInstanceState);
            mMap = getMap();
            return root;
        }
    }
    
    0 讨论(0)
  • 2020-11-28 03:52
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // toggle mapType
        if (mapFragment != null) {
            googleMap = mapFragment.getMap();
        }
        switch (item.getItemId()) {
        case R.id.action_normal:
            googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
            Toast.makeText(getActivity(), "normal", Toast.LENGTH_LONG).show();
            return true;
        case R.id.action_satellite:
            googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
            Toast.makeText(getActivity(), "satellite", Toast.LENGTH_LONG)
                    .show();
            return true;
        case R.id.action_terrian:
            googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
            Toast.makeText(getActivity(), "terian", Toast.LENGTH_LONG).show();
            return true;
        case R.id.action_hybrid:
            googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
            Toast.makeText(getActivity(), "hybrid", Toast.LENGTH_LONG).show();
            return true;
        default:
    
            return super.onOptionsItemSelected(item);
        }
    }
    
    0 讨论(0)
  • 2020-11-28 03:56

    I can't comment everywhere yet, that's why I answer @sureshcheemalamudi If you are trying to implement it on a Fragment, or SherlockFragment, take a look at this: https://stackoverflow.com/a/17803561/1755300

    0 讨论(0)
  • 2020-11-28 03:58

    I tried implementing SupportMapFragment with ActionBarSherlock.

    It is working very fine.

    enter image description here

    Below is code snippet.

    package com.example.newmapview;
    
    import android.os.Bundle;
    import android.widget.Toast;
    import com.actionbarsherlock.app.SherlockFragmentActivity;
    import com.actionbarsherlock.view.Menu;
    import com.actionbarsherlock.view.MenuItem;
    import com.actionbarsherlock.view.SubMenu;
    import com.google.android.gms.maps.GoogleMap;
    import com.google.android.gms.maps.SupportMapFragment;
    
    public class MainActivity extends SherlockFragmentActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            SupportMapFragment fragment = SupportMapFragment.newInstance();
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.mapLayout, fragment).commit();
    
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
    
            SubMenu subMenu = menu.addSubMenu("Type");
    
            subMenu.add("Normal");
            subMenu.add("SATELLITE");
    
            subMenu.getItem().setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
    
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
    
            if (item.getTitle().toString().equalsIgnoreCase("Normal")) {
                Toast.makeText(this, "Clicked Normal", Toast.LENGTH_LONG).show();
                GoogleMap googleMap = ((SupportMapFragment) getSupportFragmentManager()
                        .findFragmentById(R.id.mapLayout)).getMap();
    
                if (googleMap != null)
                    googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                else
                    Toast.makeText(this, "GoogleMap is null", Toast.LENGTH_LONG)
                            .show();
            } else if (item.getTitle().toString().equalsIgnoreCase("SATELLITE")) {
                Toast.makeText(this, "Clicked SATELLITE", Toast.LENGTH_LONG).show();
                GoogleMap googleMap = ((SupportMapFragment) getSupportFragmentManager()
                        .findFragmentById(R.id.mapLayout)).getMap();
    
                if (googleMap != null)
                    googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
                else
                    Toast.makeText(this, "GoogleMap is null", Toast.LENGTH_LONG)
                            .show();
            }
    
            return true;
    
        }
    }
    

    Hope this will help.

    0 讨论(0)
  • 2020-11-28 04:02

    Basically what i am sure of is that this SupportMapFragment is totally fresh and maybe the maintainer of ActionBarSherlock didn't yet have the time to add it on the ABS Project.

    Also it requires API Lvl 8+ so you can just remove your support to the API lvl 7 devices or you will have to wait for Jake to add support for the new SupportMapFragment.

    For other API lvls you can find a work around here:http://xrigau.wordpress.com/2012/03/22/howto-actionbarsherlock-mapfragment-listfragment/

    0 讨论(0)
  • 2020-11-28 04:07

    I heard that Jake is not going to do too much more to ABS as Google may be bringing out their own backward compatible ActionBar. I think if I remember correctly it was discussed in one of the Android related Google+ hangouts.

    The new maps requires API level 8 onward so before even worrying about the actionbar you will run into problems if you must support API level 7.

    My advice would be produce 2 layout files one for level 7 and and one for 8+. In the level 7 use the now old MapView although they are deprecating it, which for me shows how API level 7 is not necessarily worth considering as a target. In the 8+ layout use the new map system.

    As for the actionbar, we are porting an app right now and have easily and successfully added a map to a ViewPager, by creating the Fragment programtically (rather than in XML). We have tested it on multiple devices.

    We have also had no issues using the new map system as described in Google demos with ABS. We declared the fragment in an XML layout and set this as the content of the activity. The ActionBar displays as normal. The Activity is a SherlockFragmentActivity.

    0 讨论(0)
提交回复
热议问题