片段 有效地替换片段和导航片段

发布于 2024-11-26 10:31:23 字数 4050 浏览 1 评论 0原文

所以我有这个 ClientListView ,它工作得很好,可以显示客户,我可以单击客户并在右侧获取他们的详细信息(在我的第二个片段中)。由这里的布局定义:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">

<fragment class="com.viciousbytes.studiotab.subactivities.ClientListView"
        android:id="@+id/client_list" android:layout_weight="1"
        android:layout_width="0px" android:layout_height="match_parent" />

<FrameLayout android:id="@+id/client_details" android:layout_weight="1"
        android:layout_width="0px" android:layout_height="match_parent"
        android:background="?android:attr/detailsElementBackground" />
</LinearLayout>

这很好用,但后来我意识到我拥有的另一个活动(即显示片段的片段活动)占据了整个屏幕,并且分成两个会更好。

因此,我开始更改一些最初显示此片段活动的代码,

void showSessionEdit()
{
 ...

 Intent intent = new Intent(getActivity(), EditSessionActivity.class);
            //  Send the recipe index to the new activity
            intent.putExtra(EditSessionActivity.THE_SELECTED_CLIENT, (int)mClient.getID());
            intent.putExtra(EditSessionActivity.SELECTED_SESSION, sessionId);
            startActivityForResult(intent, 1899); 
 ....
}

这效果很好,打开了我的会话编辑器,我单击“返回”,返回我的客户和详细信息。尽管我意识到我希望我的会话编辑器更像我的客户列表/详细信息,它们都在同一屏幕上。经过大量的错误尝试,我最终用这个替换了上面的内容:

void showSessionEdit()
{
 ...
    SessionEdit details = (SessionEdit) getFragmentManager().findFragmentById(R.id.session_edit);               
                // Make new fragment instance to show the recipe
                details = SessionEdit.newInstance(mContext, mIsTablet, (int)mClient.getID(), sessionId);
                // Replace the old fragment with the new one
                FragmentTransaction ft = getFragmentManager().beginTransaction();                   
                ft.replace(R.id.client_list, details);
                ft.addToBackStack("client_list");
                // Use a fade animation. This makes it clear that this is not a new "layer"
                // above the current, but a replacement
                ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);                            

      ft.commit();
              ...
              //now add another fragment to the right, just to test i dont have my invoice fragment done yet so I just added session again to see if it would display it does.

SessionEdit details2 = (SessionEdit) getFragmentManager().findFragmentById(R.id.session_edit);              

                // Make new fragment instance to show the recipe
                details2 = SessionEdit.newInstance(mContext, mIsTablet, (int)mClient.getID(), sessionId);
                // Replace the old fragment with the new one
                FragmentTransaction ft2 = getFragmentManager().beginTransaction();
                ft2.replace(R.id.client_details, details2);
                ft.addToBackStack("client_details");
                // Use a fade animation. This makes it clear that this is not a new "layer"
                // above the current, but a replacement
                ft2.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);                           

      ft2.commit();
 ...
}

这效果很好,尽管我意识到我替换的不是 "div" 可以说是布局,而是片段本身,因此,我对 findFragmentById 的引用不再是 client_details 类型或 client_list 类型,而是现在的 SessionEdit 类型。因此,经过更多的尝试和错误,我学会了将标签添加到 addToBackStack(tag) 中,现在我可以找到fragmentsByTag,这效果很好,并且后退按钮有点有效:单击后退将替换左侧的 client_list再次单击客户端并在右侧获取其详细信息,问题是,如果我的 client_list 再次返回,右侧的详细信息仍然会显示我的会话片段。另一个问题是我的客户列表是一个 ListFragment,所以当我进行替换时,我仍然可以看到新片段下方的列表,就像它是赛璐珞或其他东西一样。很奇怪。

因此,我在用新片段替换原始片段方面取得了一些进展,但是使用后退按钮导航不再像我刚刚执行两个片段并相互添加新活动时那样“开箱即用”。那么如何在多个片段之间进行导航呢?理想情况下,我会有一个 SessionInvoiceActivity ,它将同时替换两个片段(左侧的客户列表,右侧的客户详细信息),左侧的会话,右侧的发票。当单击后退按钮时,我会返回我的客户列表和客户详细信息吗?但这我不知道该怎么做,并且仍然传递我需要的信息。我也仍然不清楚为什么当我替换片段时,原来的片段可以在下面看到?是xml布局定义问题吗?

So I have this ClientListView that works great, shows clients, I can click on a client and get their details on the right (in my second fragment). Defined by this layout here:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">

<fragment class="com.viciousbytes.studiotab.subactivities.ClientListView"
        android:id="@+id/client_list" android:layout_weight="1"
        android:layout_width="0px" android:layout_height="match_parent" />

<FrameLayout android:id="@+id/client_details" android:layout_weight="1"
        android:layout_width="0px" android:layout_height="match_parent"
        android:background="?android:attr/detailsElementBackground" />
</LinearLayout>

