【问题标题】:Refreshing my fragment not working like I thought it should刷新我的片段没有像我认为的那样工作
【发布时间】:2011-07-08 17:37:09
【问题描述】:

我的 ListFragment 中有一个不错的方法,我调用它来填写其他片段的详细信息:

private void showClientDetails(int pos) {           
        myCursor.moveToPosition(pos);
        int clientId = myCursor.getInt(0);         
        if(mIsTablet) {

                // Set the list item as checked
                getListView().setItemChecked(mCurrentSelectedItemIndex, true);

                // Get the fragment instance
                ClientDetails details = (ClientDetails) getFragmentManager().findFragmentById(R.id.client_details);
                // Is the current visible recipe the same as the clicked? If so, there is no need to update

                if (details == null || details.getClientIndex() != mCurrentSelectedItemIndex) {
                        // Make new fragment instance to show the recipe
                        details = ClientDetails.newInstance(mCurrentSelectedItemIndex, clientId, mIsTablet);
                        // Replace the old fragment with the new one
                        FragmentTransaction ft = getFragmentManager().beginTransaction();
                        ft.replace(R.id.client_details, details);
                        // 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();
                }
        }
}

当用户在 ListFragment 视图中点击客户端时调用:

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
       mCurrentSelectedItemIndex = position;    
           showClientDetails(position);
}

这很好用,但是另一个 FragmentActivity 可以更改它显示的数据,所以我认为这会起作用:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) 
{

    super.onActivityResult(requestCode, resultCode, data);          
            //update the client list incase a new one is added or the name changes
    if(requestCode==1899)
    {               
      myCursor.requery();
      theClients.notifyDataSetChanged();
          showClientDetails(mCurrentSelectedItemIndex); //now if client was edited update their details in the details fragment
    }
}

现在我知道了:

if (details == null || details.getClientIndex() != mCurrentSelectedItemIndex) {

防止在我的 onActivityResult 中调用代码块。因此,如果我删除该 if 声明,那么事情就会变得异常,并且 ft.commit() 非常适合并给我错误:

`07-08 16:53:31.783: ERROR/AndroidRuntime(2048): Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

所以我想我想要做的并不像听起来那么简单,这对我来说毫无意义,因为我可以整天这样做 onListItemClicked 并且片段不断显示新点击客户端的详细信息嗯……

我什至在我的onActivityResult 中尝试过这个:

//simulate a click event really fast to refresh the client details
showClientDetails(0);
showClientDetails(mCurrentSelectedItemIndex);

什么都不做,是不是我试图从 onActivityResult 调用一些不是 Ui 线程的东西?

我的 ListFragment 代码中也有这个

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
outState.putInt("currentListIndex", mCurrentSelectedItemIndex);
}

这是错误所抱怨的吗?

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    另一个FragmentActivity 的操作是执行一项任务,该任务需要Fragment 通过调用onSaveInstanceState 来保存其状态,以准备重建一个新实例。例如,当我从一个填充整个屏幕的片段中触发一个活动时,我已经看到了这一点,因为这导致视图与片段分离,需要保存状态等。

    您基本上不能在onSaveInstanceState 和正在重新创建的片段的新实例之间调用commit。见commit

    至于解决方案,请重新考虑尝试避免在调用 commit 时调用它,或者如果您认为 UI 可以在用户上意外更改是可以的,也可以调用 commitAllowingStateLoss

    【讨论】:

    • 感谢您的回复。显示的客户端是从编辑客户端窗口更新的,所以我认为这并不意外,我认为 commitAllowingStateLoss 没问题。
    • 我使用了commitAllowingStateLoss,但是在方向改变时显示了警告对话框。
    【解决方案2】:

    我认为答案是不要在 onActivityResult 中进行任何片段事务。我相信发生的情况是,当调用 onActivityResult 时,它所在的活动尚未恢复并重新启动其片段。 使用处理程序将函数调用回发到活动。

    handler.post(new Runnable() {
        @Override
        public void run() {
            showClientDetails(mCurrentSelectedItemIndex);
        }
    });
    

    【讨论】:

    • 想知道如果您的应用程序在后台运行,并且在调用 onActivityResult 时保持在后台运行?
    【解决方案3】:

    你可以做另一件不太好但有效的事情。

    • 完成(你的活动)
    • 通过以下方式执行同一类的意图:

    Intent mIntent = new Intent(getApplicationContext(), YouClass.class);

    startActivity(mIntent);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-07
      • 2011-09-29
      • 1970-01-01
      • 2016-06-19
      • 2013-04-11
      • 2016-12-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多