【问题标题】:Transferring one fragment among two frameLayouts in one activity programmatically以编程方式在一个活动中的两个 frameLayouts 之间传输一个片段
【发布时间】:2017-07-28 20:48:33
【问题描述】:

在我的应用中(横向时),在同一个 Activity 中有两个 frameLayout,一个在左边,一个在右边。

左侧是一个listView(菜单),右侧应该显示listView(“表格”)或表单片段。

现在,如果从右侧 frameLayout 的“表格”中选择了一个项目,则该“表格”片段应该转移到左侧的 frameLayout,而不是那个“表格”片段,现在出现一个新片段.

那么,我的问题是如何以编程方式将一个片段从一个 frameLayout 转移到同一活动中的另一个 frameLayout?

基本上问题是如何在一个活动中将一个片段从一个视图转移到另一个视图。

我尝试使用片段事务删除/替换,但无法执行此操作,因为右侧 frameLayout 中的片段具有该 frameLayout 的 ID,这与右侧 frameLayout 不同。

应用程序的流程应该类似于以所述方式将所有其他片段从一个 frameLayout 切换和替换到另一个。

所以,如果有人知道怎么做,我将不胜感激。

提前致谢。

【问题讨论】:

    标签: android transactions fragment


    【解决方案1】:

    在你的“table”片段中定义一个interface,界面应该是这样的:

    public interface FragmentReplacerListerner{
    
        void replace();
    
    }
    

    在你的 Activity 中实现这个接口。

    现在,在 "table" 片段的 onAttach() 方法中,将您的活动转换为替换器。需要替换时,在“table”片段中调用监听器的replace()方法。

    在你的活动中实现这样的回调

    void replace(){
       //replace your left FrameLayout with right fragment
       // inflate the right FrameLayout with new Fragment
    }
    

    这里是link 的示例应用实现

    【讨论】:

    • 感谢您的回答,我已经尝试过您的解决方案,但它不起作用,并且我收到与之前相同的错误:“java.lang.IllegalStateException: Can't change container ID of片段 TableFragmentNew{cfdfb17 #2 id=0x3ea}: was 1002 now 1001" 问题是片段获取了它之前所在的 frameLayout 的 ID,如果我尝试将它放在“左侧 frameLayout”中一个不同的 ID 它抛出异常...
    • 需要先从右边的FrameLayout中移除,然后再添加到左边的FrameLayout中。
    • 请看下面我的方法 replace() 的实现,如果你能评论它.. 谢谢
    • 好的,谢谢你的例子。我已经尝试过这个例子,它的工作原理和它说的一样,但是,我忘了提到......我需要将事务放在后台,因为当用户按下(在工具栏/动作栏中)时,事务必须反转。另一个问题是,当我在“左侧”有表时,从表中选择了几条记录后,当按下返回时,它需要返回到“主菜单 - 表”状态,而不是返回之前打开的所有记录.这是一个棘手的应用流程...
    • 所以 LANDSCAPE 中的流程如下: 1. 左 - 主菜单,右 - 空 2. (从菜单中选择某些内容) - 左 - 主菜单,右表或表格。 3.(如果从表中选择记录) - 左表,右表,记录详细信息。 4.(如果从表中选择了另一条记录) - 左表,右表,记录详细信息。 5.(如果按下返回)- 左主菜单,右表。
    【解决方案2】:

    好的,这就是替换方法中的内容:

    @Override
    public void replace() {
        TableFragmentNew tableFragmentNew = (TableFragmentNew)fragManager.findFragmentById(frameLayoutLand.getId());
        fragTransaction.remove(tableFragmentNew).commit();
        fragManager.executePendingTransactions();
        fragTransaction = fragManager.beginTransaction();
        fragTransaction.add(frameLayout.getId(), tableFragmentNew);
        fragTransaction.addToBackStack(null)
        fragTransaction.commit();
    }
    

    这样可以吗?

    【讨论】:

    • 今天午餐时间我会为你写一个示例代码。希望到那时还不会太晚。
    • 提前致谢。我正在实现完全不同的方法,只需在一个容器中添加和删除片段。但我想在一个活动中看到两个不同 FrameLayouts 的解决方案。
    • 没问题...我会这样做的。
    【解决方案3】:

    好的,经过数小时和数小时的测试,我想出了这个解决方案来解决将片段从一个容器转移/移动到另一个容器的问题。有两个 FrameLayout 视图就是这种情况。

    //First create New fragment which should replace the one in the RIGHT FrameLayout
    MyFragmentForRightFrameLayout myFragmentForRightFrameLayout = new MyFragmentForRightFrameLayout;
    Bundle bundle = new Bundle();
    //Set whatever arguments to a Bundle
    bundle.set.... ;
    //Find last fragment on BackStack, or find it by ID of the container in which the FragmentToMove resides, and get it so you can get its Bundle arguments  
    Fragment fragmentToMove = fragManager.findFragmentByTag(fragManager.getBackStackEntryAt(fragManager.getBackStackEntryCount() - 1).getName());
    //Instantiate the same type of fragment as the one you want to remove
    YourFragment fragmentToAdd = new YourFragment();
    //Set arguments to a new Fragment FROM the fragment you found on a backstack    
    fragmentToAdd.setArguments(fragmentToMove.getArguments());
    fragmentTransacion = fragmentManager.beginTransaction();
    //Replace the fragment in right FrameLayout with new fragment (whichever type)
    fragTransaction.replace(frameLayoutRight.getId(), myFragmentForRightFrameLayout, "Tag for this Fragment");
    //And finaly replace the left FrameLayout fragment with the newly created fragment of the same type as the one you wish to move to the left FrameLayout
    fragTransaction.replace(frameLayoutLeft.getId(), fragmentToAdd, "Tag for this fragment");
    fragTransaction.addToBackStack("Tag for transaction" or null);
    fragTransaction.commit();
    

    好的,所以问题在于,当您尝试将片段从一个容器(在我的情况下为 FrameLayout)移动到另一个容器时,您不能通过查找片段并简单地替换它来直接执行此操作,因为它有一个 ID的 RIGHT FrameLayout,片段在添加到 RIGHT FrameLayout 时得到的。 Fragment的ID不能删除,也不能设置新的。

    因此,您需要制作一个相同类型的新片段,该片段没有 ID,并将您要删除/替换的片段中的捆绑包设置到其中。

    @Ekundayo Blessing Funminiyi 给出的解决方案的主要问题是无法回到之前的状态。因此,此解决方案可以导航回之前的屏幕(片段组合)。

    而且,就是这样。快乐编码。我希望这对将来的人有所帮助。

    【讨论】:

    • 不错。很高兴您终于找到了可行的解决方案。编码愉快!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多