Android-为什么会发生这种情况(“内容尚未创建”错误)

发布于 2025-01-06 02:10:47 字数 8351 浏览 2 评论 0原文

这是此问题的后续内容: Android -为什么这告诉我“内容视图尚未创建”?

因此,以下代码会引发错误:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
       Bundle savedInstanceState) {

        LinearLayout Layout5 = (LinearLayout) inflater.inflate(R.layout.tab_frag5_layout, container, false);

        Cursor allBands;
        MyDatabase db;

        Context ctx = (Context)TabFragment5.this.getActivity();


        db = new MyDatabase(ctx);
        allBands = db.getBands();


        ListAdapter adapter = new SimpleCursorAdapter (ctx, 
                R.layout.listelement, 
                allBands, 
                new String[] {"BandName"},  
                new int[] {R.id.text15});

        getListView().setAdapter(adapter);  

        return Layout5;

     }

但是, 如果我向布局添加一个按钮并将代码放入 OnClick 方法中,它就可以完美工作。就像这样:

@Override
         public View onCreateView(LayoutInflater inflater, ViewGroup container,
           Bundle savedInstanceState) {

            LinearLayout Layout5 = (LinearLayout) inflater.inflate(R.layout.tab_frag5_layout, container, false);
            // Register for the Button.OnClick event 
            Button bShop = (Button)Layout5.findViewById(R.id.button_test);
            bShop.setOnClickListener(new View.OnClickListener() {           
                @Override
                public void onClick(View v) {

                    Cursor allBands;
                    MyDatabase db;

                    Context ctx = (Context)TabFragment5.this.getActivity();


                    db = new MyDatabase(ctx);
                    allBands = db.getBands();


                    ListAdapter adapter = new SimpleCursorAdapter (ctx, 
                            R.layout.listelement, 
                            allBands, 
                            new String[] {"BandName"},  
                            new int[] {R.id.text15});   

                    getListView().setAdapter(adapter);

                        }
                    });                                                                 

            return Layout5; 

为什么会发生这种情况。我知道它一定与片段生命周期有关,但是什么?如何规避此问题,以便在片段打开时填充列表列表视图,而不仅仅是在单击按钮时填充?

谢谢

编辑:这是主要活动

 public class TabsFragmentActivity extends FragmentActivity implements TabHost.OnTabChangeListener {

private TabHost mTabHost;
private HashMap mapTabInfo = new HashMap();
private TabInfo mLastTab = null;



private class TabInfo {
     private String tag;
     private Class clss;
     private Bundle args;
     private Fragment fragment;
     TabInfo(String tag, Class clazz, Bundle args) {
         this.tag = tag;
         this.clss = clazz;
         this.args = args;
     }

}

class TabFactory implements TabContentFactory {

    private final Context mContext;

    /**
     * @param context
     */
    public TabFactory(Context context) {
        mContext = context;
    }


    /** (non-Javadoc)
     * @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
     */
    public View createTabContent(String tag) {
        View v = new View(mContext);
        v.setMinimumWidth(0);
        v.setMinimumHeight(0);
        return v;
    }

}
/** (non-Javadoc)
 * @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
 */
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Step 1: Inflate layout
    setContentView(R.layout.tabs_layout);
    // Step 2: Setup TabHost
    initialiseTabHost(savedInstanceState);



    if (savedInstanceState != null) {
        mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); //set the tab     as per the saved state
    }
}

  /** (non-Javadoc)
 * @see android.support.v4.app.FragmentActivity#onSaveInstanceState(android.os.Bundle)
 */
   protected void onSaveInstanceState(Bundle outState) {
    outState.putString("tab", mTabHost.getCurrentTabTag()); //save the tab selected
    super.onSaveInstanceState(outState);
}

/**
 * Step 2: Setup TabHost
 */
