【问题标题】:Content view not yet created in refreshing a list fragment刷新列表片段时尚未创建内容视图
【发布时间】:2013-12-21 09:16:42
【问题描述】:

解决方案: 有 2 个不同的 WinnersFragment 实例导致 lv = getListView() 在刷新时为空。

我的片段列表视图在加载时工作正常。但是,当我调用 public static void InitTask(String searchState) 时。我在 lv = getListView() 获得尚未创建的内容视图。

我的目标是用新的 json 刷新列表视图。

我尝试在执行前调用 getlistView,并尝试使用新的 inittask。
我相信这与创建一个新的WinnersFragment 实例有关,但我不确定。

我找到了这个"Content view not yet Created" on Android Fragments,但是虽然我理解它击中了主线程,但我不明白如何实施解决方案,看看这是否是我的问题。

 public class WinnersFragment extends ListFragment {
private static String URL = "http://www.xxx.com/RichardsTesting/winners.json";

Context context;
Winners_List_Adapter adapter;
static View v;
ListView lv;
ArrayList<String> alFName;
private ProgressDialog pd;
private static final String TAG_ID = "id";
private static final String TAG_FNAME = "fname";
private static final String TAG_STATE = "state";
private static final String TAG_CODE = "code";
private static final String TAG_AMOUNT = "amount";

ArrayList<HashMap<String, String>> winnersList;

JSONArray winners = null;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

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

    v = inflater.inflate(R.layout.winners_list, container, false);
    context = getActivity().getApplicationContext();
    new InitTask().execute();

    return v;
}

@Override
public void onDestroy() {
    lv.setAdapter(null);
    super.onDestroy();
}

protected class InitTask extends AsyncTask<Context, Integer, String> {
    @Override
    protected void onPreExecute() {
        pd = new ProgressDialog(v.getContext());
        pd.setTitle("Updating...");
        pd.setMessage("Please wait.");
        pd.setCancelable(false);
        pd.setIndeterminate(true);
        pd.show();
    }

    @Override
    protected String doInBackground(Context... params) {
        // Hashmap for ListView
        winnersList = new ArrayList<HashMap<String, String>>();

        // Creating JSON Parser instance
        JSONParser jParser = new JSONParser();

        // getting JSON string from URL
        String json = jParser.getJSONFromUrl(URL);
        try {
            JSONArray json1 = new JSONArray(json);

            // looping through All Contacts
            for (int i = 0; i < json.length(); i++) {
                JSONObject c = json1.getJSONObject(i);

                // Storing each json item in variable
                String id = c.getString(TAG_ID);
                String fName = c.getString(TAG_FNAME);
                String state = c.getString(TAG_STATE);
                String code = c.getString(TAG_CODE);
                String amount = c.getString(TAG_AMOUNT);

                // creating new HashMap
                HashMap<String, String> map = new HashMap<String, String>();

                // adding each child node to HashMap key => value
                map.put(TAG_ID, id);
                map.put(TAG_FNAME, fName);
                map.put(TAG_STATE, state);
                map.put(TAG_CODE, code);
                map.put(TAG_AMOUNT, amount);

                // adding HashList to ArrayList
                winnersList.add(map);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return "COMPLETE!";
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        // selecting single ListView item
        lv = getListView();
        if (pd != null) {
            pd.dismiss();
        }
        setListWinners();
    }
}

public void setListWinners() {
    adapter = new Winners_List_Adapter(this.getActivity(), winnersList);
    lv.setAdapter(adapter);
}

public static void InitTask(String searchState) {
    if (searchState !=null) {
    URL = URL+"?state="+searchState;
    WinnersFragment search = new WinnersFragment();
    search.new InitTask().execute();
    }
}
}

日志

12-04 13:01:48.156: E/AndroidRuntime(1367): FATAL EXCEPTION: main
12-04 13:01:48.156: E/AndroidRuntime(1367): java.lang.IllegalStateException: Content view not yet created
12-04 13:01:48.156: E/AndroidRuntime(1367):     at android.support.v4.app.ListFragment.ensureList(ListFragment.java:328)
12-04 13:01:48.156: E/AndroidRuntime(1367):     at android.support.v4.app.ListFragment.getListView(ListFragment.java:222)
12-04 13:01:48.156: E/AndroidRuntime(1367):     at com.xxx.xxx.WinnersFragment$InitTask.onPostExecute(WinnersFragment.java:123)
12-04 13:01:48.156: E/AndroidRuntime(1367):     at com.xxx.xxx.WinnersFragment$InitTask.onPostExecute(WinnersFragment.java:1)
12-04 13:01:48.156: E/AndroidRuntime(1367):     at android.os.AsyncTask.finish(AsyncTask.java:631)
12-04 13:01:48.156: E/AndroidRuntime(1367):     at android.os.AsyncTask.access$600(AsyncTask.java:177)
12-04 13:01:48.156: E/AndroidRuntime(1367):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
12-04 13:01:48.156: E/AndroidRuntime(1367):     at android.os.Handler.dispatchMessage(Handler.java:99)
12-04 13:01:48.156: E/AndroidRuntime(1367):     at android.os.Looper.loop(Looper.java:137)
12-04 13:01:48.156: E/AndroidRuntime(1367):     at android.app.ActivityThread.main(ActivityThread.java:4898)
12-04 13:01:48.156: E/AndroidRuntime(1367):     at java.lang.reflect.Method.invokeNative(Native Method)
12-04 13:01:48.156: E/AndroidRuntime(1367):     at java.lang.reflect.Method.invoke(Method.java:511)
12-04 13:01:48.156: E/AndroidRuntime(1367):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008)
12-04 13:01:48.156: E/AndroidRuntime(1367):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775)
12-04 13:01:48.156: E/AndroidRuntime(1367):     at dalvik.system.NativeStart.main(Native Method)

