删除其他片段后,无法将新片段添加到LinearLayout

时间:2012-09-12 01:16:53

标签: android android-layout android-fragments

我有一些LinearLayouts用于包含片段。我正在使用兼容性库片段,管理器等。当我尝试重绘LinearLayouts的内容时,我首先删除所有片段,然后添加所需的内容。我不使用替换,因为我的理解是它并不总是按预期工作,我需要在布局中添加多个片段。接近,因为我可以告诉下面的代码应该工作,但是当它执行时,所有发生的是原始片段消失但新的片段不会出现。

相关代码如下:

public boolean onDrag(View v, DragEvent event) {
    int action = event.getAction();
    switch (action) {
    case DragEvent.ACTION_DRAG_ENTERED:
        Log.d(TAG, "ACTION_DRAG_ENTERED called on view: " + v + " with id: " + v.getId());
        handleActionDragEntered(v, event);
        break;
    default:
        break;
    }
    return true;
}

protected void handleActionDragEntered(View v, DragEvent event) {
    ArrayList<Integer> oldRow;
    switch (mState) {
    case TARGET_NOT_ENTERED:
        mState = State.TARGET_ENTERED_PARENT;
        mParentOld = mParentNew = (LinearLayout) v; //Save the parent row
        //Replace the drag view with a drop target. Need to lookup which row the parent row is.
        oldRow = mAdapter.replaceDragViewWithTarget(mDragView.getId(), 
                mRowIndices.get(mParentOld.getId()));
        redraw(mParentOld, oldRow, mAdapter.getIndiciesForRow(mRowIndices.get(mParentOld.getId())));
        break;
    case TARGET_ENTERED_PARENT:
        mState = State.TARGET_ENTERED_NEW_PARENT;
        mParentNew = (LinearLayout) v;
        oldRow = mAdapter.addDragViewToRow(mDragView, mRowIndices.get(mParentNew.getId()), getIndexInRow(event.getX(), v));
        redraw(mParentNew, oldRow, mAdapter.getIndiciesForRow(mRowIndices.get(mParentNew.getId())));
        break;
    default:
        Log.w(TAG, "Unhandled Action Drag Entered!");
    }
}

public void redraw(View v, ArrayList<Integer> oldRow, ArrayList<Integer> newRow) {
    FragmentManager fragmentManager = mParentActivity.getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    //fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
    for (int oldFragment : oldRow) {
        Log.d(TAG, "Removing fragment " + oldFragment);
        fragmentTransaction.remove(fragmentManager.findFragmentByTag(String.valueOf(oldFragment)));
    }
    fragmentTransaction.commit();
            fragmentManager.executePendingTransactions();
    fragmentTransaction = fragmentManager.beginTransaction();
    //fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
    for (int newFragment : newRow) {
        Log.d(TAG, "Adding fragment " + newFragment + " to row: " + v.getId());
        fragmentTransaction.add(v.getId(), mAdapter.getFragmentAtIndex(newFragment), String.valueOf(newFragment));
    }
    fragmentTransaction.commit();
}

LogCat中没有任何错误迹象,代码中的所有日志语句都会按预期报告值,包括片段的回调,通知他们正在创建视图。

更新

在视图容器上调用invalidate()无法解决问题。

更新2

根据访客用户的建议,我尝试将重绘代码包装在视图上发布的Runnable中。目前我的重绘代码在UI线程上执行,因此我认为这本身并不是必需的,但也许它可以让我们深入了解我的问题。我还编辑了上面的代码片段,以包含Wizetux的建议,并包含更多负责调用重绘函数的代码。所有这些都与Android的拖放组件有关。测试是在Galaxy Nexus 4.1设备上进行的,但我尝试过的所有设备的代码行为都是相同的。

更新3

如果我删除了删除事务并仅执行添加事务,则结果与预期一致,因此问题似乎与连续执行这两个事务有关。 Wizetux的建议对我来说很有意义,所以我没有正确执行它?

2 个答案:

答案 0 :(得分:1)

您是否在提交删除事务后尝试过,在执行添加之前调用fragmentManager.executePendingTransactions()。我想知道这些是否在管理器的执行中出现故障,因为它们在提交时并没有真正执行,而是被放到队列中。

答案 1 :(得分:0)

在尝试了发布者的所有(非常赞赏的)建议后,似乎没有什么能解决问题。结果,我重新设计并重写了负责我的应用程序的这一部分的代码,新的布局设计似乎没有问题。具体来说,没有片段的LinearLayout父母,而是直接使用GridLayout似乎解决了这个问题。我仍然没有看到为什么两种方法都无法工作的任何原因,但我会继续使用有效的方法,特别是因为少了一层布局是一个不错的性能提升。