Wait until fragment has been added to the UI

泄露秘密 提交于 2020-02-02 02:48:33

问题


In my app I got to a point where, in landscape mode, I need to attach two fragments. In order to do that, the second fragment needs to wait until the first fragment has been attached (added), before it's being added. The reason for it is that the first fragment needs to execute a function that the second fragment needs. I managed to do that via a thread, but in this case it only waits the amount of time indicated, before attaching the second fragment, and in case the first fragment isn't attached in the time given, the app will crush because the second fragment doesn't have the necessary data.

Any better practices (examples) then the code below (like waiting until the first fragment is attached, and no on a certain time interval) ? :

getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.mainContent, fragment).commit();
        Thread thread = new Thread() {
            @Override
            public void run() {
                try {
                    synchronized (this) {
                        wait(1000);
                    }
                } catch (InterruptedException e) {

                }
                if (isLandscape) {
                openSecondFragment(mIndex, R.id.rightConent);
                }
            }
        };
        thread.start();

Much appreciated.

The handler i need to be executed in the first fragment:

@SuppressLint("HandlerLeak")
protected void loadAccountList() {

    LoadAccountList loadAccountListThread = new LoadAccountList(new Handler() {

        @SuppressWarnings("unchecked")
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case LOAD_SUCCESSFUL_CODE:
                items = (ArrayList<Account>) msg.obj;
                break;
            case LOAD_FAILED_IOEXCEPTION_CODE:
                getActivity().showDialog(ERROR_DIALOG);
                break;
            default:
                break;
            }
        }
    });
    loadAccountListThread.start();

回答1:


Fragments lifecycle works in your favor here. According to the documentation the method onStart() is "Called when the Fragment is visible to the user", so I suggest you do something like this in your first fragment class:

public void onStart() {

    super.onStart();
    ((MainActivity)getActivity()).loadSecondFragment();
}

And in your Activity:

public void loadSecondFragment() {
    if (isLandscape) {
        openSecondFragment(mIndex, R.id.rightConent);
    }    
}

And voilá! Try any of the lifecycle methods and see which one works best for your purpose.




回答2:


onCreateView is called when Fragment is created

public static class CustomFragment extends SupportMapFragment{

        public CustomFragment() {}

        @Override
        public View onCreateView(LayoutInflater arg0, ViewGroup arg1, Bundle arg2) {
            return super.onCreateView(arg0, arg1, arg2);

        }
}



回答3:


first off @SuppressLint("HandlerLeak") is bad. If you're not carefull with leaks, you're memory is gonna fill up.

My solution (it's a personal preference)

I like to use Otto to pass around messages while still having loose coupling. It allows you to set-up an EventBus to which different classes can simply register and receive the events they want. In this case, you could make a helper class which loads the data and fires an event when it has received the data (or an error). Then you catch this in your second fragment and populate your list. (in the meantime you can show an indefinite progressbar or something)

This way, you don't have to wait for the data to be received before you load your fragment.

You can find the documentation here: https://github.com/square/otto



来源:https://stackoverflow.com/questions/28457015/wait-until-fragment-has-been-added-to-the-ui

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!