private void initialiseTabHost(Bundle args) {
    mTabHost = (TabHost)findViewById(android.R.id.tabhost);
    mTabHost.setup();
    TabInfo tabInfo = null;
    TabsFragmentActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab1").setIndicator("s1"), ( tabInfo = new TabInfo("Tab1", TabFragment1.class, args)));
    this.mapTabInfo.put(tabInfo.tag, tabInfo);
    TabsFragmentActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab2").setIndicator("s2"), ( tabInfo = new TabInfo("Tab2", TabFragment2.class, args)));
    this.mapTabInfo.put(tabInfo.tag, tabInfo);
    TabsFragmentActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab3").setIndicator("s3"), ( tabInfo = new TabInfo("Tab3", TabFragment3.class, args)));
    this.mapTabInfo.put(tabInfo.tag, tabInfo);
    TabsFragmentActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab4").setIndicator("s4"), ( tabInfo = new TabInfo("Tab4", TabFragment4.class, args)));
    this.mapTabInfo.put(tabInfo.tag, tabInfo);
    TabsFragmentActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab5").setIndicator("s5"), ( tabInfo = new TabInfo("Tab5", TabFragment5.class, args)));
    this.mapTabInfo.put(tabInfo.tag, tabInfo);
    TabsFragmentActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab6").setIndicator("s6"), ( tabInfo = new TabInfo("Tab6", TabFragment6.class, args)));
    this.mapTabInfo.put(tabInfo.tag, tabInfo);
    // Default to first tab
    this.onTabChanged("Tab1");
    //
    mTabHost.setOnTabChangedListener(this);
}

/**
 * @param activity
 * @param tabHost
 * @param tabSpec
 * @param clss
 * @param args
 */
private static void addTab(TabsFragmentActivity activity, TabHost tabHost, TabHost.TabSpec tabSpec, TabInfo tabInfo) {
    // Attach a Tab view factory to the spec
    tabSpec.setContent(activity.new TabFactory(activity));
    String tag = tabSpec.getTag();

    // Check to see if we already have a fragment for this tab, probably
    // from a previously saved state.  If so, deactivate it, because our
    // initial state is that a tab isn't shown.
    tabInfo.fragment = activity.getSupportFragmentManager().findFragmentByTag(tag);
    if (tabInfo.fragment != null && !tabInfo.fragment.isDetached()) {
        FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction();
        ft.detach(tabInfo.fragment);
        ft.commit();
        activity.getSupportFragmentManager().executePendingTransactions();
    }

    tabHost.addTab(tabSpec);
}

/** (non-Javadoc)
9
 * @see android.widget.TabHost.OnTabChangeListener#onTabChanged(java.lang.String)
 */
public void onTabChanged(String tag) {
    TabInfo newTab = (TabInfo) this.mapTabInfo.get(tag);
   if (mLastTab != newTab) {
        FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
        if (mLastTab != null) {
            if (mLastTab.fragment != null) {

                ft.detach(mLastTab.fragment);
            }

       }
        if (newTab != null) {
            if (newTab.fragment == null) {
                newTab.fragment = Fragment.instantiate(this,
                        newTab.clss.getName(), newTab.args);
                ft.add(R.id.realtabcontent, newTab.fragment, newTab.tag);
            } else {
                ft.attach(newTab.fragment);

            }
        }

        mLastTab = newTab;
        ft.commit();
        this.getSupportFragmentManager().executePendingTransactions();
    }
}

}

和片段 XML

        <?xml version="1.0" encoding="utf-8"?>
<LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/mylayout2"
  android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:background="#D6D6D6"
 >

<Button
    android:id="@+id/button_test"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="0"
    android:text="Button" />

<ListView 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="0" 
    android:id="@android:id/list"></ListView>

This is a followup to this question: Android - why is this telling me "Content view not yet created"?

So, the following code throws an error:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
       Bundle savedInstanceState) {

        LinearLayout Layout5 = (LinearLayout) inflater.inflate(R.layout.tab_frag5_layout, container, false);

        Cursor allBands;
        MyDatabase db;

        Context ctx = (Context)TabFragment5.this.getActivity();


        db = new MyDatabase(ctx);
        allBands = db.getBands();


        ListAdapter adapter = new SimpleCursorAdapter (ctx, 
                R.layout.listelement, 
                allBands, 
                new String[] {"BandName"},  
                new int[] {R.id.text15});

        getListView().setAdapter(adapter);  

        return Layout5;

     }

BUT,
if i add a button to the layout and place the code inside the OnClick method, it works perfectly. Like this:

