片段,地图应用程序崩溃时,后退按钮是pressed或者方向变化 [英] Fragment with Map crashes app when back button is pressed or when orientation changes

查看:103
本文介绍了片段,地图应用程序崩溃时,后退按钮是pressed或者方向变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个活动,加载2个选项卡中的动作条。标签1会装载片段将将抬高一个的WebView ,而标签2加载一个片段的地图。起初,我有改变的选项卡,导致应用程序崩溃的问题。我也跟着指示<一href="http://stackoverflow.com/questions/14074625/mapfragment-in-action-bar-tabs/14466954#14466954">here实施 onDestroyView()

现在的问题是,如果我preSS后退按钮由表1(的WebView ),它退出活动正常。但是,如果我这样做的选项卡2(图),该应用程序崩溃。确切相同的情况时,我改变方向。我相信,它有事可做与 onDestroyView(),但我不知道它是什么。

我甚至尝试覆盖返回按钮,但没有任何工程。

下面是我的code提供一些背景:

Activity类:

 公共类MyActivity延伸活动{

@覆盖
保护无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_main);

    //调用动作条显示卡
    动作条动作条= getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    //详细信息选项卡
    。字符串卷标1 = getResources()的getString(R.string.details);
    TAB键= actionBar.newTab();
    tab.setText(LABEL1);
    TabListener&LT; D​​etailsFragment&GT; T1 =新TabListener&LT; D​​etailsFragment&GT;(这一点,LABEL1,DetailsFragment.class);
    tab.setTabListener(T1);
    actionBar.addTab(标签);

    //地图标签
    。字符串标签2 = getResources()的getString(R.string.map);
    标签= actionBar.newTab();
    tab.setText(LABEL2);
    TabListener&LT; MapFragment&GT; T2 =新TabListener&LT; MapFragment&GT;(这一点,LABEL2,MapFragment.class);
    tab.setTabListener(T2);
    actionBar.addTab(标签);
}

私有类TabListener&LT;吨延伸片断&gt;实现ActionBar.TabListener {
    私人片段mFragment;
    私人最终活动mActivity;
    私人最终字符串MTAG;
    私人最终类别&LT; T&GT; mClass;

    / **
     *构造函数用于创建一个新的标签,每次。
     *
     * @参数活动
     *主机活动,用实例片段
     * @参数标签
     *标识符标记的片段
     * @参数CLZ
     *片段的类,用于实例片段
     * /
    公共TabListener(活动活动,字符串变量,类&LT; T&GT; CLZ){
        mActivity =活动;
        MTAG =标签;
        mClass = CLZ;
    }

    公共无效onTabSelected(TAB键,FragmentTransaction英尺){
        //检查片段已初始化
        如果(mFragment == NULL){
            //如果没有,实例化并把它添加到活动
            mFragment = Fragment.instantiate(mActivity,mClass.getName());
            ft.add(android.R.id.content,mFragment,MTAG);
        } 其他 {
            //如果它存在,只需将它为了显示它
            ft.attach(mFragment);

        }
    }

    公共无效onTabUnselected(TAB键,FragmentTransaction英尺){
        如果(mFragment!= NULL){
            //分离的片段,因为另一个被连接
            ft.detach(mFragment);
        }
    }

    公共无效onTabReselected(TAB键,FragmentTransaction英尺){
        //用户选择已经选择的选项卡。通常什么也不做。
    }
}

@覆盖
公共布尔onCreateOptionsMenu(功能菜单){
    //充气菜单;这增加了项目操作栏,如果它是present。
    。getMenuInflater()膨胀(R.menu.main,菜单);
    返回true;
}}
 

DetailsFragment:

 公共类DetailsFragment扩展片段{


@覆盖
公共查看onCreateView(LayoutInflater充气,容器的ViewGroup,捆绑savedInstanceState){

    视图V = inflater.inflate(R.layout.morning,集装箱,假);
    的WebView的WebView =(web视图)v.findViewById(R.id.details);
    webview.loadUrl(文件:///android_asset/pools/details.html);
    返回伏;
}}
 

MapFragment:

 公共类MapFragment扩展片段{

static final的经纬度mapLatLng =新的经纬度(一些数字,有些数字);
私人GoogleMap的地图;

@覆盖
公共查看onCreateView(LayoutInflater充气,容器的ViewGroup,捆绑savedInstanceState){

    视图V = inflater.inflate(R.layout.map,集装箱,假);
    地图=((MapFragment)getFragmentManager()findFragmentById(R.id.map)。)的GetMap()。
    标记amksc = map.addMarker(新MarkerOptions()位置(mapLatLng).title伪(地图));

    map.moveCamera(CameraUpdateFactory.newLatLngZoom(mapLatLng,18));
    返回伏;
}


@覆盖
公共无效onDestroyView(){
    super.onDestroyView();
    MapFragment destroyMe =(MapFragment)getFragmentManager()findFragmentById(R.id.map)。
    如果(destroyMe!= NULL){
        。getFragmentManager()的BeginTransaction()删除(destroyMe).commit()。
    }
}}
 

感谢您阅读这么长的帖子。任何帮助是极大的AP preciated。我要离开一段时间没有我的笔记本电脑(15天是精确的),所以我可能无法作出反应,并测试出你的答案,但请放心,我会=)