This works great, but then I realized another activity I had (that was a fragmentactivity displaying a fragment) took up the whole screen, and would be better served being split into two.

So I went about changing some code that displayed this fragment activity originally

void showSessionEdit()
{
 ...

 Intent intent = new Intent(getActivity(), EditSessionActivity.class);
            //  Send the recipe index to the new activity
            intent.putExtra(EditSessionActivity.THE_SELECTED_CLIENT, (int)mClient.getID());
            intent.putExtra(EditSessionActivity.SELECTED_SESSION, sessionId);
            startActivityForResult(intent, 1899); 
 ....
}

This worked great, brough up my session editor, i click back I get back to my clients and details. Though I realized I want my session editor to work more like my client list /details which has both on same screen. Through lots LOTS of trial of error I finally did replaced the above with this:

void showSessionEdit()
{
 ...
    SessionEdit details = (SessionEdit) getFragmentManager().findFragmentById(R.id.session_edit);               
                // Make new fragment instance to show the recipe
                details = SessionEdit.newInstance(mContext, mIsTablet, (int)mClient.getID(), sessionId);
                // Replace the old fragment with the new one
                FragmentTransaction ft = getFragmentManager().beginTransaction();                   
                ft.replace(R.id.client_list, details);
                ft.addToBackStack("client_list");
                // Use a fade animation. This makes it clear that this is not a new "layer"
                // above the current, but a replacement
                ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);                            

      ft.commit();
              ...
              //now add another fragment to the right, just to test i dont have my invoice fragment done yet so I just added session again to see if it would display it does.

SessionEdit details2 = (SessionEdit) getFragmentManager().findFragmentById(R.id.session_edit);              

                // Make new fragment instance to show the recipe
                details2 = SessionEdit.newInstance(mContext, mIsTablet, (int)mClient.getID(), sessionId);
                // Replace the old fragment with the new one
                FragmentTransaction ft2 = getFragmentManager().beginTransaction();
                ft2.replace(R.id.client_details, details2);
                ft.addToBackStack("client_details");
                // Use a fade animation. This makes it clear that this is not a new "layer"
                // above the current, but a replacement
                ft2.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);                           

      ft2.commit();
 ...
}

This works well, though i realized that I was replacing not the "div" so to speak on the layout but the fragment itself, so my references to findFragmentById were no longer my client_details type or client_list type but now a SessionEdit type. So after more trial and error i learned to add the tag to addToBackStack(tag) and I could find fragmentsByTag now, this worked well, and back button sorta worked: Clicking back would replace my client_list on the left again so I could click clients and get their details on the right, the problem is, if my client_list was back again the details on the right would still show my session fragment. Also another issue is my clients list was a ListFragment, so when I did the replace, I could still see the list like underneath the new fragment, as if it was celluloid or something. Very strange.

So I made some headway on replacing my original fragments with new ones, but navigating using the back button no longer works "out of the box" like it did when I was just doing the two fragments, and adding new activities onto each other. So how does one go about navigating around multiple fragments? Ideally I would have a SessionInvoiceActivity that would replace both fragments at once (The client list on left, client details on right) with the session on left, invoices on right. And when the backbutton is clicked, id get back to my client list and client details? But this I am not sure how to do and still pass in the information I need. I am also still not clear as to why when I replace the fragment, the original fragment can be seen underneath? Is it a xml layout definition issue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

七分※倦醒 2024-12-03 10:31:23

我不确定你现在是否明白了这一点,看来我已经落后了一个夏天。

我发现布局中指定的片段(在 XML 中)和使用 FragmentManager 添加的片段很难混合。

我遇到了类似的问题,我在 onCreate() 中添加了我的“主”片段,然后当通过大小或用户选择认为有必要时,第二个片段“详细信息”片段要么放在“主”片段所在的位置,要么添加到如果处于横向模式,则为第二种布局。当用户按下后退键时,它将显示一个空白屏幕,没有“主”片段。我想我可能已经通过最初的调用在活动的 onStart() 中显示我的“主”片段来解决这个问题。然而,这似乎还有一个问题。从 onStart() 添加“主”片段时,请勿将事务添加到 BackStack。这样,将调用 onResume() 或之前 Activity 中的任何内容,从而不会使 Activity 留下空白屏幕。

I am not sure if you have figured this out now, seems I am a summer behind.

I found fragments specified in layouts (in XML) and fragments added with the FragmentManager are difficult to mix.

I am having a similar issue being I add my "Master" Fragment in onCreate(), then when deemed necessary through size or user selection a second fragment the "Details" Fragment is either put where the "Master" Fragment was or is added to a second layout if it is in landscape mode. When the user hits the Back Key it will show a blank screen with no "Master" Fragment. I thought I may have had a work around for this by making the original call to display my "Master" Fragment in the onStart() of the Activity. Yet there seems to be one more gotcha to this. When adding the "Master" Fragment from the onStart() DO NOT add the transaction to the BackStack. That way the onResume() or whatever from your previous Activity will be called instead, thus not leaving an Activity with a blank screen.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文