没有 activity 上下文的 ViewPager 片段
ViewPager's fragment without activity context
功能:
我正在开发某种配置向导,它可能有很多步骤。每个步骤都有自己的配置,在本例中,isSkippable()
用户是否可以跳过该步骤。以及当用户点击菜单项进入下一步或确实完成向导时的回调方法。
问题:我没有activity上下文,当从activity调用onStepCompleted
时我的字段也为空。
Activity 扩展了 ActionBarActivity
并且没有实现任何接口:
private WizardStepListener mStepListener;
private WizardPagerAdapter mPagerAdapter;
private ViewPager mViewPager;
public static Intent getIntent(final Context context) {
final Intent intent = new Intent(context, WizardActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP);
return intent;
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
if (mStepListener == null) {
return false;
}
switch (item.getItemId()) {
case R.id.action_step_skip:
moveToNextStep();
break;
case R.id.action_step_done:
case R.id.action_step_next:
final boolean stepCompleted = mStepListener.onStepCompleted();
if (stepCompleted && !isLastStep() || !stepCompleted) {
break;
}
final Intent intent = LandingActivity.getIntent(this);
WizardActivity.this.startActivity(intent);
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_right);
WizardActivity.this.finish();
break;
}
return true;
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wizard);
final Resources resources = getResources();
final PagerTabStrip pagerTabStrip = (PagerTabStrip) findViewById(R.id.pager_tab_strip);
pagerTabStrip.setDrawFullUnderline(false);
pagerTabStrip.setBackgroundColor(resources.getColor(R.color.tabs_categories_background));
pagerTabStrip.setTextColor(Color.WHITE);
pagerTabStrip.setTabIndicatorColor(Color.WHITE);
mPagerAdapter = new WizardPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.wizard_pager);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(final int position) {
setupView(position);
}
});
setupView(0);
}
private void setupView(final int position) {
final Fragment fragment = mPagerAdapter.getActiveFragment(mViewPager, position);
mStepListener =
fragment instanceof WizardStepListener ? (WizardStepListener) fragment : null;
supportInvalidateOptionsMenu();
}
private boolean isLastStep() { ... }
private boolean moveToNextStep() { ... }
}
扩展 Fragment
并实现 LoaderManager.LoaderCallbacks>、WizardStepListener 的片段:
private CategoriesExpandableAdapter mCatAdapter;
private ViewFlipper mViewFlipper;
/**
* @return A new instance of fragment WizardCategories.
*/
public static WizardCategories newInstance() {
return new WizardCategories();
}
@Override
public boolean isSkippable() {
return false;
}
@Override
public boolean onStepCompleted() {
if (!isAdded()) {
return false;
}
if (mCatAdapter == null || !mCatAdapter.hasCheckedCategories()) {
FeedbackToast.getInstance(
getActivity(),
"Debes seleccionar al menos una categoría",
FeedbackToast.NEGATIVE
).show();
return false;
}
...
return true;
}
扩展的 PagerAdapter FragmentPagerAdapter
:
private final FragmentManager mFragmentManager;
public WizardPagerAdapter(final FragmentManager fm) {
super(fm);
mFragmentManager = fm;
}
@Override
public Fragment getItem(final int position) {
final Fragment fragment;
switch (position) {
case 0:
fragment = WizardCategories.newInstance();
break;
default:
fragment = new Fragment();
break;
}
return fragment;
}
public Fragment getActiveFragment(final ViewPager container, final int position) {
final String name = makeFragmentName(container.getId(), position);
final Fragment fragment = mFragmentManager.findFragmentByTag(name);
return fragment != null ? fragment : getItem(position);
}
private static String makeFragmentName(final int viewId, final int index) {
return "android:switcher:" + viewId + ":" + index;
}
我试过的:
- 更改 PagerAdapter 扩展到
FragmentStatePagerAdapter
没有成功。
- 使用
getActiveFragment
从 FragmentManager 中检索片段,在另一个可能相关的帖子中看到。
补充评论:
- 片段的
isAdded()
总是 returns false。
- 在片段的
onStepCompleted
上调用 getActivity()
总是 returns null。
您应该能够使用 getActivity() 获取 Activity 并将上下文存储在您的片段中的 onCreate 中,要记住的主要事情是您需要在 onAttach 之后调用它已被调用,它将片段链接到 activity.
我目前在我的应用程序的 onCreate() 中使用 Activity 的上下文没有问题。
或者,您可以覆盖 onAttach 并直接获取对 Activity 的引用并将其存储在那里:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
参考:
Using context in a fragment
转动 table 并让向导片段自己保存 MenuItems 怎么样?然后他们可以直接调用 activity,例如 ((YourActivity)getActivity()).moveToNextPage()。
可以对一个通用的 WizardFragment 执行此方法,然后让所有向导页面从中扩展。
功能:
我正在开发某种配置向导,它可能有很多步骤。每个步骤都有自己的配置,在本例中,isSkippable()
用户是否可以跳过该步骤。以及当用户点击菜单项进入下一步或确实完成向导时的回调方法。
问题:我没有activity上下文,当从activity调用onStepCompleted
时我的字段也为空。
Activity 扩展了 ActionBarActivity
并且没有实现任何接口:
private WizardStepListener mStepListener;
private WizardPagerAdapter mPagerAdapter;
private ViewPager mViewPager;
public static Intent getIntent(final Context context) {
final Intent intent = new Intent(context, WizardActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP);
return intent;
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
if (mStepListener == null) {
return false;
}
switch (item.getItemId()) {
case R.id.action_step_skip:
moveToNextStep();
break;
case R.id.action_step_done:
case R.id.action_step_next:
final boolean stepCompleted = mStepListener.onStepCompleted();
if (stepCompleted && !isLastStep() || !stepCompleted) {
break;
}
final Intent intent = LandingActivity.getIntent(this);
WizardActivity.this.startActivity(intent);
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_right);
WizardActivity.this.finish();
break;
}
return true;
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wizard);
final Resources resources = getResources();
final PagerTabStrip pagerTabStrip = (PagerTabStrip) findViewById(R.id.pager_tab_strip);
pagerTabStrip.setDrawFullUnderline(false);
pagerTabStrip.setBackgroundColor(resources.getColor(R.color.tabs_categories_background));
pagerTabStrip.setTextColor(Color.WHITE);
pagerTabStrip.setTabIndicatorColor(Color.WHITE);
mPagerAdapter = new WizardPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.wizard_pager);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(final int position) {
setupView(position);
}
});
setupView(0);
}
private void setupView(final int position) {
final Fragment fragment = mPagerAdapter.getActiveFragment(mViewPager, position);
mStepListener =
fragment instanceof WizardStepListener ? (WizardStepListener) fragment : null;
supportInvalidateOptionsMenu();
}
private boolean isLastStep() { ... }
private boolean moveToNextStep() { ... }
}
扩展 Fragment
并实现 LoaderManager.LoaderCallbacks>、WizardStepListener 的片段:
private CategoriesExpandableAdapter mCatAdapter;
private ViewFlipper mViewFlipper;
/**
* @return A new instance of fragment WizardCategories.
*/
public static WizardCategories newInstance() {
return new WizardCategories();
}
@Override
public boolean isSkippable() {
return false;
}
@Override
public boolean onStepCompleted() {
if (!isAdded()) {
return false;
}
if (mCatAdapter == null || !mCatAdapter.hasCheckedCategories()) {
FeedbackToast.getInstance(
getActivity(),
"Debes seleccionar al menos una categoría",
FeedbackToast.NEGATIVE
).show();
return false;
}
...
return true;
}
扩展的 PagerAdapter FragmentPagerAdapter
:
private final FragmentManager mFragmentManager;
public WizardPagerAdapter(final FragmentManager fm) {
super(fm);
mFragmentManager = fm;
}
@Override
public Fragment getItem(final int position) {
final Fragment fragment;
switch (position) {
case 0:
fragment = WizardCategories.newInstance();
break;
default:
fragment = new Fragment();
break;
}
return fragment;
}
public Fragment getActiveFragment(final ViewPager container, final int position) {
final String name = makeFragmentName(container.getId(), position);
final Fragment fragment = mFragmentManager.findFragmentByTag(name);
return fragment != null ? fragment : getItem(position);
}
private static String makeFragmentName(final int viewId, final int index) {
return "android:switcher:" + viewId + ":" + index;
}
我试过的:
- 更改 PagerAdapter 扩展到
FragmentStatePagerAdapter
没有成功。 - 使用
getActiveFragment
从 FragmentManager 中检索片段,在另一个可能相关的帖子中看到。
补充评论:
- 片段的
isAdded()
总是 returns false。 - 在片段的
onStepCompleted
上调用getActivity()
总是 returns null。
您应该能够使用 getActivity() 获取 Activity 并将上下文存储在您的片段中的 onCreate 中,要记住的主要事情是您需要在 onAttach 之后调用它已被调用,它将片段链接到 activity.
我目前在我的应用程序的 onCreate() 中使用 Activity 的上下文没有问题。
或者,您可以覆盖 onAttach 并直接获取对 Activity 的引用并将其存储在那里:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
参考: Using context in a fragment
转动 table 并让向导片段自己保存 MenuItems 怎么样?然后他们可以直接调用 activity,例如 ((YourActivity)getActivity()).moveToNextPage()。
可以对一个通用的 WizardFragment 执行此方法,然后让所有向导页面从中扩展。