【问题标题】:Freezing UI when fragment transaction片段交易时冻结 UI
【发布时间】:2014-07-21 15:23:11
【问题描述】:

我在使用 FragmentManager 替换片段时遇到问题。我的问题是冻结 UI。我正在尝试寻找一些好的做法和/或库来处理我的问题。

我的部分代码:

主要活动布局:

<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>

主要活动类

public class MyActivity extends Activity 

用方法

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

}

我的每一个片段都像

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);

    }
}

现在由于在每个片段开始下载数据,我的 UI 冻结。提前感谢您的帮助。

【问题讨论】:

  • 您正在使用带有 android.app.Fragments 的 support.v4 布局,我不知道为什么。将extends Activity 更改为extends FragmentActivity,将getFragmentManager() 更改为getSupportFragmentManager()。将 android.app.Fragment 导入更改为 android.support.v4.Fragment
  • 我正在使用 navigationDrawer 并通过 android 开发者网站示例我正在使用这个示例
  • 但我不是在开玩笑,你应该切换片段以支持片段
  • 我明白了,为什么要改成支持fragment呢?
  • @Meryl, getFragmentManager() 是 API 级别 11。getSupportFragmentManager 受支持库支持。如果您将其保留为Activity 而不是FragmentActivity,那么您将无法使用getSupportFragmentManager

标签: android android-fragments android-fragmentactivity fragmenttransaction


【解决方案1】:

通常,您不应在 UI 线程上执行长时间运行/阻塞操作。使用工作线程或AsyncTask

一般情况下,我建议您在onCreateView 中创建任何您可以创建的内容,然后在后台操作完成后设置值。例如,马上创建一个TextView,然后当你从后台操作得到结果时,再将文本设置在已经存在的TextView中。

使用线程:

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();

你也可以用getActivity().runOnUiThread(new Runnable(){...});代替Handler

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2014-11-06
    • 1970-01-01
    • 2017-08-05
    • 1970-01-01
    • 1970-01-01
    • 2017-03-13
    相关资源
    最近更新 更多