“Affichage du contenu n'est pas encore Créé” sur Android Fragments
Je suis en utilisant Android Fragments avec une viewpager
de l'installation. Fondamentalement il y a 5 onglets, vous pouvez passer à travers.
4 des 5 contiennent ListFragments
qui sont peuplées par les tables MySQL; c'est fait à l'intérieur d'un AsyncTask
. Quand j'ai balayage très rapide parfois, j'ai cette erreur:
09-01 07:54:01.243: E/AndroidRuntime(19706): FATAL EXCEPTION: main
09-01 07:54:01.243: E/AndroidRuntime(19706): java.lang.IllegalStateException: Content view not yet created
09-01 07:54:01.243: E/AndroidRuntime(19706): at android.support.v4.app.ListFragment.ensureList(ListFragment.java:328)
09-01 07:54:01.243: E/AndroidRuntime(19706): at android.support.v4.app.ListFragment.getListView(ListFragment.java:222)
09-01 07:54:01.243: E/AndroidRuntime(19706): at com.---.---.MasterCat$TopFrag$TopTask.onPostExecute(MasterCat.java:570)
09-01 07:54:01.243: E/AndroidRuntime(19706): at com.---.---.MasterCat$TopFrag$TopTask.onPostExecute(MasterCat.java:1)
09-01 07:54:01.243: E/AndroidRuntime(19706): at android.os.AsyncTask.finish(AsyncTask.java:631)
09-01 07:54:01.243: E/AndroidRuntime(19706): at android.os.AsyncTask.access$600(AsyncTask.java:177)
09-01 07:54:01.243: E/AndroidRuntime(19706): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
09-01 07:54:01.243: E/AndroidRuntime(19706): at android.os.Handler.dispatchMessage(Handler.java:99)
09-01 07:54:01.243: E/AndroidRuntime(19706): at android.os.Looper.loop(Looper.java:137)
09-01 07:54:01.243: E/AndroidRuntime(19706): at android.app.ActivityThread.main(ActivityThread.java:4928)
09-01 07:54:01.243: E/AndroidRuntime(19706): at java.lang.reflect.Method.invokeNative(Native Method)
09-01 07:54:01.243: E/AndroidRuntime(19706): at java.lang.reflect.Method.invoke(Method.java:511)
09-01 07:54:01.243: E/AndroidRuntime(19706): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
09-01 07:54:01.243: E/AndroidRuntime(19706): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558)
09-01 07:54:01.243: E/AndroidRuntime(19706): at dalvik.system.NativeStart.main(Native Method)
J'ai intentionly pas utilisé un ProgressDialog
parce qu'il fait glisser bégayer un peu.
J'ai donc deux options et j'ai besoin d'aide de toute façon:
-
Comment éviter cette erreur et de garder la liste rafraîchissant, même tout en glissant.
-
OU une fois les 5 fragments sont chargés, de désactiver l'option "actualiser tout en glissant'. En d'autres termes, les listes restera la même, à moins que vous de retour de l'Activité et de revenir.
Je préfère l'option #1. S'il vous plaît laissez-moi savoir quel est le code que vous devez voir:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_layout);
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager
.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
}
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
Fragment f = null;
switch (position) {
case 0: {
f = new MasterFrag();
Bundle args = new Bundle();
f.setArguments(args);
break;
}
case 1: {
f = new FeaturedFrag();
Bundle args = new Bundle();
f.setArguments(args);
break;
}
case 4: {
f = new TopFrag();
Bundle args = new Bundle();
f.setArguments(args);
break;
}
case 3: {
f = new NewFrag();
Bundle args = new Bundle();
f.setArguments(args);
break;
}
case 2: {
f = new TrendFrag();
Bundle args = new Bundle();
f.setArguments(args);
break;
}
default:
throw new IllegalArgumentException("not this many fragments: "
+ position);
}
return f;
}
Également, la ligne de 570 référencé dans le LogCat se rapporte à un getListView() à l'intérieur d'une AsyncTask qui est à l'intérieur d'un ListFragment pas indiqué ci-dessus.
MODIFIER:
En ajoutant l'un des 5 Fragments, celui référencé dans le LogCat - "TopFrag"
class TopTask extends AsyncTask<String, String, Void> {
InputStream is = null;
String result = "";
@Override
protected Void doInBackground(String... params) {
String url_select = "http://www.---.com/---/---.php";
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url_select);
ArrayList<NameValuePair> param = new ArrayList<NameValuePair>();
param.add(new BasicNameValuePair("Top", "Top"));
try {
httpPost.setEntity(new UrlEncodedFormEntity(param));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
//read content
is = httpEntity.getContent();
} catch (Exception e) {
Log.e("log_tag", "Error in http connection " + e.toString());
}
try {
BufferedReader br = new BufferedReader(
new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
} catch (Exception e) {
//TODO: handle exception
Log.e("log_tag", "Error converting result " + e.toString());
}
return null;
}
protected void onPostExecute(Void v) {
String item, cat;
try {
JSONArray jArray = new JSONArray(result);
JSONObject json_data = null;
for (int i = 0; i < jArray.length(); i++) {
json_data = jArray.getJSONObject(i);
item = json_data.getString("item");
cat = json_data.getString("category");
items.add(item);
cats.add(cat);
}
} catch (JSONException e1) {
Toast.makeText(getActivity(), "No Top Items Found",
Toast.LENGTH_LONG).show();
} catch (ParseException e1) {
e1.printStackTrace();
}
ListView listView;
listView = getListView();
listView.setTextFilterEnabled(true);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2, long id) {
//edit
}
});
MasterCatObject[] mco = new MasterCatObject[items.size()];
int index = 0;
for (@SuppressWarnings("unused")
String i : items) {
mco[index] = new MasterCatObject(items.get(index),
cats.get(index));
index++;
}
adapter = new AllTimeAdapter(getActivity(), mco);
setListAdapter(adapter);
}
}
}
Vous devez vous connecter pour publier un commentaire.
votre
TopTask.onPostExecute()
ne doit pas toucher l'INTERFACE utilisateur, tandis que le fragment n'est pas encore (avantonCreateView
) /plus (aprèsonDestroyView
) montré. Il n'y a tout simplement pas deListView
vous pouvez obtenir.Ce que vous pouvez faire ici est de mettre à jour le discbased qui est utilisé par le
ListView
donc, la prochaine fois que la liste est tirée de la nouvelle de données est inclus.ListView
par la normalegetListView()
à l'intérieur de la PostExecute - serait-il préférable de le placer dans laOnActivityCreated
?OnActivityCreated
devrait fonctionner, mais je voudrais le mettre dansonCreateView
après l'appel desuper
puisque c'est certainement un endroit où vous pouvez être sûr qu'il est appelé lorsque laListView
est créé.for
boucle que vous utilisez pour effectuer une itération sur les éléments de la collection est un peu contre-intuitif. Vous savez queitems.get(index) == i
, en supposant unList
, parce que Java est renforcée pour boucles de travail. Je vois que vous aussi besoin d'obtenir le même index à partir de lacats
collection. Dans ce cas, vous pouvez utiliser une Map<String, String> à partir deitem
àcategory
ou une collection de classes (direMyPair
) qui ont deux valeurs: l'article et la catégorie -- dans ce cas, vous pouvez parcourir votre collection deMyPair
s et d'obtenir toutes les données. Je recommanderais unMap
bien que depuis qu'ils sont exactement de paires clé-valeur (=onPostExecute()
je ne lance mon code pour la liste si la vue n'est pas null. Quelque chose comme ceci:if(getView() != null && getActivity() != null) { /*set listview's adapter or whatever*/}
Pour éviter le plantage de vérifier si ListFragment isAdded())
au moment d'exception ListFragment est détachée.