xml

  <ListView
    android:id="@id/android:list"
    android:layout_width="match_parent"
    android:layout_height="0dip"
    android:layout_weight="1"
    android:drawSelectorOnTop="false" />

调用片段代码

public class TabsFragmentActivity extends FragmentActivity implements
    FragmentTabHost.OnTabChangeListener, OnClickListener {
      blablabla
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btnDismiss:
        getSupportFragmentManager().popBackStackImmediate();
        break;
    case R.id.ibSearch:
        LayoutInflater inflater = LayoutInflater.from(this);
        final View textenter = inflater.inflate(R.layout.winners_list, null);
        final EditText userinput = (EditText) textenter
                .findViewById(R.id.etSearchState);
        String searchState = userinput.toString();
        WinnersFragment.InitTask(searchState);
        break;  
    }
}

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    尝试在 onActivityCreated() 方法中执行你的后台任务。

    Fragment Lifecycle

    【讨论】:

      【解决方案2】:
      onCreateView  
      

      当您尝试访问列表视图时,返回为该片段显示的视图,然后返回此视图,您会收到该错误。

      尝试按照@Makario 所说的去做,或者通过以下方式在 onCreateView 中获取列表视图引用:

       v = inflater.inflate(R.layout.winners_list, container, false);
       context = getActivity().getApplicationContext();
       listView=v.findViewById(R.id.list);
       new InitTask().execute();
      

      并在你的任务中使用这个 listview 对象。

      【讨论】:

      • 如果我将 InitTask().execute() 移动到 onViewCreated 或 onActivityCreated 如何使用公共静态 void InitTask(String searchState) { if (searchState !=null ) { URL = URL+"?state="+searchState; WinnersFragment 搜索 = 新的WinnersFragment(); search.new InitTask().execute(); }
      • 你不应该创建一个新的WinnersFragment对象,而是想办法使用同一个对象来创建新的InitTask对象。
      • 不要将该函数设为静态并在同一个 winsFragment 对象上调用它,例如: public void InitTask(String searchState) { if (searchState !=null) { URL = URL+"?state=" +搜索状态;新的 InitTask().execute(); } }
      • 问题是调用它的按钮位于我的 TabFragment 上,它扩展了 FragmentActivity。所以我不能从WinnersFragment中调用它
      • 你也可以显示该代码吗?尝试一些如何持久化引用或使用一些回调系统来刷新数据
      【解决方案3】:

      如错误消息所示,您的 ListView 的视图尚未创建。 (您在 onCreateView 中调用它,即使该方法异步运行,您仍试图在 ListView 完全设置之前访问它。)

      将 InitTask().execute() 改为 onViewCreatedonActivityCreated

      【讨论】:

      • 这不会解决问题。 onCreateView 中的 InitTask().execute() 工作正常。我需要从 public static void InitTask(String searchState) 再次调用它
      • 我假设您已经尝试过解决方案,那么?问题是在调用该方法之前您的视图尚未完全设置。您正试图在 ListView 准备好之前访问它。如果您想尝试调试问题,请将 getListView() 调用包装在 if 语句中: if (isAdded()) { lv = getListView(); } else { System.out.println("调用太早") }
      猜你喜欢
      • 2016-09-07
      • 1970-01-01
      • 2014-04-13
      • 2014-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多