Так что я разрабатываю приложение в течение лета. Он хранит элементы в базе данных, отображает их в списке (в противном случае 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>
я, вероятно, понимают, как использовать фрагменты, но это было необходимо для того, чтобы использовать учебник я следующий за помощью контент-провайдеров. Я не включил контент-провайдера здесь, но я уверен, что он работает (ну ... сломался где-то в другом месте, но я думаю, что смогу справиться с этим). Если кто-то хочет его увидеть, я могу изменить свой вопрос.
Если это вообще имеет значение, элементы списка имеют свои данные и могут быть интерактивными, но они кажутся серыми, как будто они неприступны. Возможно, это проблема стиля, но я бы подумал, что они будут использовать стиль, разделяемый остальной частью приложения.
Но, чтобы повторить мою проблему, список просматривается, но адаптер утверждает, что он пуст. Я не уверен, насколько большой проблемой будет/будет, но я хотел бы либо получить их, чтобы они согласились, либо объяснили, почему им это может не понадобиться.
Итак: переместите свой тост-код в 'onLoadFinished' – dmon
Неудивительно, что объяснение api для' setEmptyView() 'не помогло. Я не нахожу, как реализовать это в Activity или Fragment где угодно; Я нашел 'setEmptyText()' для фрагмента, поэтому я вставил его в метод OnViewCreated. Полагаю, что это сработает; в противном случае кажется достаточно простым, чтобы поставить тост в onLoadFinished, как упоминалось в @dmon. В любом случае, это не объясняет, почему текст серый. Это проблема стиля? И где я это исправим? – Stspurg
Тогда я думаю, что ваш вопрос непонятен. Причина, по которой он пуст, когда вы показываете тост, заключается в том, что он загружается асинхронно, данных еще нет. Это не имеет ничего общего с Фрагментами. Если вы действительно хотите показать тост (почему?), Вам придется переместить его на onLoadFinished. И я не знаю, почему ваши взгляды серые. – dmon