カーソルローダーを使用して、アクティビティにタブを作成しています。android View Pagerのドキュメントで詳しく説明されているように、スワイプ可能なタブを使用しています。
http://developer.android.com/reference/android/support/v4/view/ViewPager.html
これまでのところ、バックスタックにロードされたページを配置することは実装していません。そのため、クリックして戻ると、前のアクティビティにジャンプします。(今のところこれで問題ありません。)戻るボタンまたは上ボタンをクリックすると、ランタイム例外が発生します。java.lang.RuntimeException: Unable to destroy activity: java.lang.IllegalStateException: Activity has been destroyed
私が持っているものと例の違いは、カーソルの使用と、ViewPager自体をコンテンツビューとして設定しているのに対し、ViewPagerを含むレイアウトファイルを使用していることだけです。また、FragmentPagerAdapterではなくFragmentStatePagerAdapterを使用していますが、これら2つを切り替えても違いはありません。
androidのonDestroy呼び出しで、アクティビティを2回破棄しようとするものがわかりません。私のコードは以下の通りです。どんな助けでもありがたいです、そして私はより多くの情報を提供してうれしいです。ありがとう。
public class WorksheetActivity extends FragmentActivity implements android.support.v4.app.LoaderManager.LoaderCallbacks<Cursor> {
public String user;
private static final int DAY_LOADER = 0;
public int program_index;
public int program_id;
public int item_id;
public int type_key;
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
LoaderManager.LoaderCallbacks<Cursor> mCallbacks;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_worksheet);
mCallbacks = this;
ActionBar bar = getActionBar();
//this sets up to include tabs, and to show the title on each tab
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
//enables navigation up, when clicked calls on options item selected for home button.
bar.setDisplayHomeAsUpEnabled(true);
Bundle extras = getIntent().getExtras();
if (!(extras.isEmpty())){
user = extras.getString("user");
//used for moving up to the Program Activity and restoring the selection.
program_index = extras.getInt(ProgramActivity.PROGRAM_KEY);
program_id = extras.getInt(ProgramActivity.PROGRAM_ID);
item_id = extras.getInt(ProgramActivity.ITEM_ID);
type_key = extras.getInt(ProgramActivity.TYPE_KEY);
}
Bundle tabData = new Bundle();
tabData.putAll((extras.isEmpty()? savedInstanceState : extras));
mViewPager = (ViewPager) findViewById(R.id.pager);
mTabsAdapter = new TabsAdapter(this, mViewPager, null, tabData);
LoaderManager lm = getSupportLoaderManager();
lm.initLoader(0, tabData, mCallbacks);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_worksheet, menu);
return true;
}
@Override
public void onSaveInstanceState(Bundle out){
out.putString("user",user);
//used for moving up to the Program Activity and restoring the selection.
out.putInt(ProgramActivity.PROGRAM_KEY, program_index);
out.putInt(ProgramActivity.ITEM_ID, item_id);
out.putInt(ProgramActivity.PROGRAM_ID, program_id);
out.putInt(ProgramActivity.TYPE_KEY, type_key);
}
@Override
public void onRestoreInstanceState(Bundle in){
user = in.getString("user");
program_index = in.getInt(ProgramActivity.PROGRAM_KEY);
program_id = in.getInt(ProgramActivity.PROGRAM_ID);
item_id = in.getInt(ProgramActivity.ITEM_ID);
type_key = in.getInt(ProgramActivity.TYPE_KEY);
}
@SuppressLint("NewApi")
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent upIntent = new Intent(this, ProgramActivity.class);
upIntent.putExtra("user", user);
upIntent.putExtra(ProgramActivity.PROGRAM_KEY, program_index);
if (NavUtils.shouldUpRecreateTask(this, upIntent)){
TaskStackBuilder.create(this)
.addNextIntent(new Intent(this, Marta_QC.class))
.addNextIntent(upIntent).startActivities();
finish();
}else{
NavUtils.navigateUpTo(this, upIntent);
}
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {
CursorLoader cl = null;
switch(id){
case DAY_LOADER:
cl = new CursorLoader(getApplicationContext(), Tasks.CONTENT_URI, new String[]{Tasks.DAY_COL},Tasks.PROGRAM_COL+" = ?",
new String[]{Integer.toString(program_id)}, Tasks.DAY_COL+" ASC");
break;
default:
}
return cl;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
switch(loader.getId()){
case DAY_LOADER:
mTabsAdapter.swapCursor(c);
break;
default:
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
switch(loader.getId()){
case DAY_LOADER:
mTabsAdapter.swapCursor(null);
break;
default:
}
}
public static class TabsAdapter extends FragmentStatePagerAdapter
implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
private Bundle mArgs;
private int currentPosition;
static final class TabInfo{
private final Class<?> clss;
private final Bundle args;
public final int position;
TabInfo(Class<?> _class, Bundle _args, int _position){
clss = _class;
args = _args;
position = _position;
}
}
public TabsAdapter (FragmentActivity activity, ViewPager pager, Cursor days, Bundle args){
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
mArgs = args;
}
public void swapCursor(Cursor c){
mActionBar.removeAllTabs();
mViewPager.removeAllViews();
//add the exceptions tab. Always first.
ActionBar.Tab tab = mActionBar.newTab();
Bundle tabArgs = new Bundle();
tabArgs.putAll(mArgs);
this.addTab(tab, ExceptionsSheet.class, tabArgs);
//add each of the day tabs to the set, which stores unique values only
LinkedHashSet<String> days = new LinkedHashSet<String>();
if(c.moveToFirst()){
do{
days.add(c.getString(c.getColumnIndex(Tasks.DAY_COL)));
}while (c.moveToNext());
}
//iterate through the unique days
for(String day:days){
ActionBar.Tab dayTab = mActionBar.newTab();
Bundle dayArgs = new Bundle();
dayArgs.putAll(mArgs);
dayArgs.putString("day", day);
this.addTab(dayTab, Worksheet.class, dayArgs);
}
//start with the first day
mActionBar.setSelectedNavigationItem(1);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args){
//implemented adding a position to the tab info class.
//gets the current tab count prior to adding this tab.
TabInfo info = new TabInfo(clss, args, this.getCount());
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
if (clss.equals(ExceptionsSheet.class)){
//tab.setCustomView(R.layout.exceptions_tab);
tab.setText(mContext.getText(R.string.exceptions_tab_title));
}else{
if(clss.equals(Worksheet.class)){
tab.setText("Day "+args.getString("day"));
}else{
Log.d("unknown class", clss.toString());
}
}
mActionBar.addTab(tab);
notifyDataSetChanged();
}
@Override
public void onPageSelected(int pos) {
// set the tab to match the page, following a swipe action.
currentPosition = pos;
mActionBar.setSelectedNavigationItem(pos);
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
//this will return our tab info
TabInfo minfo = (TabInfo) tab.getTag();
int pos = minfo.position;
this.getItem(currentPosition);
mViewPager.setCurrentItem(pos);
currentPosition = pos;
}
//this is the FragmentPager Adapter main method
//here we will use the arguments bundled into the tab to set the
//fragment for the page.
@Override
public Fragment getItem(int pos) {
TabInfo tabInfo = mTabs.get(pos);
return Fragment.instantiate(mContext, tabInfo.clss.getName(), tabInfo.args);
}
}
//class for exceptions display
public static class ExceptionsSheet extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
int i = 1;
i = i+1;
//must include false, since we're attaching to the ViewPager sheet, not the root view.
return inflater.inflate(R.layout.exception, container, false);
}
}
//class for standard worksheet display
public static class Worksheet extends Fragment{
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
return inflater.inflate(R.layout.worksheet, container, false);
}
}
}