在Android 文档中的 FragmentTransaction项中,描述了该方法replace()与为remove()当前视图中添加的所有片段调用方法相同,然后调用该方法add().在这种情况下,为了恢复前一个片段,我们可以使用addBackToStack(),这意味着事务状态仍由片段管理器管理,并在我们弹出堆栈时将反转其操作.
另一方面,当我们使用add()超出使用的实现事务时add().addBackToStack(),我们可以使用该detach()方法并使用attach()具有相同行为的片段来恢复addBackToStack().
那么这些场景之间的幕后差异是什么?
有没有办法如何更改正在进行的FragmentTransaction期间显示的片段的z顺序?我有一个动画,其中两个片段彼此重叠,我想让从右边滑动的片段(第二个片段)显示在另一个向下滑动的片段下面.现在它们在交易期间以相反的顺序显示.
这是我的一个动画的代码:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="400"
android:zAdjustment="bottom">
<scale android:toXScale="1"
android:fromXScale="0.9"
android:pivotX="50%p"
android:pivotY="50%p"
android:toYScale="1"
android:startOffset="300"
android:fromYScale="0.9"/>
<translate android:fromXDelta="50%p"
android:interpolator="@android:interpolator/overshoot"
android:toXDelta="0"/>
</set>
Run Code Online (Sandbox Code Playgroud)
这是交易的代码
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.show(fragmentToShow).hide(fragmentToHide).commit();
Run Code Online (Sandbox Code Playgroud)
我想让它fragmentToHide出现在fragmentToShow.我试图解决该android:zAdjustment属性,但由于它显然只适用于窗口动画,它只是没有为我工作.
android android-animation android-fragments fragmenttransaction
尝试从第一个片段启动片段时出现此错误:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.FragmentTransaction android.app.FragmentManager.beginTransaction()' on a null object reference
Run Code Online (Sandbox Code Playgroud)
这是我收到错误的方法:
@Override
public void onClick(View v) {
Fragment fragment = new PropertyFragment();
if (fragment != null) {
FragmentManager fragmentManager = fragment.getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
fragmentTransaction.replace(R.id.rent_viewer, fragment);
fragmentTransaction.addToBackStack(null);
// Commit the transaction
fragmentTransaction.commit();
}
}
Run Code Online (Sandbox Code Playgroud)
确切地说,以下代码指令导致错误:
fragmentManager.beginTransaction();
Run Code Online (Sandbox Code Playgroud)
以下是类和嵌套类的外观:
public class …Run Code Online (Sandbox Code Playgroud) 我有两个片段FragmentHome和FragmentAbout,我已经添加NavigationDrawer到应用程序,当我点击Home它打开FragmentHome并About打开FragmentAbout,当我打开FragmentAbout我也在它堆栈中.这工作正常.
现在的问题是,当我点击About并按回按钮它进入FragmentHome但NavigationDrawer仍然显示About所选项目时,我想将此选定项目更改为Home当我按下后退按钮时FragmentAbout
家庭活动:
public class ActivityHome extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
Toolbar toolbar;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
// Toolbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Drawer layout
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.nav_drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.nav_drawer_open, R.string.nav_drawer_close);
assert drawer != null;
drawer.setDrawerListener(toggle);
toggle.syncState(); …Run Code Online (Sandbox Code Playgroud) android android-fragments fragmenttransaction navigation-drawer fragment-backstack
我正在学习片段,下面给出的是我的第一个片段程序.一个简单的项目,我有2个屏幕.当我点击第一个屏幕的下一个按钮时,需要显示第二个按钮.

