Note that there are some explanatory texts on larger screens.

plurals
  1. POListview populates, but the adapter claims to be empty
    text
    copied!<p>So I'm developing an app over the summer. It stores items in the database, displays them in a listview (otherwise makes Toast telling the user its empty), and allows users to see details by clicking on one. Eventually I plan on having search criteria narrow down the list, but I'm not there yet.</p> <p>My problem is that the listview seems to be populating, but the app makes Toast....</p> <p>ResultsActivity.java</p> <pre><code>public class ResultsActivity extends FragmentActivity implements ResultsFragment.OnPlantSelectedListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_results); }// method: FragmentActivity.onCreate() @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.results, menu); return true; }// method: FragmentActivity.onCreateOptionsMenu() /* Custom methods */ //@Override public void onPlantSelected(long id){ Intent intent = new Intent(this, PlantViewActivity.class); //TODO confirm id intent.putExtra(DBContentProvider.KEY_PLANT_ID, id); startActivity(intent); }// method: ResultsFragment.OnPlantSelectedListener.onPlantSelected(long) }// class: ResultsActivity extends ListActivity </code></pre> <p>ResultsFragment.java</p> <pre><code>public class ResultsFragment extends ListFragment implements LoaderManager.LoaderCallbacks&lt;Cursor&gt;{ private static OnPlantSelectedListener emptyPlantSelectedListener = new OnPlantSelectedListener(){ @Override public void onPlantSelected(long id){} }; private static OnPlantSelectedListener plantSelectedListener = emptyPlantSelectedListener; private static final String STATE_ACTIVATED_POSITION = "activated_position"; private int activatedPosition = ListView.INVALID_POSITION; private SimpleCursorAdapter adapter; public ResultsFragment(){} /* Fragment Lifespan */ @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); String[] dbPlantColumns = {DBContentProvider.KEY_GENUS_TEXT, DBContentProvider.KEY_SPECIES, DBContentProvider.KEY_COMMON_NAME_GROUP}; int[] fragPlantFields = {R.id.result_item_txt_genus, R.id.result_item_txt_species, R.id.result_item_txt_common_name}; getLoaderManager().initLoader(0x01, null, this);//null can be replaced by a Bundle of search criteria adapter = new SimpleCursorAdapter(getActivity().getApplicationContext(), R.layout.list_item_results, null, dbPlantColumns, fragPlantFields, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); setListAdapter(adapter); if(adapter.isEmpty())//This returns true Toast.makeText(getActivity().getApplicationContext(), "Nothing returned from the database", Toast.LENGTH_LONG).show(); }// method: Activity.onCreate(Bundle) @Override public void onViewCreated(View view, Bundle savedInstanceState){ super.onViewCreated(view, savedInstanceState); if (savedInstanceState != null &amp;&amp; savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)){ setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION)); } }// method: ListFragment.onViewCreated(View, Bundle) @Override public void onAttach(Activity activity){ super.onAttach(activity); if (!(activity instanceof OnPlantSelectedListener)){ throw new IllegalStateException("Activity must implement fragment's listener."); } plantSelectedListener = (OnPlantSelectedListener) activity; }// method: ListFragment.onAttach(Activity) @Override public void onDetach(){ super.onDetach(); plantSelectedListener = emptyPlantSelectedListener; }// method: ListFragment.onDetach() @Override public void onSaveInstanceState(Bundle outState){ super.onSaveInstanceState(outState); if (activatedPosition != ListView.INVALID_POSITION){ outState.putInt(STATE_ACTIVATED_POSITION, activatedPosition); } }// method: ListFragment.onSaveInstanceState(Bundle) /* LoaderManager abstract methods */ @Override public Loader&lt;Cursor&gt; onCreateLoader(int id, Bundle args){ //TODO parse args for searching. Second null is String[]; index 0-17 are search arguments. String[] arguments = new String[18]; String[] dbPlantColumns = {DBContentProvider.TABLE_PLANT + "." + DBContentProvider.KEY_PLANT_ID, DBContentProvider.KEY_FAMILY_TEXT, DBContentProvider.KEY_GENUS_TEXT, DBContentProvider.KEY_SPECIES, DBContentProvider.KEY_COMMON_NAME_GROUP, DBContentProvider.KEY_GROWTH_FORM_TEXT}; CursorLoader cursorLoader = new CursorLoader(getActivity(), Uri.parse(DBContentProvider.CONTENT_URI_STRING + "search"), dbPlantColumns, null, arguments, null); return cursorLoader; }// method: LoaderCallbacks.onCreateLoader(int, Bundle) @Override public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor cursor){ adapter.swapCursor(cursor); }// method: LoaderCallbacks.onLoadFinished(Loader&lt;Cursor&gt;, Cursor) @Override public void onLoaderReset(Loader&lt;Cursor&gt; loader){ adapter.swapCursor(null); }// method: LoaderCallbacks.onLoaderReset(Loader&lt;Cursor&gt;) /* ListFragment response methods */ @Override public void onListItemClick(ListView listView, View view, int position, long id){ super.onListItemClick(listView, view, position, id); plantSelectedListener.onPlantSelected(id /*Get id of plant at this position*/); }// method: ListFragment.onListItemClick(Listview, View, int, long) public void setActivateOnItemClick(boolean activateOnItemClick){ getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); }// method: setActivateOnItemClick(boolean) private void setActivatedPosition(int position){ if(position == ListView.INVALID_POSITION){ getListView().setItemChecked(activatedPosition, false); } else{ getListView().setItemChecked(position, true); } activatedPosition = position; }//method: setActiviatedPosition(int) /** * OnPlantSelectedListener is used by the fragment and the activity to * make sure that the selection of a plant is dealt with correctly. */ public interface OnPlantSelectedListener{ public void onPlantSelected(long id); }// interface: OnPlantSelectedListener }// class: ResultsFragment extends ListFragment </code></pre> <p>activity_results.xml</p> <pre><code>&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=".ResultsActivity" android:id="@+id/Results_Lin" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"&gt; &lt;!-- @android:id/list is the necessary id for the activity to find it. --&gt; &lt;ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="5dp"&gt; &lt;/ListView&gt; &lt;TextView android:id="@+id/results_empty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/txt_no_results"/&gt; &lt;/LinearLayout&gt; </code></pre> <p>fragment_results.xml</p> <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;fragment xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:name="edu.dordt.grassrootsplantid.ResultsFragment" android:id="@+id/Result_Fragment"/&gt; </code></pre> <p>list_item_results.xml</p> <pre><code>&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/Result_Item_Lin" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="5dp"&gt; &lt;TextView android:id="@+id/result_item_txt_lbl_common_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/lbl_common_name"/&gt; &lt;TextView android:id="@+id/result_item_txt_common_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/result_item_txt_lbl_common_name"/&gt; &lt;TextView android:id="@+id/result_item_txt_lbl_scientific_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/result_item_txt_lbl_common_name" android:text="@string/lbl_scientific_name"/&gt; &lt;TextView android:id="@+id/result_item_txt_genus" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/result_item_txt_lbl_scientific_name" android:layout_below="@id/result_item_txt_lbl_common_name"/&gt; &lt;TextView android:id="@+id/result_item_txt_species" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/result_item_txt_genus" android:layout_below="@id/result_item_txt_lbl_common_name" android:layout_marginLeft="5dp"/&gt; &lt;/RelativeLayout&gt; </code></pre> <p>I probably misunderstand how to use fragments, but it was necessary in order to use the tutorial I was following for using Content Providers. I didn't put in the Content Provider here, but I'm pretty sure that's working (well...broken somewhere else, but I think I can handle that one). If someone wants to see it anyway, I can edit my question.</p> <p>If it's at all relevant, the list items have their data and are clickable, but they appear greyed out as though they are unclickable. Perhaps that's a styling issue, but I would figure they would use the style shared by the rest of the app.</p> <p>But to reiterate my problem, the listview is populating, but the adapter claims to be empty. I'm not sure how big of an issue it is/will be, but I would like either a way to get them to agree or an explanation of why they might not need to.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload