Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Freezing UI when fragment transaction

I'm facing problem with replacing fragment using FragmentManager. My problem is freezing the UI. I'm trying to find some good practices and/or library to handle my problems.

Part of my code:

Main activity layout:

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/my_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<FrameLayout
    android:id="@+id/content"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

</android.support.v4.widget.DrawerLayout>

Main activity class

public class MyActivity extends Activity 

with method

  public void nextFragment(Fragment fragment, int position) {
    fragment.setArguments(new Bundle());
    FragmentManager fragmentManager = getFragmentManager();
    fragmentManager
            .beginTransaction()
            .replace(R.id.content, fragment).commit();

}

Each of my fragment is like

import android.app.Fragment;

public class SomeFragment extends Fragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    RelativeLayout rootView = (RelativeLayout) inflater.inflate(
            R.layout.fragment_layout, container, false);
    //many long time data downloading & creating view
    }

private void nextFragment() {

        ((MyActivity) getActivity()).nextFragment(
                new SomeNextFragment(), 0);

    }
}

Now because of downloading data on each fragment start my UI is freezing. Thanks in advance for any help.

like image 630
Meryl Avatar asked Nov 01 '22 20:11

Meryl


1 Answers

As a rule, you should not do the long running/blocking operations on the UI thread. Either use a worker thread or an AsyncTask.

Generally, I would suggest that you create whatever you can in onCreateView then set values after the background operation is complete. For example, create a TextView right away, then when you get the result from the background operation, then set the text in the already existing TextView.

To use a thread:

final Handler handler = new Handler();
new Thread(new Runnable(){
    @Override
    public void run(){
       //long running code
       //this is running on a background thread
       final String someText = //result of long running code
       handler.post(new Runnable(){
           @Override
           public void run(){
               //since the handler was created on the UI thread,
               //   this code will run on the UI thread
               someTextView.setText(someText);
           }
       });
    }
}).start();

You can also use getActivity().runOnUiThread(new Runnable(){...}); instead of using Handler

like image 95
Reed Avatar answered Nov 11 '22 04:11

Reed