使用导航抽屉从应用程序中的另一个更改片段

Change fragment from another in app with Navigation Drawer

所以,我有带导航抽屉的应用程序。 我想将 Extra 放入 Fragment "ScreenSourceCollection" 并在 Fragment "ScreenPlayList" 中获取 Extra。但如果我打电话 i.putExtra(MainActivity.EXTRA_BOOK_ID, bookId); 开始活动(我); 我得到索引为 0 的第一个屏幕,而不是索引为 1 的第二个屏幕。我意识到我犯了错误,但我没有意识到我必须做什么。

下面是我的代码

ScreenSourceCollection

public View onCreateView(LayoutInflater inflater, ViewGroup parent,
                         Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.tab_sources_albums, parent,false);
    ListView lvSourceList = (ListView)rootView.findViewById(R.id.lvSourceList);

    database = new MediaDatabase(getActivity());
    mDB = new MediaDB(getActivity());
    mBooks = mDB.getBooks();

    BookAdapter bookAdapter = new BookAdapter(mBooks);
    lvSourceList.setAdapter(bookAdapter);

    lvSourceList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view1,
                                int position, long id) {

            Book book = (Book)parent.getAdapter().getItem(position);
            long bookId = position;
            Intent i = new Intent(getActivity(),MainActivity.class);
            i.putExtra(MainActivity.EXTRA_BOOK_ID, bookId);
            startActivity(i);

            Toast.makeText(getActivity(), String.valueOf(book.getId()), Toast.LENGTH_SHORT).show();
        }
    });

    return rootView;
}

屏幕播放列表

public static ScreenPlayList newInstance (long bookId) {
    Bundle args = new Bundle();
    args.putLong(ARG_BOOK_ID, bookId);
    ScreenPlayList pl = new ScreenPlayList();
    pl.setArguments(args);
    return pl;

}

主要活动

public class MainActivity extends ActionBarActivity {

private String[] mScreenTitles;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
public static final String EXTRA_BOOK_ID = "ru.thevoice.sounds.book_id";

private ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;

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

    mTitle = mDrawerTitle = getTitle();
    mScreenTitles = getResources().getStringArray(R.array.screen_array);
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawerList = (ListView) findViewById(R.id.left_drawer);

    // Set the adapter for the list view
    mDrawerList.setAdapter(new ArrayAdapter<String>(this,
            R.layout.drawer_list_item, mScreenTitles));
    // Set the list's click listener
    mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setHomeButtonEnabled(true);

    mDrawerToggle = new ActionBarDrawerToggle(
            this, /* host Activity */
            mDrawerLayout, /* DrawerLayout object */
            R.drawable.ic_drawer, /* nav drawer icon to replace 'Up' caret */
            R.string.drawer_open, /* "open drawer" description */
            R.string.drawer_close /* "close drawer" description */
    ) {

        /** Called when a drawer has settled in a completely closed state. */
        public void onDrawerClosed(View view) {
            getSupportActionBar().setTitle(mTitle);
            supportInvalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }

        /** Called when a drawer has settled in a completely open state. */
        public void onDrawerOpened(View drawerView) {
            getSupportActionBar().setTitle(mDrawerTitle);
            supportInvalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }
    };

    // Set the drawer toggle as the DrawerListener
    mDrawerLayout.setDrawerListener(mDrawerToggle);

    // Initialize the first fragment when the application first loads.
    if (savedInstanceState == null) {
        selectItem(0);
    }

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu;
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu_main, menu);
    return super.onCreateOptionsMenu(menu);
}

/* Called whenever we call invalidateOptionsMenu() */
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    // If the nav drawer is open, hide action items related to the content view
    boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
    menu.findItem(R.id.action_search).setVisible(!drawerOpen);
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Pass the event to ActionBarDrawerToggle, if it returns
    // true, then it has handled the app icon touch event
    if (mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    // Handle action buttons
    switch(item.getItemId()) {
        case R.id.action_search:
            // Show toast about click.
            Toast.makeText(this, R.string.action_search, Toast.LENGTH_SHORT).show();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

/* The click listener for ListView in the navigation drawer */
private class DrawerItemClickListener implements ListView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        selectItem(position);
    }
}

/** Swaps fragments in the main content view */
private void selectItem(int position) {
    // Update the main content by replacing fragments
    Fragment fragment = null;
    switch (position) {
        case 0:
            fragment = new ScreenPlay();
            break;
        case 1:
            //fragment = new ScreenPlayList();
            long bookId = getIntent().getLongExtra(EXTRA_BOOK_ID, -1);
            if (bookId != -1) {
                fragment =  ScreenPlayList.newInstance(bookId);
            } else {
                fragment =  new ScreenPlayList();
            }
            break;
        case 2:
            fragment = new ScreenSourcesCollection();
            break;
        case 3:
            fragment = new ScreenSettings();
            break;
        case 4:
            fragment = new ScreenPlayTabs();
            break;
        default:
            break;
    }

    // Insert the fragment by replacing any existing fragment
    if (fragment != null) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.content_frame, fragment).commit();

        // Highlight the selected item, update the title, and close the drawer
        mDrawerList.setItemChecked(position, true);
        setTitle(mScreenTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    } else {
        // Error
        Log.e(this.getClass().getName(), "Error. Fragment is not created");
    }
}

@Override
public void setTitle(CharSequence title) {
    mTitle = title;
    getSupportActionBar().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 toggles
    mDrawerToggle.onConfigurationChanged(newConfig);
}

}

我是怎么做的,通过保留对我想将 Bundle 传递给的片段的引用:

Bundle args = new Bundle();
args.putInt(YourFragment.QUESTIONNUMBER, position + 1);
args.putSerializable(YourFragment.QUESTIONCONTENT, question);
currentFragment.setArguments(args);

为您可以在片段内部传递的每个值制作字符串标签,例如

public static final String QUESTIONCONTENT = "question"

这样您就可以始终准确地知道要传递什么,以防止出现转换错误。调用您的片段,设置参数包,然后在您的片段中您可以调用:

Bundle args = getArguments();
int position = (Integer)args.get(QUESTIONNUMBER);
question = (Question)args.get(QUESTION);

这段代码在我的 onCreateView 中,还没有真正尝试过在其他地方使用它。祝你好运!