ListFragment no acepta mi diseño

De acuerdo con este enlace: ListFragment android developers

Quiero establecer mi diseño personalizado para la lista, pero hace excepciones.

Aquí está el código:

public class ListFragmentActivity extends FragmentActivity { @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); FragmentManager fm = getSupportFragmentManager(); if(fm.findFragmentById(android.R.id.content) == null) { myListFragments list = new myListFragments(); fm.beginTransaction().add(android.R.id.content, list).commit(); } } public static class myListFragments extends ListFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.topoffers, container, false); } @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); List offers = Global.getInstance().getOffers(); List topOffers = new ArrayList(4); for (int i = 0; i < 4; i++) { if (offers.get(i).getOfferImage() == null) offers.get(i).setOfferImage( downloadFile(offers.get(i).getOfferImageUrl())); topOffers.add(offers.get(i)); } LazyAdapter adapter = new LazyAdapter(getActivity()); adapter.setData(topOffers); setListAdapter(adapter); setListShown(true); } public Bitmap downloadFile(String fileUrl) { URL myFileUrl = null; try { myFileUrl = new URL(fileUrl); } catch (MalformedURLException e) { e.printStackTrace(); return null; } try { HttpURLConnection conn = (HttpURLConnection) myFileUrl .openConnection(); conn.setDoInput(true); conn.connect(); InputStream is = conn.getInputStream(); return BitmapFactory.decodeStream(is); } catch (IOException e) { e.printStackTrace(); return null; } } }} 

y mi diseño personalizado es R.layout.topoffers

Logcat:

  05-15 21:43:56.975: W/dalvikvm(218): threadid=3: thread exiting with uncaught exception (group=0x4001b188) 05-15 21:43:56.975: E/AndroidRuntime(218): Uncaught handler: thread main exiting due to uncaught exception 05-15 21:43:56.995: E/AndroidRuntime(218): java.lang.RuntimeException: Unable to start activity ComponentInfo{org.anddev.android.ikiwi/org.anddev.android.ikiwi.ListFragmentActivity}: java.lang.IllegalStateException: Can't be used with a custom content view 05-15 21:43:56.995: E/AndroidRuntime(218): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496) 05-15 21:43:56.995: E/AndroidRuntime(218): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512) 05-15 21:43:56.995: E/AndroidRuntime(218): at android.app.ActivityThread.access$2200(ActivityThread.java:119) 05-15 21:43:56.995: E/AndroidRuntime(218): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863) 05-15 21:43:56.995: E/AndroidRuntime(218): at android.os.Handler.dispatchMessage(Handler.java:99) 05-15 21:43:56.995: E/AndroidRuntime(218): at android.os.Looper.loop(Looper.java:123) 05-15 21:43:56.995: E/AndroidRuntime(218): at android.app.ActivityThread.main(ActivityThread.java:4363) 05-15 21:43:56.995: E/AndroidRuntime(218): at java.lang.reflect.Method.invokeNative(Native Method) 05-15 21:43:56.995: E/AndroidRuntime(218): at java.lang.reflect.Method.invoke(Method.java:521) 05-15 21:43:56.995: E/AndroidRuntime(218): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 05-15 21:43:56.995: E/AndroidRuntime(218): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 05-15 21:43:56.995: E/AndroidRuntime(218): at dalvik.system.NativeStart.main(Native Method) 05-15 21:43:56.995: E/AndroidRuntime(218): Caused by: java.lang.IllegalStateException: Can't be used with a custom content view 05-15 21:43:56.995: E/AndroidRuntime(218): at android.support.v4.app.ListFragment.setListShown(ListFragment.java:282) 05-15 21:43:56.995: E/AndroidRuntime(218): at android.support.v4.app.ListFragment.setListShown(ListFragment.java:258) 05-15 21:43:56.995: E/AndroidRuntime(218): at org.anddev.android.ikiwi.ListFragmentActivity$myListFragments.onActivityCreated(ListFragmentActivity.java:57) 05-15 21:43:56.995: E/AndroidRuntime(218): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:891) 05-15 21:43:56.995: E/AndroidRuntime(218): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080) 05-15 21:43:56.995: E/AndroidRuntime(218): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:622) 05-15 21:43:56.995: E/AndroidRuntime(218): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1416) 05-15 21:43:56.995: E/AndroidRuntime(218): at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:505) 05-15 21:43:56.995: E/AndroidRuntime(218): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1129) 05-15 21:43:56.995: E/AndroidRuntime(218): at android.app.Activity.performStart(Activity.java:3723) 05-15 21:43:56.995: E/AndroidRuntime(218): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2468) 05-15 21:43:56.995: E/AndroidRuntime(218): ... 11 more 05-15 21:43:57.025: I/dalvikvm(218): threadid=7: reacting to signal 3 05-15 21:43:57.025: E/dalvikvm(218): Unable to open stack trace file '/data/anr/traces.txt': Permission denied 

Esto parece un problema que ya se informó a Google.

Google Issue

Si este es realmente su problema, hay un par de sugerencias en la parte inferior de esa página para solucionarlo (bueno, más hacerlo funcionar que arreglarlo).

Crea el archivo de diseño list_content.xml

            