@Override
         public View onCreateView(LayoutInflater inflater, ViewGroup container,
           Bundle savedInstanceState) {

            LinearLayout Layout5 = (LinearLayout) inflater.inflate(R.layout.tab_frag5_layout, container, false);
            // Register for the Button.OnClick event 
            Button bShop = (Button)Layout5.findViewById(R.id.button_test);
            bShop.setOnClickListener(new View.OnClickListener() {           
                @Override
                public void onClick(View v) {

                    Cursor allBands;
                    MyDatabase db;

                    Context ctx = (Context)TabFragment5.this.getActivity();


                    db = new MyDatabase(ctx);
                    allBands = db.getBands();


                    ListAdapter adapter = new SimpleCursorAdapter (ctx, 
                            R.layout.listelement, 
                            allBands, 
                            new String[] {"BandName"},  
                            new int[] {R.id.text15});   

                    getListView().setAdapter(adapter);

                        }
                    });                                                                 

            return Layout5; 

Why does this happen. i understand it must have something to do with the fragments lifecycle, but what? How can I circumvent this so the list listview is populated when the fragment opens, and not only when i click the button?

Thanks

EDIT: this is the main activity

 public class TabsFragmentActivity extends FragmentActivity implements TabHost.OnTabChangeListener {

private TabHost mTabHost;
private HashMap mapTabInfo = new HashMap();
private TabInfo mLastTab = null;



private class TabInfo {
     private String tag;
     private Class clss;
     private Bundle args;
     private Fragment fragment;
     TabInfo(String tag, Class clazz, Bundle args) {
         this.tag = tag;
         this.clss = clazz;
         this.args = args;
     }

}

class TabFactory implements TabContentFactory {

    private final Context mContext;

    /**
     * @param context
     */
    public TabFactory(Context context) {
        mContext = context;
    }


    /** (non-Javadoc)
     * @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
     */
    public View createTabContent(String tag) {
        View v = new View(mContext);
        v.setMinimumWidth(0);
        v.setMinimumHeight(0);
        return v;
    }

}
/** (non-Javadoc)
 * @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
 */
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Step 1: Inflate layout
    setContentView(R.layout.tabs_layout);
    // Step 2: Setup TabHost
    initialiseTabHost(savedInstanceState);



    if (savedInstanceState != null) {
        mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); //set the tab     as per the saved state
    }
}

  /** (non-Javadoc)
 * @see android.support.v4.app.FragmentActivity#onSaveInstanceState(android.os.Bundle)
 */
   protected void onSaveInstanceState(Bundle outState) {
    outState.putString("tab", mTabHost.getCurrentTabTag()); //save the tab selected
    super.onSaveInstanceState(outState);
}

/**
 * Step 2: Setup TabHost
 */
private void initialiseTabHost(Bundle args) {
    mTabHost = (TabHost)findViewById(android.R.id.tabhost);
    mTabHost.setup();
    TabInfo tabInfo = null;
    TabsFragmentActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab1").setIndicator("s1"), ( tabInfo = new TabInfo("Tab1", TabFragment1.class, args)));
    this.mapTabInfo.put(tabInfo.tag, tabInfo);
    TabsFragmentActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab2").setIndicator("s2"), ( tabInfo = new TabInfo("Tab2", TabFragment2.class, args)));
    this.mapTabInfo.put(tabInfo.tag, tabInfo);
    TabsFragmentActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab3").setIndicator("s3"), ( tabInfo = new TabInfo("Tab3", TabFragment3.class, args)));
    this.mapTabInfo.put(tabInfo.tag, tabInfo);
    TabsFragmentActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab4").setIndicator("s4"), ( tabInfo = new TabInfo("Tab4", TabFragment4.class, args)));
    this.mapTabInfo.put(tabInfo.tag, tabInfo);
    TabsFragmentActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab5").setIndicator("s5"), ( tabInfo = new TabInfo("Tab5", TabFragment5.class, args)));
    this.mapTabInfo.put(tabInfo.tag, tabInfo);
    TabsFragmentActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab6").setIndicator("s6"), ( tabInfo = new TabInfo("Tab6", TabFragment6.class, args)));
    this.mapTabInfo.put(tabInfo.tag, tabInfo);
    // Default to first tab
    this.onTabChanged("Tab1");
    //
    mTabHost.setOnTabChangedListener(this);
}

/**
 * @param activity
 * @param tabHost
 * @param tabSpec
 * @param clss
 * @param args
 */
private static void addTab(TabsFragmentActivity activity, TabHost tabHost, TabHost.TabSpec tabSpec, TabInfo tabInfo) {
    // Attach a Tab view factory to the spec
    tabSpec.setContent(activity.new TabFactory(activity));
    String tag = tabSpec.getTag();

    // Check to see if we already have a fragment for this tab, probably
    // from a previously saved state.  If so, deactivate it, because our
    // initial state is that a tab isn't shown.
    tabInfo.fragment = activity.getSupportFragmentManager().findFragmentByTag(tag);
    if (tabInfo.fragment != null && !tabInfo.fragment.isDetached()) {
        FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction();
        ft.detach(tabInfo.fragment);
        ft.commit();
        activity.getSupportFragmentManager().executePendingTransactions();
    }

    tabHost.addTab(tabSpec);
}

