【问题标题】:Using ActionBarSherlock With the New SupportMapFragment将 ActionBarSherlock 与新的 SupportMapFragment 一起使用
【发布时间】:2012-12-05 11:09:54
【问题描述】:

我正在考虑使用 ActionbarSherlock,但有一个问题让我望而却步。

所以我的应用程序需要完全向后兼容 API Level 7。

我需要在我的应用程序中实现新的 Google 地图,为此我需要使用 SupportMapFragment 类。

** 我的问题**

是否可以在 ActionBarSherlock 旁边使用 SupportMapFragment 类?

提前致谢

编辑

我已经下载并查看了库。我可以看到对扩展 Fragments 的唯一更改非常简单,并且对所有更改都相同。

你认为我可以自己添加支持吗?

这是它们的支持方式。

package com.actionbarsherlock.app;

import android.app.Activity;
import android.support.v4.app.DialogFragment;
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 static com.actionbarsherlock.app.SherlockFragmentActivity.OnCreateOptionsMenuListener;
import static com.actionbarsherlock.app.SherlockFragmentActivity.OnOptionsItemSelectedListener;
import static com.actionbarsherlock.app.SherlockFragmentActivity.OnPrepareOptionsMenuListener;

public class SherlockDialogFragment extends DialogFragment 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;
}

}

【问题讨论】:

    标签: android android-actionbar actionbarsherlock actionbarsherlock-map


    【解决方案1】:

    这一切都像魅力一样,主要归功于 Jake 在 ActionBarSherlock 上的出色工作

    这是我遵循的步骤:

    1. 在您的 actiobarsherlock 库项目中创建一个 SherlockMapFragment 类。我只是制作了 SherlockFragment 的副本,因为我还需要对 setHasOptionsMenu(true) 的支持
    2. 活动扩展了 SherlockFragmentActivity(像往常一样)
    3. 片段扩展了新创建的 SherlockMapFragment
    4. ActionBarSherlock 需要新的 google-play-services_lib
    5. 您的项目需要 ActionBarSherlock 库。无需再次包含 google-play-services,也无需针对 Google API 进行构建。
    6. 正如 Graham 所提到的,您必须放弃对 API 7 设备的支持:<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />

    这里有一些更详细的解释代码:

    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;
        }
    }
    

    活动:

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

    活动 XML 布局:

    <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>
    

    地图片段:

    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;
        }
    }
    

    【讨论】:

    • 我也这样做了,效果很好。如果您不想弄乱 ABS 库项目,也可以将 SherlockMapFragment 放在主项目中。
    • 全部完成,谢谢。下一个问题是让它正常工作。请参阅我关于检索地图的其他问题。 stackoverflow.com/questions/13727992/…
    • 您知道这段代码在使用 Android Maven 项目时是否会出现问题吗?我尝试了相同的代码,但在这里报告了错误:stackoverflow.com/questions/14004668/…
    • 我已经尝试过这个......但是我的项目中发生了一些奇怪的事情:stackoverflow.com/questions/14430716/…
    • 非常感谢您的解释
    【解决方案2】:

    听说 Jake 不会对 ABS 做太多事情,因为 Google 可能会推出他们自己的向后兼容的 ActionBar。我想如果我没记错的话,它是在一个与 Android 相关的 Google+ 环聊中讨论的。

    新地图需要 API 8 级以上,所以在担心操作栏之前,如果您必须支持 API 7 级,您就会遇到问题。

    我的建议是生成 2 个布局文件,一个用于 7 级,一个用于 8+。在第 7 级中使用现在旧的MapView,尽管他们正在弃用它,这对我来说表明 API 级别 7 不一定值得考虑作为目标。在 8+ 布局中使用新的地图系统。

    至于操作栏,我们现在正在移植一个应用程序,并且通过以编程方式(而不是在 XML 中)创建 Fragment,轻松成功地将地图添加到 ViewPager。我们已经在多台设备上对其进行了测试。

    我们在使用带有 ABS 的 Google 演示中描述的新地图系统时也没有遇到任何问题。我们在 XML 布局中声明了片段并将其设置为活动的内容。 ActionBar 正常显示。 Activity 是一个 SherlockFragmentActivity。

    【讨论】:

    • 你能分享如何通过程序将地图添加到片段中的代码。我正在尝试将其添加到 Sherlock 选项卡中
    • 您是否将此 SupportMapFragment 子类化了?我可以以编程方式创建,但如果我子类化则不能?
    • 当您滑动ViewPager 时,当MapFragment 在屏幕上移动时,您不会看到那些闪烁的黑色伪影吗?
    【解决方案3】:

    基本上我可以肯定的是,这个 SupportMapFragment 是全新的,也许 ActionBarSherlock 的维护者还没有时间将它添加到 ABS 项目中。

    它还需要 API Lvl 8+,因此您可以删除对 API lvl 7 设备的支持,否则您将不得不等待 Jake 添加对新 SupportMapFragment 的支持。

    对于其他 API lvls,您可以在此处找到解决方法:http://xrigau.wordpress.com/2012/03/22/howto-actionbarsherlock-mapfragment-listfragment/

    【讨论】:

      【解决方案4】:

      我尝试使用 ActionBarSherlock 实现 SupportMapFragment。

      它工作得很好。

      下面是代码sn-p。

      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;
      
          }
      }
      

      希望这会有所帮助。

      【讨论】:

      • 能否请您也分享 xml。我正在尝试在片段中实现它
      • 感谢您的回答,我很高兴您能够使用它,因为它向我展示了它绝对是可能的。现在的问题是我需要能够创建此 SupportMapFragment 的子类,但是我遇到了各种类转换异常。有什么想法吗?
      • 在您的 xml 布局中,将 MapFragment 更改为 SupportMapFragment,它应该如下所示:
      【解决方案5】:

      我还不能到处评论,这就是我回答 @sureshcheemalamudi 的原因 如果您尝试在 Fragment 或 SherlockFragment 上实现它,请查看:https://stackoverflow.com/a/17803561/1755300

      【讨论】:

        【解决方案6】:
        @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);
            }
        }
        

        【讨论】:

        • 这段代码如何回答这个问题?请展开或删除。
        • 只检查一次mapfragment是否为null,不需要每次更改map类型时检查map是否为null,如上代码所示
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-10
        相关资源
        最近更新 更多