在此先感谢!

编辑,包括错误日志(不知道如何格式化)

  11月四号至25日:27:54.333:E / AndroidRuntime(21779):致命异常:主要

11月4号至25日:27:54.333:E / AndroidRuntime(21779):显示java.lang.NullPointerException

11月4号至25日:27:54.333:E / AndroidRuntime(21779):在android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1380)

11月4号至25日:27:54.333:E / AndroidRuntime(21779):在android.app.FragmentManagerImpl $ 1.运行(FragmentManager.java:430)

11月4号至25日:27:54.333:E / AndroidRuntime(21779):在android.os.Handler.handleCallback(Handler.java:615)

11月4号至25日:27:54.333:E / AndroidRuntime(21779):在android.os.Handler.dispatchMessage(Handler.java:92)

11月4号至25日:27:54.333:E / AndroidRuntime(21779):在android.os.Looper.loop(Looper.java:213)

11月4号至25日:27:54.333:E / AndroidRuntime(21779):在android.app.ActivityThread.main(ActivityThread.java:4786)

11月4号至25日:27:54.333:E / AndroidRuntime(21779):在java.lang.reflect.Method.invokeNative(本机方法)

11月4号至25日:27:54.333:E / AndroidRuntime(21779):在java.lang.reflect.Method.invoke(Method.java:511)

11月4号至25日:27:54.333:E / AndroidRuntime(21779):在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:789)

11月4号至25日:27:54.333:E / AndroidRuntime(21779):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)

11月4号至25日:27:54.333:E / AndroidRuntime(21779):在dalvik.system.NativeStart.main(本机方法)
 

解决方案

我似乎已经解决了这两个后退按钮和方向变化的问题​​。

这里的技巧是不使用 onDestroyView(),而是要改变片段的处理方式。而不是 ft.attach(mFragment) ft.detach(mFragment),我改变了他们为 ft.show(mFragment) ft.hide(mFragment)

对于方向的改变导致应用程序崩溃,我相信(不纠正我,如果我错了),只要你没有一个替代的景观布局,您可以添加安卓configChanges =方向|屏幕尺寸的清单这项活动,像这样的:

 &LT;活动
        机器人:主题=@风格/ AppTheme
        机器人:名称=MyFragmentActivity
        机器人:标签=@字符串/ fragmentActivity
        机器人:configChanges =方向|屏幕尺寸&GT;
    &LT; /活性GT;
 

I have an Activity that loads 2 tabs in the ActionBar. Tab 1 loads a Fragment that will will inflate a WebView, while Tab 2 loads a Fragment with a map. Initially, I have the problem of changing tabs that causes the app to crash. I have followed the instructions here and implemented onDestroyView().

The problem now is that if I press the back button from Tab 1 (WebView), it exits the Activity properly. But if I do it on Tab 2 (map), the app crashes. The exact same scenario applies to when I change the orientation. I am convinced that it has something to do with the onDestroyView(), but I am not sure what it is.

I have even attempted to Override the back button, but nothing works.

Here is my code to provide some context:

The Activity Class:

public class MyActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //Displaying the tabs by calling ActionBar
    ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    //Details Tab
    String label1 = getResources().getString(R.string.details);
    Tab tab = actionBar.newTab();
    tab.setText(label1);
    TabListener<DetailsFragment> t1 = new TabListener<DetailsFragment>(this, label1, DetailsFragment.class);
    tab.setTabListener(t1);
    actionBar.addTab(tab);

    //Map Tab
    String label2 = getResources().getString(R.string.map);
    tab = actionBar.newTab();
    tab.setText(label2);
    TabListener<MapFragment> t2 = new TabListener<MapFragment>(this, label2, MapFragment.class);
    tab.setTabListener(t2);
    actionBar.addTab(tab);
}

