当前位置: 首页 > 知识库问答 >
问题:

使用片段时的onBackPressed混乱

仰城
2023-03-14
public class MainActivity extends Activity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;

// nav drawer title
private CharSequence mDrawerTitle;

// used to store app title
private CharSequence mTitle;

// slide menu items
private String[] navMenuTitles;
private TypedArray navMenuIcons;

private ArrayList<NavDrawerItem> navDrawerItems;
private NavDrawerListAdapter adapter;

MediaPlayer ourSong;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    ourSong = MediaPlayer.create(MainActivity.this, R.raw.audirs6);

    SharedPreferences getPrefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
    boolean music = getPrefs.getBoolean("checkbox", true);
    if (music == true)
    ourSong.start();

    mTitle = mDrawerTitle = getTitle();

    // load slide menu items
    navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);

    // nav drawer icons from resources
    navMenuIcons = getResources().obtainTypedArray(R.array.nav_drawer_icons);

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawerList = (ListView) findViewById(R.id.list_slidermenu);

    navDrawerItems = new ArrayList<NavDrawerItem>();

    // adding nav drawer items to array
    // AutoMart Home
    navDrawerItems.add(new NavDrawerItem(navMenuTitles[0], navMenuIcons.getResourceId(0, -1)));
    // Search For A Car
    navDrawerItems.add(new NavDrawerItem(navMenuTitles[1], navMenuIcons.getResourceId(1, -1)));

    navDrawerItems.add(new NavDrawerItem(navMenuTitles[2], navMenuIcons.getResourceId(2, -1)));

    navDrawerItems.add(new NavDrawerItem(navMenuTitles[3], navMenuIcons.getResourceId(3, -1)));

    // Recycle the typed array
    navMenuIcons.recycle();

    mDrawerList.setOnItemClickListener(new SlideMenuClickListener());

    // setting the nav drawer list adapter
    adapter = new NavDrawerListAdapter(getApplicationContext(),
            navDrawerItems);
    mDrawerList.setAdapter(adapter);

    // enabling action bar app icon and behaving it as toggle button
    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setHomeButtonEnabled(true);

    if (savedInstanceState == null) {
        // on first time display view for first nav item
        displayView(0);
    }   

    mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
            R.drawable.ic_drawer, //nav menu toggle icon
            R.string.app_name, // nav drawer open - description for accessibility
            R.string.app_name // nav drawer close - description for accessibility
    ) {
        public void onDrawerClosed(View view) {
            getActionBar().setTitle(mTitle);
            // calling onPrepareOptionsMenu() to show action bar icons
            invalidateOptionsMenu();
        }


        public void onDrawerOpened(View drawerView) {
            getActionBar().setTitle(mDrawerTitle);
            // calling onPrepareOptionsMenu() to hide action bar icons
            invalidateOptionsMenu();
        }
    };
    mDrawerLayout.setDrawerListener(mDrawerToggle);

}

/**
 * Slide menu item click listener
 * */
private class SlideMenuClickListener implements
        ListView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id) {
        // display view for selected nav drawer item
        displayView(position);
    }
}

@Override
protected void onStop() {
    // TODO Auto-generated method stub
    super.onStop();
    ourSong.release();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // toggle nav drawer on selecting action bar app icon/title
    if (mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    // Handle action bar actions click
    switch (item.getItemId()) {
    case R.id.action_settings:
        Intent settings  = new Intent("com.loui.automartdirectcars.SETTINGS");
        startActivity(settings);
        break;
    case R.id.aboutUs:
        Intent about = new Intent("com.loui.automartdirectcars.ABOUT");
        startActivity(about);
        break;
    case (R.id.tellFriend):
        Intent share = new Intent(Intent.ACTION_SEND);
        share.setType("application/octet-stream");
        share.putExtra(Intent.EXTRA_SUBJECT, "AutoMart Direct Cars Android App");
        share.putExtra(Intent.EXTRA_TEXT, "Hey check out AutoMart Direct Cars Android App at https://play.google.com/store/apps/details?id=com.loui.automartdirectcars");
        startActivity(share);
        break;
    case R.id.contactDeveloper:
        String body = "Enter your Question, Enquiry or Feedback below:\n\n";
        Intent contactDev = new Intent(Intent.ACTION_SEND);
        contactDev.setType("application/octet-stream");
        contactDev.putExtra(Intent.EXTRA_EMAIL, new String[]{"louigi7386@gmail.com"});
        contactDev.putExtra(Intent.EXTRA_SUBJECT, "AutoMart Direct Cars Android App");
        contactDev.putExtra(Intent.EXTRA_TEXT, body);
        startActivity(contactDev);
        break;
    case R.id.exit:
        finish();
        break;
    }
        return super.onOptionsItemSelected(item);
}

/* *
 * Called when invalidateOptionsMenu() is triggered
 */
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    // if nav drawer is opened, hide the action items
    boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
    menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
    menu.findItem(R.id.aboutUs).setVisible(!drawerOpen);
    menu.findItem(R.id.tellFriend).setVisible(!drawerOpen);
    menu.findItem(R.id.contactDeveloper).setVisible(!drawerOpen);
    menu.findItem(R.id.exit).setVisible(!drawerOpen);

    return super.onPrepareOptionsMenu(menu);
}