Pon esto dentro de tu clase ListFragment :

 public ListView mList; boolean mListShown; View mProgressContainer; View mListContainer; public void setListShown(boolean shown, boolean animate){ if (mListShown == shown) { return; } mListShown = shown; if (shown) { if (animate) { mProgressContainer.startAnimation(AnimationUtils.loadAnimation( getActivity(), android.R.anim.fade_out)); mListContainer.startAnimation(AnimationUtils.loadAnimation( getActivity(), android.R.anim.fade_in)); } mProgressContainer.setVisibility(View.GONE); mListContainer.setVisibility(View.VISIBLE); } else { if (animate) { mProgressContainer.startAnimation(AnimationUtils.loadAnimation( getActivity(), android.R.anim.fade_in)); mListContainer.startAnimation(AnimationUtils.loadAnimation( getActivity(), android.R.anim.fade_out)); } mProgressContainer.setVisibility(View.VISIBLE); mListContainer.setVisibility(View.INVISIBLE); } } public void setListShown(boolean shown){ setListShown(shown, true); } public void setListShownNoAnimation(boolean shown) { setListShown(shown, false); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { int INTERNAL_EMPTY_ID = 0x00ff0001; View root = inflater.inflate(R.layout.list_content, container, false); (root.findViewById(R.id.internalEmpty)).setId(INTERNAL_EMPTY_ID); mList = (ListView) root.findViewById(android.R.id.list); mListContainer = root.findViewById(R.id.listContainer); mProgressContainer = root.findViewById(R.id.progressContainer); mListShown = true; return root; } 

Ahora puedes usarlo normalmente:

 setListShown(boolean shown); setListShown(boolean shown, boolean animate); setListShownNoAnimation(boolean shown); 

Fuente:

http://source-android.frandroid.com/frameworks/base/core/java/android/app/ListFragment.java

http://source-android.frandroid.com/frameworks/base/core/res/res/layout/list_content.xml

Esto podría ser más fácil: cree su diseño como lo haría normalmente, pero no agregue la lista / vacío / cargando cosas. Luego, en el displayfragment enCreateView:

 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = super.onCreateView(inflater, container, savedInstanceState); ViewGroup parent = (ViewGroup) inflater.inflate(R.layout.mylayout, container, false); parent.addView(v, 0); return parent; } 

Ahora puedes usar setListShown …

Simplemente reemplace el ListView original con su LayListView Layout dentro del método onCreateView. Trabajó para mi.

  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View layout = super.onCreateView(inflater, container, savedInstanceState); ListView lv = (ListView) layout.findViewById(android.R.id.list); ViewGroup parent = (ViewGroup) lv.getParent(); // Remove ListView and add CustomView in its place int lvIndex = parent.indexOfChild(lv); parent.removeViewAt(lvIndex); LinearLayout mLinearLayout = (LinearLayout) inflater.inflate( R.layout.custom_list, container, false); parent.addView(mLinearLayout, lvIndex, lv.getLayoutParams()); return layout; } 

Hoy tuve el mismo problema. Buscando la solución en Google, encontré una publicación en un blog japonés. ( http://blog.nkzn.net/entry/2012/06/14/160706 ).

Para usar setListShown(boolean) debe hacer primero en su diseño:

           

Ahora en su ListFragment:

 public class SampleListFragment extends ListFragment { /** ID for progressbar parent */ private static final int INTERNAL_PROGRESS_CONTAINER_ID = 0x00ff0002; /** ID for listview parent */ private static final int INTERNAL_LIST_CONTAINER_ID = 0x00ff0003; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.custom_list_layout, container, false); // get you progressBar and his parent ProgressBar pBar = (ProgressBar) view.findViewById(android.R.id.progress); LinearLayout pframe = (LinearLayout) pBar.getParent(); pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID); ListView listView = (ListView) view.findViewById(android.R.id.list); listView.setItemsCanFocus(false); FrameLayout lFrame = (FrameLayout) listView.getParent(); lFrame.setId(INTERNAL_LIST_CONTAINER_ID); return view; } } 

con estos 2 números de ids seted en sus padres, setListShown (boolean) funcionará sin problemas.

Otra solución que funcionó para mí también es simplemente poner esta línea

  

en lugar de su vista de lista.

Puede construir su propio contenido encima o rodearlo con algunas otras vistas. Por ejemplo, así es como se ve mi diseño:

         

Solo necesitaba cambiar mis propiedades TextView e hice esto

 @Override public void onLoadFinished(Loader loader, Cursor cursor) { // Swap the new cursor in. (The framework will take care of closing the // old cursor once we return) mAdapter.swapCursor(cursor); if (cursor.getCount() == 0) { setEmptyText(getString(R.string.no_users)); TextView tvEmpty = (TextView) getListView().getEmptyView(); tvEmpty.setTextColor(getResources().getColor(R.color.blue)); } // The list should now be shown. if (isResumed()) { setListShown(true); } else { setListShownNoAnimation(true); } } 

No olvide que si intenta inicializar tvEmpty antes de llamar a setEmptyText("Empty") , se encontrará con una NullPointerException

Este código funcionó para mí:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = super.onCreateView(inflater, container, savedInstanceState); ((TextView)root.findViewById(0x00ff0001)).setText("some text"); ListView list = (ListView) root.findViewById(android.R.id.list); list.setEmptyView(root.findViewById(0x00ff0001)); return root; } 

Un poco tarde, pero no vio esta respuesta.

Fragment interior:

  @Override public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.fragment_list_activity, container, false); ListFragmentHelper.adaptView(view); return view; } 

pero tenga en cuenta que en fragment_list_activity.xml debe configurar los ID android:id="@id/loading" , android:id="@id/content" y android:id="@id/empty" para sus vistas !

Intenta eliminar setListShown(true); ?

Tuve el mismo problema, hace algún tiempo. Son costuras que no puedes usar si tienes diseño personalizado en ListFragment .