private class TabListener<T extends Fragment> implements ActionBar.TabListener {
    private Fragment mFragment;
    private final Activity mActivity;
    private final String mTag;
    private final Class<T> mClass;

    /**
     * Constructor used each time a new tab is created.
     * 
     * @param activity
     *            The host Activity, used to instantiate the fragment
     * @param tag
     *            The identifier tag for the fragment
     * @param clz
     *            The fragment's Class, used to instantiate the fragment
     */
    public TabListener(Activity activity, String tag, Class<T> clz) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
    }

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // Check if the fragment is already initialized
        if (mFragment == null) {
            // If not, instantiate and add it to the activity
            mFragment = Fragment.instantiate(mActivity, mClass.getName());
            ft.add(android.R.id.content, mFragment, mTag);
        } else {
            // If it exists, simply attach it in order to show it
            ft.attach(mFragment);

        }
    }

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        if (mFragment != null) {
            // Detach the fragment, because another one is being attached
            ft.detach(mFragment);
        }
    }

    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // User selected the already selected tab. Usually do nothing.
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
} }

DetailsFragment:

public class DetailsFragment extends Fragment {


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View v = inflater.inflate(R.layout.morning, container, false);
    WebView webview = (WebView) v.findViewById(R.id.details);
    webview.loadUrl("file:///android_asset/pools/details.html");
    return v;
} }

MapFragment:

public class MapFragment extends Fragment {

static final LatLng mapLatLng = new LatLng("some numbers", "some numbers");
private GoogleMap map;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View v = inflater.inflate(R.layout.map, container, false);
    map = ((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();
    Marker amksc = map.addMarker(new MarkerOptions().position(mapLatLng).title("Map"));

    map.moveCamera(CameraUpdateFactory.newLatLngZoom(mapLatLng, 18)); 
    return v;
}


@Override
public void onDestroyView() {
    super.onDestroyView();
    MapFragment destroyMe = (MapFragment)getFragmentManager().findFragmentById(R.id.map);
    if (destroyMe != null) {
        getFragmentManager().beginTransaction().remove(destroyMe).commit();
    }
} }

Thanks for reading such a long post. Any help is greatly appreciated. I will be away for awhile without my laptop (15 days to be exact), so I may not be able to respond and test out your answer, but rest assured that I will =)

Thanks in advance!

EDITED to include Error Log (Not sure how to format it)

04-25 11:27:54.333: E/AndroidRuntime(21779): FATAL EXCEPTION: main

04-25 11:27:54.333: E/AndroidRuntime(21779): java.lang.NullPointerException

04-25 11:27:54.333: E/AndroidRuntime(21779):    at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1380)

04-25 11:27:54.333: E/AndroidRuntime(21779):    at android.app.FragmentManagerImpl$1.run(FragmentManager.java:430)

04-25 11:27:54.333: E/AndroidRuntime(21779):    at android.os.Handler.handleCallback(Handler.java:615)

04-25 11:27:54.333: E/AndroidRuntime(21779):    at android.os.Handler.dispatchMessage(Handler.java:92)

04-25 11:27:54.333: E/AndroidRuntime(21779):    at android.os.Looper.loop(Looper.java:213)

04-25 11:27:54.333: E/AndroidRuntime(21779):    at android.app.ActivityThread.main(ActivityThread.java:4786)

04-25 11:27:54.333: E/AndroidRuntime(21779):    at java.lang.reflect.Method.invokeNative(Native Method)

04-25 11:27:54.333: E/AndroidRuntime(21779):    at java.lang.reflect.Method.invoke(Method.java:511)

04-25 11:27:54.333: E/AndroidRuntime(21779):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)

04-25 11:27:54.333: E/AndroidRuntime(21779):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)

04-25 11:27:54.333: E/AndroidRuntime(21779):    at dalvik.system.NativeStart.main(Native Method)

解决方案

I seem to have solved both the back button and orientation change problem.

The trick here is to not use onDestroyView(), but to change the way the fragments are handled. instead of ft.attach(mFragment) and ft.detach(mFragment), I changed them to ft.show(mFragment) and ft.hide(mFragment).

As for the orientation change causing the app to crash, I believe (do correct me if I am wrong) that as long as you do not have an alternative landscape layout, you can add android:configChanges="orientation|screenSize" to the manifest for this activity, like this:

<activity 
        android:theme="@style/AppTheme" 
        android:name="MyFragmentActivity" 
        android:label="@string/fragmentActivity" 
        android:configChanges="orientation|screenSize">
    </activity>

这篇关于片段,地图应用程序崩溃时,后退按钮是pressed或者方向变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