0

Так что я разрабатываю приложение в течение лета. Он хранит элементы в базе данных, отображает их в списке (в противном случае Toast сообщает пользователю о своем пустом) и позволяет пользователям видеть детали, щелкая по одному. В конце концов я планирую, что критерии поиска сужаются по списку, но я еще не там.Listview заполняет, но адаптер утверждает, что он пуст

Моя проблема заключается в том, что ListView, кажется, заселение, но приложение делает Тост ....

ResultsActivity.java

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 

ResultsFragment.java

public class ResultsFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor>{ 
    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 && 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<Cursor> 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<Cursor> loader, Cursor cursor){ 
     adapter.swapCursor(cursor); 
    }// method: LoaderCallbacks.onLoadFinished(Loader<Cursor>, Cursor) 

    @Override 
    public void onLoaderReset(Loader<Cursor> loader){ 
     adapter.swapCursor(null); 
    }// method: LoaderCallbacks.onLoaderReset(Loader<Cursor>) 

    /* 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 

activity_results. xml

<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"> 

    <!-- @android:id/list is the necessary id for the activity to find it. --> 
    <ListView 
     android:id="@android:id/list" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:padding="5dp"> 
    </ListView> 
    <TextView 
     android:id="@+id/results_empty" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@string/txt_no_results"/> 
</LinearLayout> 

fragment_results.xml

<?xml version="1.0" encoding="utf-8"?> 
<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"/> 

list_item_results.xml

<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"> 

    <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"/> 
    <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"/> 

    <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"/> 
    <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"/> 
    <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"/> 
</RelativeLayout> 

я, вероятно, понимают, как использовать фрагменты, но это было необходимо для того, чтобы использовать учебник я следующий за помощью контент-провайдеров. Я не включил контент-провайдера здесь, но я уверен, что он работает (ну ... сломался где-то в другом месте, но я думаю, что смогу справиться с этим). Если кто-то хочет его увидеть, я могу изменить свой вопрос.

Если это вообще имеет значение, элементы списка имеют свои данные и могут быть интерактивными, но они кажутся серыми, как будто они неприступны. Возможно, это проблема стиля, но я бы подумал, что они будут использовать стиль, разделяемый остальной частью приложения.

Но, чтобы повторить мою проблему, список просматривается, но адаптер утверждает, что он пуст. Я не уверен, насколько большой проблемой будет/будет, но я хотел бы либо получить их, чтобы они согласились, либо объяснили, почему им это может не понадобиться.

ответ

0

или объяснение причин, по которым им может не понадобиться.

Они, похоже, не согласны с тем, что адаптер действительно пуст в то время, когда вызывается isEmpty. Android Loaders выполняют работу по отдельному потоку (асинхронно).

Я предлагаю setting empty view вместо использования тостов.

+1

Итак: переместите свой тост-код в 'onLoadFinished' – dmon

+0

Неудивительно, что объяснение api для' setEmptyView() 'не помогло. Я не нахожу, как реализовать это в Activity или Fragment где угодно; Я нашел 'setEmptyText()' для фрагмента, поэтому я вставил его в метод OnViewCreated. Полагаю, что это сработает; в противном случае кажется достаточно простым, чтобы поставить тост в onLoadFinished, как упоминалось в @dmon. В любом случае, это не объясняет, почему текст серый. Это проблема стиля? И где я это исправим? – Stspurg

+0

Тогда я думаю, что ваш вопрос непонятен. Причина, по которой он пуст, когда вы показываете тост, заключается в том, что он загружается асинхронно, данных еще нет. Это не имеет ничего общего с Фрагментами. Если вы действительно хотите показать тост (почему?), Вам придется переместить его на onLoadFinished. И я не знаю, почему ваши взгляды серые. – dmon

 Смежные вопросы

  • Нет связанных вопросов^_^