/**
 * Diplaying fragment view for selected nav drawer list item
 * @param <FragmentTransaction>
 * */
private <FragmentTransaction> void displayView(int position) {
    // update the main content by replacing fragments
    Fragment fragment = null;
    switch (position) {
    case 0:
        fragment = new HomeFragment();
        break;
    case 1:
        fragment = new SearchCarFragment();
        break;
    case 2:
        fragment = new LogoFlipperFragment();
        break;
    case 3:
        fragment = new CommunityFragment();
        break;
    default:
        break;
    }


        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.frame_container, fragment).addToBackStack(null).commit();

        // update selected item and title, then close the drawer
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        setTitle(navMenuTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);

}



@Override
public void setTitle(CharSequence title) {
    mTitle = title;
    getActionBar().setTitle(mTitle);
}

/**
 * When using the ActionBarDrawerToggle, you must call it during
 * onPostCreate() and onConfigurationChanged()...
 */

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred.
    mDrawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Pass any configuration change to the drawer toggls
    mDrawerToggle.onConfigurationChanged(newConfig);
    }
public void onBackPressed() {
    WebView mWebView = (WebView) findViewById(R.id.webView);
    if (mWebView.canGoBack())
        mWebView.goBack(); 
    return;
}
}
public class HomeFragment extends Fragment {

public HomeFragment(){}


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

    View rootView = inflater.inflate(R.layout.fragment_home, container, false);
    WebView mWebView = (WebView) rootView.findViewById(R.id.webView);


  //Initializing and loading url in webview       
    mWebView = (WebView) rootView.findViewById(R.id.webView);
    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.loadUrl("http://www.automartdirect.co.uk");
    mWebView.setWebViewClient(new WebViewClient() {


        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if( url.startsWith("http:") || url.startsWith("https:") ) {
                return false;
            }

            // Otherwise allow the OS to handle it
            else if (url.startsWith("tel:")) { 
                Intent tel = new Intent(Intent.ACTION_DIAL, Uri.parse(url)); 
                startActivity(tel);
                return true;
            }
            else if (url.startsWith("mailto:")) {
                String body = "Enter your Question, Enquiry or Feedback below:\n\n";
                Intent mail = new Intent(Intent.ACTION_SEND);
                mail.setType("application/octet-stream");
                mail.putExtra(Intent.EXTRA_EMAIL, new String[]{"info@automartdirect.co.uk"});
                mail.putExtra(Intent.EXTRA_SUBJECT, "Enquiry From AutoMart Direct Cars Android App");
                mail.putExtra(Intent.EXTRA_TEXT, body);
                startActivity(mail);
                return true;
                }
            return true;
        }
    });
    return rootView;
    }
}

这就是我卡住的地方。当我从导航抽屉中选择另一个项目(片段)时,它会显示出来,但当我按后退按钮时,应用程序关闭时会显示消息“不幸的是,myapp已经停止了。我是缺少了一些代码,还是必须为每个片段添加onBackPressed代码?更重要的是,我对onBackPressed方法应该去哪里感到困惑。它应该只在MainActivity中进行还是应该在每个碎片活动中进行?目前,我唯一的onBackPressed方法是在MainActivity for webview中,它可以工作,但可能仍然是错误的实践。什么代码我需要其他片段,当返回按钮被按下,它没有关闭应用程序与上面的消息我提到,它应该去哪里?

任何帮助都是非常感谢的!

下面是logcat:

