我目前正在为我即将开发的应用程序奠定基础。有一个动作栏,分配了几个菜单项。每个菜单项都有自己的片段,需要在主活动中显示。但是,我想要" up"当显示除MainFragment本身之外的任何片段时,动作栏的可供性。
我目前的方法是基于actionbar up navigation with fragments提出的解决方案,看起来像这样:
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
int id = item.getItemId();
Fragment fragment = null;
if (id == R.id.action_identities) {
fragment = new IdentitiesFragment();
} else if (id == R.id.action_history) {
fragment = new HistoryFragment();
} else if (id == R.id.action_settings) {
fragment = new SettingsFragment();
} else if (id == R.id.action_about) {
fragment = new AboutFragment();
}
if (fragment != null) {
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.container, fragment);
transaction.addToBackStack(null);
transaction.commit();
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
@Override
public void onBackStackChanged()
{
displayHomeAsUp();
}
private void displayHomeAsUp()
{
int stackCount = getFragmentManager().getBackStackEntryCount();
getActionBar().setDisplayHomeAsUpEnabled(stackCount > 0);
}
@Override
public boolean onNavigateUp()
{
getFragmentManager().popBackStack();
return true;
}
这很有用,但是多次按下同一个菜单项时会出现问题,因为片段的新实例每次都会放在后面的堆栈上。防止这种情况发生的最佳方法是什么?显然,我可以检查当前显示的片段是否是被请求的片段,但这会导致大量检查并且是多余的。另一种方式可能是交易代码,但我不确定这是否会导致代码更清晰。
最好的方法是什么?这不是一般问题,或者是我希望应用程序表现出来的方式"错误?因为我个人喜欢" up"动作栏的功能相当多。
答案 0 :(得分:1)
这就是我解决这个问题的方法
在每个片段上附加一个标签,然后在后栈中添加任何片段之前检查它是否已在堆栈中可用?
示例代码
public void replaceFragment(Fragment fragment, String FRAGMENT_TAG) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.container, fragment, FRAGMENT_TAG);
if (getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG) == null) {
if (AppConstants.DEBUG) {
Toast.makeText(MainActivity.this, "Inside Fragment add", Toast.LENGTH_SHORT).show();
}
fragmentTransaction.addToBackStack(FRAGMENT_TAG);
}
fragmentTransaction.commit();
}
答案 1 :(得分:0)
你可以通过布尔检查它简单干净......
假设你有4个片段,所以每次你按下其中一个片段时它需要4个布尔检查,其对应的布尔值将为真,下次你按下它时不会添加到片段,直到你后退它...
if (identity == true && id == R.id.action_identities) {
fragment = new IdentitiesFragment();
identity = true;
} else if (history == true && id == R.id.action_history) {
fragment = new HistoryFragment();
history = true;
} else if (setting == true && id == R.id.action_settings) {
fragment = new SettingsFragment();
setting = true;
} else if (about == true && id == R.id.action_about) {
fragment = new AboutFragment();
about = true;
}
答案 2 :(得分:0)
您可以将所选菜单ID保存为Integer
,下次您可以使用前一个ID检查所选ID,并仅在ID不同时添加片段
private int previousSelectedId = 0;
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
int id = item.getItemId();
if(previousSelectedId == id) {
return true;
}else{
previousSelectedId = id;
// add the fragment
}
}
另一种方法是,您可以查看已存在的instance
的{{1}},只有在它不存在时才替换。
Fragment
Fragment addedFragment = getSupportFragmentManager().findFragmentById(R.id.container);
if (addedFragment != null &&
!addedFragment.getClass().isInstance(fragment)) {
// replace the fragment here
return true;
}
是已添加片段的实例。 addedFragment
是基于所选菜单项的实例。
注意:我不建议您使用fragment
或getClass()
。但要简单地检查一下,我可以提出建议。