我的目标是Android 2.1及更高版本并使用兼容包
public class AppMainFragmentActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.app_main_layout);
}
}
Run Code Online (Sandbox Code Playgroud)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical" android:id="@+id/fragment_container">
<fragment class="com.research.fragmentstudy.FirstFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/id_first_fragment"/>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
public class FirstFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.first_fragment_layout
, container,false);
Button nextButton =(Button) view.findViewById(R.id.button);
nextButton.setOnClickListener(nextListener);
return view;
}
private OnClickListener nextListener = new OnClickListener() {
@Override
public void onClick(View v) …Run Code Online (Sandbox Code Playgroud) 我有一个分散布局的问题,如果之前已经回答过,我真诚地道歉,而且我太傻了,无法找到它.我搜索了几个小时,什么都没有(好吧,我有很多,但没有解决我的问题).
所以这是我的设置:我有一个两个窗格布局,使用两个FrameLayouts作为我的片段的容器.activity_listing.xml:
<FrameLayout android:id="@+id/listing" />
<FrameLayout android:id="@+id/details" />
Run Code Online (Sandbox Code Playgroud)
在打开app(片段活动中的onCreate)时,使用FragmentTransaction以编程方式将名为Listing的片段添加到FrameLayout"listing"中.
public class ListingActivity extends FragmentActivity
implements ListingFragment.Callbacks {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listing);
// Displaying the first listing here ...
Fragment fragment = new ListingFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.listing, fragment);
ft.addToBackStack(null);
ft.commit();
...
}
Run Code Online (Sandbox Code Playgroud)
这个ListingFragment在运行时被替换了几次,所以我必须创建它而不是用XML定义它.我试过后者
<fragment android:name="com.example.app.ListingFragment" />
Run Code Online (Sandbox Code Playgroud)
但是之后不会以编程方式替换或删除它.我只能添加()然后通过新的可见旧的.但这不是问题所在 - 只是对我的解释.
到目前为止,所有这些工作都应该如此,列表被创建和显示等,所以没有问题.但:
当在启动时显示ListingFragment并按下后退键时,在最后一个位置FrameLayout"listing"被清空而不是回退到主屏幕!我认为必须是因为我的ListingActivity的onCreate我显示一个空框架并向其添加()一个ListingFragment.所以后面的堆栈也有空框架.对?
我尝试通过这个解决情况到ListingActivity:
@Override
public void onBackPressed() {
super.onBackPressed();
if(getSupportFragmentManager().getBackStackEntryCount() == 0) {
this.finish();
}
}
Run Code Online (Sandbox Code Playgroud)
但不知怎的,这看起来并不正确......看起来好像是一个糟糕的工作.
那么有没有办法在视图之前插入片段,空的FrameLayout被充气,所以没有空状态"回"到?或者是否可以从后堆栈中删除"空"状态,即使它不在后面?关于如何在击退"后退"后避免空框架的任何其他想法?
非常感谢你提前做出的努力!
我使用show/hide来显示占据屏幕一部分的片段.出于某种原因,当显示片段时,slide_in_left动画播放,但是当片段被隐藏时没有动画,片段就会消失.我已经使用试过slide_in_left两个动画exit和enter,这并没有帮助.当将代码跟踪到支持包中时,动画确实被创建并且正在执行用于显示它的代码.(我跟踪了.hide电话)
FragmentManager fm = _activity.getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.my_fragment);
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_left);
if (fragment.isHidden()) {
ft.show(fragment);
fragment.setUserVisibleHint(true);
} else {
ft.hide(fragment);
}
ft.commit();
Run Code Online (Sandbox Code Playgroud)
以防万一这里是slide_out_left动画的xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="-50%p"
android:duration="@android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
Run Code Online (Sandbox Code Playgroud)
编辑:
问题可能与my_fragment分享屏幕宽度与另一个包含webview的片段的事实有关.当为my_fragment执行.show时,它变为可见并在水平线性布局内共享空间(两个片段中的每一个占用多少屏幕宽度由权重参数确定).
android android-animation android-fragments fragmenttransaction
我可以先将一个片段添加到视图中,然后"分离"它,然后将其"重新附加"到另一个视图中吗?
在代码中,我想:
fragOne one = new fragOne();
getSupportFragmentManager().beginTransaction()
.add(R.id.left, one, "tag").commit();
getSupportFragmentManager().beginTransaction()
.detach(one).commit(); // or .remove(), or .addToBackStack(null).remove()
getSupportFragmentManager().executePendingTransactions();
getSupportFragmentManager().beginTransaction()
.add(R.id.right, one).commit();
Run Code Online (Sandbox Code Playgroud)
但它会引发错误:
04-05 13:28:03.492: E/AndroidRuntime(7195): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.trybackstack/com.example.trybackstack.MainActivity}: java.lang.IllegalStateException: Can't change container ID of fragment fragOne{40523130 #0 id=0x7f080000 tag}: was 2131230720 now 2131230721
Run Code Online (Sandbox Code Playgroud)
感谢帮助!
android android-layout android-fragments android-fragmentactivity fragmenttransaction
我是Android开发的新手,现在遇到了奇怪的行为.
这是我的代码
public void showFragment(View v) {
FragmentA f = new FragmentA();
FragmentManager fm = getSupportFragmentManager();
String tag = f.getFragmentTag(); // instance method of a to get a tag
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_top, 0, 0, R.anim.slide_out_top);
ft.replace(R.id.container, f, tag);
ft.addToBackStack(tag);
ft.commit();
}
@Override
public void onBackPressed() {
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
} else {
super.onBackPressed();
}
}
Run Code Online (Sandbox Code Playgroud)
当用户第一次按下按钮时,它的行为与我的预期相同,将新片段添加到容器中.但是,第二次用户按下按钮时容器仍然包含一个片段,而不是替换,它在现有的一个上添加新的.所以,容器里面有2个碎片,2个按下去除所有碎片.
我发现如果我删除该行
ft.addToBackStack();
Run Code Online (Sandbox Code Playgroud)
并重做像下面的onBackPress()方法,它像我预期的那样再次工作(一次在容器中有1个片段)
基本上,手动删除片段而不是popFromBackStack方法
private FragmentA currentFragment = null; // …Run Code Online (Sandbox Code Playgroud) 我正在处理一些片段,但是从一个片段切换到另一个片段时的过渡动画非常滞后,有时甚至会跳过整个动画(我已经读过,有时这是片段性能不佳的结果)。
非常有趣的是,我在该片段中的所有数据获取和计算都是使用设置在计算线程上的协程完全异步完成的。包含数据的数组列表甚至不长或有很多参数。我在 UI 上做的唯一一件事就是在 RecyclerView Adapter 和 notifyDataSetChanged() 上设置最终列表 -> 就是这样!所以我的结论是 ViewHolder 膨胀本身就是导致滞后的原因。ViewHolders 的布局 XML 也非常精简(一个可绘制资源和三个字符串)。
在片段事务方面,我将当前片段替换为 FrameLayout 中的新片段,并使用一组自定义的 XML 对象动画器进行提交。
我已经看到一些答案说我应该将适配器上的项目设置延迟大约 2 秒钟,但是见鬼,最终用户在该片段中导航并在白屏上等待 2 秒钟之前看起来真的很糟糕数据突然出现。我想要一个平滑的 60fps 过渡到新片段,数据已经显示。
这件事在Android上甚至可能吗?我不是苹果迷,但就动画的流畅度和流畅度而言,iOS 设备在这个主题上破坏了 Android 的混乱局面。
我需要任何类型的建议甚至示例来向我展示如何解决此问题。
谢谢!
animation android fragment fragmenttransaction fragmentmanager