12-17 22:34:03.957: D/AndroidRuntime(8477): Shutting down VM
12-17 22:34:03.957: W/dalvikvm(8477): threadid=1: thread exiting with uncaught exception (group=0x41288930)
12-17 22:34:03.987: E/AndroidRuntime(8477): FATAL EXCEPTION: main
12-17 22:34:03.987: E/AndroidRuntime(8477): java.lang.NullPointerException
12-17 22:34:03.987: E/AndroidRuntime(8477):     at com.loui.automartdirectcars.MainActivity.onBackPressed(MainActivity.java:273)
12-17 22:34:03.987: E/AndroidRuntime(8477):     at android.app.Activity.onKeyUp(Activity.java:2145)
12-17 22:34:03.987: E/AndroidRuntime(8477):     at android.view.KeyEvent.dispatch(KeyEvent.java:2633)
12-17 22:34:03.987: E/AndroidRuntime(8477):     at android.app.Activity.dispatchKeyEvent(Activity.java:2375)
12-17 22:34:03.987: E/AndroidRuntime(8477):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1865)
12-17 22:34:03.987: E/AndroidRuntime(8477):     at android.view.ViewRootImpl.deliverKeyEventPostIme(ViewRootImpl.java:3701)
12-17 22:34:03.987: E/AndroidRuntime(8477):     at android.view.ViewRootImpl.handleImeFinishedEvent(ViewRootImpl.java:3651)
12-17 22:34:03.987: E/AndroidRuntime(8477):     at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:2818)
12-17 22:34:03.987: E/AndroidRuntime(8477):     at android.os.Handler.dispatchMessage(Handler.java:99)
12-17 22:34:03.987: E/AndroidRuntime(8477):     at android.os.Looper.loop(Looper.java:137)
12-17 22:34:03.987: E/AndroidRuntime(8477):     at android.app.ActivityThread.main(ActivityThread.java:5195)
12-17 22:34:03.987: E/AndroidRuntime(8477):     at java.lang.reflect.Method.invokeNative(Native Method)
12-17 22:34:03.987: E/AndroidRuntime(8477):     at java.lang.reflect.Method.invoke(Method.java:511)
12-17 22:34:03.987: E/AndroidRuntime(8477):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
12-17 22:34:03.987: E/AndroidRuntime(8477):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
12-17 22:34:03.987: E/AndroidRuntime(8477):     at dalvik.system.NativeStart.main(Native Method)

共有1个答案

公孙俊弼
2023-03-14

显然,问题基本上在这几条线上:

WebView mWebView = (WebView) findViewById(R.id.webView);
if (mWebView.canGoBack())

当您更改片段时,视图层次结构也会更改,方法findviewbyid()返回null。然后尝试访问空变量,导致NullPointerException。您可以通过添加空检查来解决这个问题:if(mWebView!=null&&mWebView.cangoback())

编辑

 类似资料:
  • 是否有一种方法可以检查堆栈中的前一个片段是否是包含SupportMap的片段?

  • 在我的应用程序我有导航抽屉,所以我有一个主要活动和Rest是碎片。我的应用程序运行良好。当我按back按钮时,它会重定向到以前的片段。它工作得很好。但我想要的是在成功支付后,我会显示成功支付页面,在此页面上,当用户按back按钮时,我想重定向到HomeFragment,但现在它会重定向到Placeorder片段。

  • 我在使用LocalbroadcastManager将数据从一个片段传输到另一个片段时遇到问题。 FragmentA有editText,点击它将启动FragmentB。FragmentB有一个项目列表,单击我想将数据传递给FragmentA的每个项目。 这是我的实现。 下面是广播消息发送的片段B。 调试/日志记录从未命中广播接收器的onReceive消息。少了什么吗?谢谢你的建议。

  • 我的应用程序(最小API14)使用带有3个选项卡的ActionBar。选项卡是:i。输入数据(约10个片段)ii。管理数据(15个片段)三.查看数据(8个片段)。每个选项卡都有一个默认片段,但根据用户的选择会有多个片段。 我希望用户能够在3个选项卡之间滑动(通过滑动内容),因此我需要使用ViewPager和兼容性库V4。 我得到的建议(经过大量研究)是使用一个MainActivity,它承载Act

  • 我使用带有ViewPager的FragmentPagerAdapter来切换片段 那么我如何使片段调用它们的onResume()呢?

  • 下面是我的布局: 编辑(已解决):最后,我找到了解决方案。应该在JAVA文件mapFragment中添加onDestroyView()方法,如下所示: