【问题标题】:How to save the state of an interface in my fragment?如何在我的片段中保存接口的状态?
【发布时间】:2014-01-16 16:00:54
【问题描述】:

我有一个Activity,它使用ViewPagerViewPager 类中创建三个Fragments,我在创建它们时将Fragments 设置为setRetainInstace(true);

在我的Fragments 中,我正在显示一些可编辑的信息。这个Fragment 启动DialogFragment 来编辑信息。

当用户不改变方向时,我可以更新信息并将结果发送回视图中的片段,但是,一旦我改变方向,并对我的Interface 的信息进行更新@附加在DialogFragments onAttach() 方法中,我得到了NullPointerException

我不明白为什么,因为每次启动新的DialogFragment 时,总是会调用onAttach() 方法。

我应该如何解决这个问题? 我可以保存接口的状态吗?如果是的话怎么办?

这是我的 DialogFragment 代码: GenericDialogFragment 类仅用于更改外观

public class Fragment1 extends GenericDialogFragment implements WebServiceResult{



// -------------------------------------------------------------------------
// Member Variables
//--------------------------------------------------------------------------
//Webservice Callback
private WSRequest mActiveRequest = null;
// The Current Context of the Application
private Context mClassContext = null;
// Interface reference for communication
private static CommunicateResults communicateResults = null;


// -------------------------------------------------------------------------
// New Instance Method
//--------------------------------------------------------------------------    

public static Fragment1 newInstance(int userId, GenericObject [] objects, GenericGroup [] groups, Object currentObject){
    // Initialize a new Fragment1
    Fragment1 fragment = new Fragment1();
    // Create a new Bundle
    Bundle args = new Bundle();

    fragment.setArguments(args);

    // Return the Fragment1
    return fragment;
}

// -------------------------------------------------------------------------
// Class Functions / Methods
//--------------------------------------------------------------------------    

// States that the Interface is attached to the parent activity
@Override public void onAttach(Activity activity)
{
    // Perform the Default Behavior
    super.onAttach(activity);
    Log.d("ONAttach()","On attach() is called" );
    // Try 
    try{
        // Attach the interface to the activity
        communicateResults = (CommunicateResults) ((MainActivity)  getActivity()).findFragment(EditableFragment1.class);

    }catch(Exception ex){
        // Print the stack trace
        ex.printStackTrace();
    }
}

// States that the Dialog's View has been Created
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
    // Return the Inflated XML Layout
    return inflater.inflate(R.layout.fragment1, container, false);
}

// States that the fragment has been created, last chance to update the UI
@Override
public void onActivityCreated(Bundle savedInstanceState){
    // Perform the Default behavior
    super.onActivityCreated(savedInstanceState); 

    mClassContext = getActivity();

    // Get the Arguments passed into the Fragment instance
    savedStateData = getArguments();

    // Reference all the UI Elements in the View    


    // Add listeners to the Button Widgets


    // If the savedInstanceState is not null, get the current object
    if(savedStateData != null){

        // Get the object out of the state data
        mCurrentObject = savedStateData.getParcelable(STATE_DATA_CURRENT_OBJECT);

    }



}


//-----------------------------------------------------------------------------
// Webservice Callback methods
//-----------------------------------------------------------------------------

// States that the web service has succeeded 
@Override public void webserviceSucceeded(WebServiceBase finishedService, Object responseData) 
{

    Log.d("EDIT Object", responseData.toString());

    if(responseData != null){

        if(mDeletingObject){



            // Send Back to the object to remove
            communicateResults.sendBackData(mCurrentObject, ACTION_DELETE);

        }else{

            JSONObject tempObject = (JSONObject) responseData;

            try{

                // Parse Data ...



            }catch(Exception ex){

                ex.printStackTrace();
                // TODO: The Object was deleted from the Lest
            }

            // If we are creating a object, bundle the information to pass to the parent activity
            if(mCreatingObject){

                // Create a new Workout Object
                mCurrentObject = new Object();


                // Callback to Parent Activity to notify that data has changed
                communicateResults.sendBackData(mCurrentObject, ACTION_CREATE);

                // Else the Object was updated
            }else{
                // Create a new  Object
                mCurrentObject = new Object();


                // Callback to Parent Activity to notify that data has changed
                communicateResults.sendBackData(mCurrentObject, ACTION_UPDATE);
            }
        }


    }

    // Dismiss the fragment


}


// States that the web service has failed
@Override
public void webserviceFailed(WebServiceBase finishedService,
        Object errorData) {


    // Display the Error
    displayErrorData(errorData);

}

}

【问题讨论】:

  • 听起来你的Activity就是你的接口,如果你使用onAttach(Activity activity);,那么为什么不直接使用(CastToInterface)getActivty();?
  • 我的活动不是我的界面。该接口是在我的 Fragment 中声明的,带有可编辑的数据。所以我在这个片段中创建了一个接口,然后我在 DialogFragment 中实现它。我尝试进行此更改并得到 ClassCastException,因为这会尝试将接口强制转换为未实现的 Activity
  • 明白了。你能发布你的片段代码吗?
  • 添加了我的 DialogFragment 如果你想看看我在哪里附加接口。 @Submersed
  • 这是一个嵌套片段吗?在这种情况下,使用 getParentFragment() 来获取对父片段的引用。

标签: android interface fragment dialogfragment


【解决方案1】:

我认为您正在寻找onActivityCreated(Bundle bundle);,这是Fragment 等效于Activity 类的onRestoreSavedInstanceState(Bundle bundle);

来自文档:

public void onActivityCreated (Bundle savedInstanceState) 添加在 API 级别 11

当片段的活动被创建并且这个 片段的视图层次结构实例化。可以用来做final 一旦这些部分就位,初始化,例如检索 视图或恢复状态。它对于使用的片段也很有用 setRetainInstance(boolean) 保留他们的实例,作为这个回调 告诉片段何时与新活动完全关联 实例。这在 onCreateView(LayoutInflater, ViewGroup, Bundle) 和 onViewStateRestored(Bundle) 之前。参数 savedInstanceState 如果片段是从一个 之前保存的状态,就是这个状态。

当你的fragment因方向改变而被销毁时,将其状态保存为名称值对在Activity的Bundle中,然后当它需要重新创建时,在此方法中实例化一个新的Interface,并设置相应的字段/retrieve the parcelable in your new Fragment instance.

【讨论】:

  • 这里有点困惑。如果每次创建新的 DialogFragment 时都调用 onAttach() 方法,这不重要吗?或者这是我实现接口的片段中的问题?
  • 不确定,我得看看你是如何实现你的片段的。
  • 片段中有大量代码,我将尝试将其配对,因此我只分享您需要的内容。
  • 好的,所以即使在调用 onAttach() 之后,我也会在方向改变时记录接口及其 null。当我记录活动时,它不为空。所以我认为当方向改变时它的片段类为空
  • 还不足以摆脱,只是猜测。如果您可以发布您的堆栈跟踪和活动,我会稍后再回来查看。
猜你喜欢
  • 1970-01-01
  • 2017-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多