I have a series of ListFragments
each displaying a different SQLite table or view. I switch between them with swipable tab layouts.
I have two different swipable layouts that load into the same activity, depending on the Intent arguments which are called. Buttons on an alertdialog and on the actionbar switch the swipable layouts. The Swipable Tab setup is described http://www.pushing-pixels.org/2011/08/11/android-tips-and-tricks-swipey-tabs.html .
The problem occurs after the item click.
android.database.sqlite.SQLiteException: no such column: authorHash: ,
while compiling: SELECT name, shared, authorHash, primaryMatch
FROM contacts_view
The Exception shows that the SELECT clause is from the first declaration below, while the VIEW is from the second.
LogFragment.newInstance(PeerDataProvider.URI_RESPONSES_VIEW,
PeerDataProvider.URI_PEERDATA_TABLE, R.loader.responseslogfragloader,
PeerCreatedDataColumns.NAME,
new String[] { PeerCreatedDataColumns.NAME,
PeerCreatedDataColumns.SHARED, PeerCreatedDataColumns.AUTHORHASH,
ResponsesColumns.PRIMARYMATCH });
LogFragment.newInstance(UserDataProvider.URI_CONTACTS_VIEW,
UserDataProvider.URI_USERDATA_TABLE, R.loader.contactslogfragloader,
UserCreatedDataColumns.NAME,
new String[] { UserCreatedDataColumns.LONGSUMMARY });
Here is the fragment being called:
public class LogFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {
private static int LIST_LOADER;
protected int layout = R.layout.log_fragment;
int entryLayout = R.layout.list_item;
private static Uri logView, logTable;
String[] listItemProjection;
int[] listItemFields = { R.id.title };
String itemClickProjection[];
String[] createProjection;
int mCurCheckPosition = 0;
Button clearLogButton;
protected SimpleCursorAdapter listAdapter;
public static Fragment newInstance(Uri logview, Uri logtable, int listLoader, String displayColumn,
String[] clickProjection) {
LogFragment f = new LogFragment();
Bundle args = new Bundle();
args.putString("listItemProjection", "" + displayColumn);
args.putStringArray("itemClickProjection", clickProjection);
args.putString("logView", "" + logview);
args.putString("logTable", "" + logtable);
args.putString("LIST_LOADER", "" + listLoader);
Log.d(DEBUG_TAG, "listLoader" + listLoader);
f.setArguments(args);
return f;
}
public LogFragment() {
super();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(layout, container, false);
String listItemProjection_String = getArguments().getString("listItemProjection");
String[] itemClickProjection_StringArray = getArguments().getStringArray("itemClickProjection");
String logView_String = getArguments().getString("logView");
String logTable_String = getArguments().getString("logTable");
String LIST_LOADER_String = getArguments().getString("LIST_LOADER");
listItemProjection = new String[] { listItemProjection_String };
createProjection = new String[] { UserDatabase._ID, listItemProjection_String };
itemClickProjection = itemClickProjection_StringArray;
logView = Uri.parse(logView_String);
logTable = Uri.parse(logTable_String);
LIST_LOADER = Integer.parseInt(LIST_LOADER_String);
getLoaderManager().initLoader(LIST_LOADER, null, this);
listAdapter = new SimpleCursorAdapter(getActivity().getApplicationContext(), entryLayout, null,
listItemProjection, listItemFields, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
setListAdapter(listAdapter);
return view;
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
Cursor c = getActivity().getContentResolver().query(logView, itemClickProjection, null, null, null);
String fields = "";
c.moveToPosition(position);
for (String column : itemClickProjection) {
fields += column + " " + c.getString(c.getColumnIndex(column)) + "\n";
Toast.makeText(getActivity(), fields, Toast.LENGTH_SHORT).show();
}
}
}
And here is the adapter
private class SearchSwipePagerAdapter extends FragmentPagerAdapter implements SwipeyTabsAdapter {
private final String DEBUG_TAG = "SearchSwipePagerAdapter";
private final Context mContext;
public SearchSwipePagerAdapter(Context context, FragmentManager fm) {
super(fm);
this.mContext = context;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return SearchFragment.newInstance();
case 1:
return ResponsesFragment.newInstance();
case 2:
return LogFragment.newInstance(PeerDataProvider.URI_RESPONSES_VIEW,
PeerDataProvider.URI_PEERDATA_TABLE, R.loader.responseslogfragloader,
PeerCreatedDataColumns.NAME, new String[] { PeerCreatedDataColumns.NAME,
PeerCreatedDataColumns.SHARED, PeerCreatedDataColumns.AUTHORHASH,
ResponsesColumns.PRIMARYMATCH });
case 3:
return LogFragment.newInstance(UserDataProvider.URI_CONTACTS_VIEW, UserDataProvider.URI_USERDATA_TABLE,
R.loader.contactslogfragloader, UserCreatedDataColumns.NAME,
new String[] { UserCreatedDataColumns.LONGSUMMARY });
case 4:
return LogFragment.newInstance(PeerDataProvider.URI_METHODS_VIEW, PeerDataProvider.URI_PEERDATA_TABLE,
R.loader.methodslogfragloader, PeerCreatedDataColumns.NAME, new String[] {
PeerCreatedDataColumns.NAME, PeerCreatedDataColumns.SHARED,
PeerCreatedDataColumns.AUTHORHASH, MethodsColumns.PRIMARYMATCH });
default:
return SwipeyTabFragment.newInstance(WORKFLOW[position]);
}
}
Each fragment has a unique loader id. I am maintaining compatibility mode throughout the project.
This declaration:
private static Uri logView, logTable;
means your LogFragment
will always have as those Uris
the Uris
that you pass to the last fragment built by the FragmentPagerAdapter
as those static variables will be shared by your LogFragment
instances. Make those fields as instance variables:
private Uri logView, logTable;