/** (non-Javadoc)
9
 * @see android.widget.TabHost.OnTabChangeListener#onTabChanged(java.lang.String)
 */
public void onTabChanged(String tag) {
    TabInfo newTab = (TabInfo) this.mapTabInfo.get(tag);
   if (mLastTab != newTab) {
        FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
        if (mLastTab != null) {
            if (mLastTab.fragment != null) {

                ft.detach(mLastTab.fragment);
            }

       }
        if (newTab != null) {
            if (newTab.fragment == null) {
                newTab.fragment = Fragment.instantiate(this,
                        newTab.clss.getName(), newTab.args);
                ft.add(R.id.realtabcontent, newTab.fragment, newTab.tag);
            } else {
                ft.attach(newTab.fragment);

            }
        }

        mLastTab = newTab;
        ft.commit();
        this.getSupportFragmentManager().executePendingTransactions();
    }
}

}

And the fragment XML

        <?xml version="1.0" encoding="utf-8"?>
<LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/mylayout2"
  android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:background="#D6D6D6"
 >

<Button
    android:id="@+id/button_test"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="0"
    android:text="Button" />

<ListView 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="0" 
    android:id="@android:id/list"></ListView>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

流年已逝 2025-01-13 02:10:47

这里的关键是何时在 ListFragment 中调用 setAdapter() 。

在您的第一个示例中,在 onCreateView() 内部调用 setAdapter() ,这将不起作用,因为 ListFragment 在允许设置适配器之前检查以确保布局中定义了一个列表,直到 onCreateView() 返回您的视图正在创建,没有布局需要检查。这是一个先有鸡还是先有蛋的问题。

第二个示例起作用的原因是因为您实际上并未从 onCreateView() 中调用 setAdapter() 。在生成的布局中单击按钮后,适配器才会设置。

这里的基本问题是片段与活动不同,因为您不能在 onCreate() 中执行与活动相同的操作,尤其是在设置适配器时。

The key here is when setAdapter() is being called inside your ListFragment.

In your first example, setAdapter() was being called inside onCreateView() which won't work because the ListFragment checks to ensure there is a list defined in your layouts before allowing the adapter to be set and until onCreateView() returns the view you are creating, there isn't a layout to check. It's a chicken and egg problem.

The reason the second example works is because you aren't actually callnig setAdapter() from within onCreateView(). The adapter isn't set until the button is clicked in your resulting layout.

The basic issue here is that fragments differ from activities in that you can't do the same sorts of things in onCreate() as you are used to doing with your activities, especially when it comes to setting up your adapters.

热血少△年 2025-01-13 02:10:47

您是否扩展 Fragment 类或 ListFragment?
这就是我在 ListFragment 中使用它的方式 ->

public class FooFragment extends ListFragment{

public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_eventlist, null);
        eventAdapter = new EventAdapter(getActivity(), R.layout.list_item_event, events);
        setListAdapter(eventAdapter);
        return root;
        }
}

编辑:

只需修改变量和类型:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View root = inflater.inflate(R.layout.fragment_activitystream, null);
            return root;
            }

     @Override
     public void onCreate(Bundle savedInstanceState){
         super.onCreate(savedInstanceState);
         states = new ArrayList<Status>();
             ...
         YourAdapter asa = new YourAdapter(getActivity(), R.layout.list_item_status, states);
         setListAdapter(asa);
         Log.i(TAG, "onCreate is done");
     }

Do you extend the Fragment Class or the ListFragment?
This is how I used it inside a ListFragment ->

public class FooFragment extends ListFragment{

public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_eventlist, null);
        eventAdapter = new EventAdapter(getActivity(), R.layout.list_item_event, events);
        setListAdapter(eventAdapter);
        return root;
        }
}

Edit:

Just modify the variables and types:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View root = inflater.inflate(R.layout.fragment_activitystream, null);
            return root;
            }

     @Override
     public void onCreate(Bundle savedInstanceState){
         super.onCreate(savedInstanceState);
         states = new ArrayList<Status>();
             ...
         YourAdapter asa = new YourAdapter(getActivity(), R.layout.list_item_status, states);
         setListAdapter(asa);
         Log.i(TAG, "onCreate is done");
     }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文