AutoCompleteTextView with CursorLoader and SimpleCursorAdapter - android

I try to populate the suggestions list with the data of a db table. However I get StaleDataExceptions. It throws quite randomly, but always when I enter a character into the textview.
Here is my code:
CursorLoader extending Cristian's SimpleCursorLoader class
public class TagCursorLoader extends SimpleCursorLoader {
private String mSelection;
private TagDbLoader mDbLoader;
public TagCursorLoader(Context context, TagDbLoader dBLoader, String selection) {
super(context);
this.mDbLoader = dBLoader;
this.mSelection = selection;
}
#Override
public Cursor loadInBackground() {
return mDbLoader.fetchContainingString(mSelection);
}
}
The Loader callbacks:
public class TagCursorLoaderCallback implements LoaderCallbacks<Cursor>, CursorToStringConverter {
private Context mContext;
private TagDbLoader mdDbLoader;
private SimpleCursorAdapter mAdapter;
private String mSelection;
public TagCursorLoaderCallback(Context context, TagDbLoader dBLoader, SimpleCursorAdapter adapter) {
this.mContext = context;
this.mdDbLoader = dBLoader;
mAdapter = adapter;
mSelection = "";
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new TagCursorLoader(mContext, mdDbLoader, mSelection);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if (!data.isClosed()) {
mAdapter.swapCursor(data);
}
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
public void setSelection(String mSelection) {
this.mSelection = mSelection;
}
#Override
public CharSequence convertToString(Cursor cursor) {
return cursor.getString(cursor.getColumnIndexOrThrow(DbConstants.Tags.KEY_TAG));
}
}
And finally when I set up the AutoCompleteTextView:
private void initializeAutoComplete() {
mTagDbLoader = new TagDbLoader(getActivity());
mTagDbLoader.open();
mTagInput = (AutoCompleteTextView) mLayout.findViewById(R.id.autoComplete);
mTagInput.addTextChangedListener(new TextWatcherAdapter() {
#Override
public void afterTextChanged(Editable s) {
mLoaderCallback.setSelection(s.toString());
getLoaderManager().restartLoader(0, null, mLoaderCallback);
}
});
mAdapter = new SimpleCursorAdapter(getActivity(), android.R.layout.simple_list_item_1,
null, new String[] { DbConstants.Tags.KEY_TAG }, new int[] { android.R.id.text1 },
0);
mLoaderCallback = new TagCursorLoaderCallback(getActivity(), mTagDbLoader, mAdapter);
mAdapter.setCursorToStringConverter(mLoaderCallback);
mTagInput.setAdapter(mAdapter);
getLoaderManager().initLoader(0, null, mLoaderCallback);
}

After some investigation, it seems that SimpleCursorAdapter inherits from ResourceCursorAdapter, which inherits from CursorAdapter. CursorAdapter uses CursorFilter for filtering, and this class calls changeCursor() in its publishResults(). changeCursor closes the old cursor... So that's why my cursors were closed automatically.
I dropped the loaders, and changed the implementation to the code below, and it works greatly:
mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1,
mTagDbLoader.fetchAll(), new String[] { DbConstants.Tags.KEY_TAG },
new int[] { android.R.id.text1 }, 0);
mAdapter.setFilterQueryProvider(new FilterQueryProvider() {
#Override
public Cursor runQuery(CharSequence constraint) {
if (constraint == null || constraint.equals(""))
return mAdapter.getCursor();
return mTagDbLoader.fetchContainingString(constraint.toString());
}
});
mAdapter.setCursorToStringConverter(new CursorToStringConverter() {
#Override
public CharSequence convertToString(Cursor c) {
return c.getString(c.getColumnIndexOrThrow(DbConstants.Tags.KEY_TAG));
}
});

Related

Async Task blocking UI thread

UPDATE
Thanks to #EmanuelSeibold I was able to pinpoint the problem to the update of the recyclerview. The AsyncTask works in the background just fine, and only the adapter update of the recyclerview freezes the UI.
UPDATE2
I found it was indeed my layout setup. I forgot to remove the nestedScrollView around the RecyclerView. That seemed to cause a rendering conflict.
I dug my way through answers here and blog posts, but just don't seem to be able to find a solution.
I am fairly new to Android development and trying to get an idea on multi-threading.
The scenario: I have an app that holds a SQLite database with course data and implemented a search function that queries that database. This blocks the UI-thread for roughly ~3 seconds.
I therefore implemented an AsyncTask to keep the UI responsive, but my UI is still blocked while the search is ongoing.
Thanks in advance!
Here the code:
Search activity
public class Activity_Search extends Activity_Base {
private RecyclerView rv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
setActionBarTitle(R.string.title_search);
findViewById(R.id.searchCourseTitle).setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
switch(keyCode) {
case KeyEvent.KEYCODE_ENTER:
startSearch();
break;
default:
return false;
}
return true;
}
});
rv = (RecyclerView) findViewById(R.id.searchRecycler);
Adapter_Search adapter = new Adapter_Search(this, null);
rv.setAdapter(adapter);
rv.setLayoutManager(new LinearLayoutManager(this));
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.search_FAB);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startSearch();
}
});
}
private void startSearch() {
findViewById(R.id.searchCourseTitle).clearFocus();
if (this.getCurrentFocus() != null) {
InputMethodManager imm =
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
}
{getting input}
String[] columns = {...};
String selection = {formatting input};
Async_Search search = new Async_Search(this);
search.execute(columns, new String[]{selection});
}
public void onSearchCompleted(Cursor results) {
((Adapter_Search) rv.getAdapter()).changeCursor(results);
}
}
AsyncTask
public class Async_Search extends AsyncTask<String[], Void, Cursor> {
private Activity activity;
public Async_Search (Activity activity) {
this.activity = activity;
}
#Override
protected Cursor doInBackground(String[]... params) {
SQLiteDatabase db = SQL_Database.getInstance(activity).getWritableDatabase();
String[] columns = params[0];
String selection = params[1][0];
return db.query(...)
}
#Override
protected void onPostExecute(Cursor results) {
((Activity_Search) activity).onSearchCompleted(results);
}
}
Recycler adapter
public class Adapter_Search extends RecyclerCursorAdapter<Adapter_Search.ViewHolder>{
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView name, ects, studipCode, termYear, lecturers, fields;
public ViewHolder (View view) {
super(view);
{id lookups}
}
}
public Adapter_Search(Context context, Cursor cursor) {
super(context, cursor);
}
#Override
public ViewHolder onCreateViewHolder (ViewGroup parent, int ViewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.search_list_entry, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder (ViewHolder viewHolder, Cursor cursor) {
TextView name, ects, studipCode, termYear, lecturers, fields;
name = viewHolder.name;
ects = viewHolder.ects;
studipCode = viewHolder.studipCode;
termYear = viewHolder.termYear;
lecturers = viewHolder.lecturers;
fields = viewHolder.fields;
String termandyear = cursor.getString(cursor.getColumnIndexOrThrow(SQL_Database.COURSE_COLUMN_TERM)) +
String.format("%.2s",cursor.getString(cursor.getColumnIndexOrThrow(SQL_Database.COURSE_COLUMN_YEAR)));
name.setText(cursor.getString(cursor.getColumnIndexOrThrow(SQL_Database.COURSE_COLUMN_COURSE)));
String credits = cursor.getString(cursor.getColumnIndexOrThrow(SQL_Database.COURSE_COLUMN_ECTS)) + " ECTS";
ects.setText(credits);
{and so on}
}
}
Base adapter class
public abstract class RecyclerCursorAdapter <ViewHolder extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<ViewHolder> {
private Context mContext;
private Cursor mCursor;
private boolean mDataValid;
private int mRowIdColumn;
private DataSetObserver mDataSetObserver;
public RecyclerCursorAdapter(Context context, Cursor cursor) {
mContext = context;
mCursor = cursor;
mDataValid = cursor != null;
mRowIdColumn = mDataValid ? mCursor.getColumnIndex("_id") : -1;
mDataSetObserver = new NotifyingDataSetObserver();
if (mCursor != null) {
mCursor.registerDataSetObserver(mDataSetObserver);
}
}
public Cursor getCursor() {
return mCursor;
}
#Override
public int getItemCount() {
if (mDataValid && mCursor != null) {
return mCursor.getCount();
}
return 0;
}
#Override
public long getItemId(int position) {
if (mDataValid && mCursor != null && mCursor.moveToPosition(position)) {
return mCursor.getLong(mRowIdColumn);
}
return 0;
}
#Override
public void setHasStableIds(boolean hasStableIds) {
super.setHasStableIds(true);
}
public abstract void onBindViewHolder(ViewHolder viewHolder, Cursor cursor);
#Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
if (!mDataValid) {
throw new IllegalStateException("this should only be called when the cursor is valid");
}
if (!mCursor.moveToPosition(position)) {
throw new IllegalStateException("couldn't move cursor to position " + position);
}
onBindViewHolder(viewHolder, mCursor);
}
/**
* Change the underlying cursor to a new cursor. If there is an existing cursor it will be
* closed.
*/
public void changeCursor(Cursor cursor) {
Cursor old = swapCursor(cursor);
if (old != null) {
old.close();
}
}
/**
* Swap in a new Cursor, returning the old Cursor. Unlike
* {#link #changeCursor(Cursor)}, the returned old Cursor is <em>not</em>
* closed.
*/
public Cursor swapCursor(Cursor newCursor) {
if (newCursor == mCursor) {
return null;
}
final Cursor oldCursor = mCursor;
if (oldCursor != null && mDataSetObserver != null) {
oldCursor.unregisterDataSetObserver(mDataSetObserver);
}
mCursor = newCursor;
if (mCursor != null) {
if (mDataSetObserver != null) {
mCursor.registerDataSetObserver(mDataSetObserver);
}
mRowIdColumn = newCursor.getColumnIndexOrThrow("_id");
mDataValid = true;
notifyDataSetChanged();
} else {
mRowIdColumn = -1;
mDataValid = false;
notifyDataSetChanged();
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
}
return oldCursor;
}
private class NotifyingDataSetObserver extends DataSetObserver {
#Override
public void onChanged() {
super.onChanged();
mDataValid = true;
notifyDataSetChanged();
}
#Override
public void onInvalidated() {
super.onInvalidated();
mDataValid = false;
notifyDataSetChanged();
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
}
}
}
Maybe try to remove these lines from the Async Search.
private Activity activity;
public Async_Search (Activity activity) {
this.activity = activity;
}
Instead call like this:
Async_Search search = new Async_Search();
search.execute(columns, new String[]{selection});
I don't know if this will work, but my Asynctask doesn't use the activity stuff yours has.

DialogFragment/setMultiChoiceItems with Cursor

I'm trying to use setMultiChoiceItems in the DialogFragment with Cursor, the issue I'm having is that I the dialog displays nothing, what am I doing wrong?
My DialogFragment implementation is below
public class ContactPickerFragment extends DialogFragment implements
LoaderCallbacks<Cursor> {
ArrayList mSelectedItems;
ArrayList arrayList;
Cursor listCursor;
private static Context context;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = getActivity();
getLoaderManager().initLoader(0, null, this);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
mSelectedItems = new ArrayList();
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Title")
.setMultiChoiceItems(listCursor, "ischecked", "fname",
new DialogInterface.OnMultiChoiceClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which, boolean isChecked) {
if (isChecked) {
mSelectedItems.add(which);
} else if (mSelectedItems.contains(which)) {
mSelectedItems.remove(Integer
.valueOf(which));
}
}
})
.setPositiveButton(R.string.ok,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
}
})
.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
}
});
return builder.create();
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new ContactListCursorLoader(getActivity());
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
listCursor = cursor;
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
listCursor = null;
}
private static class ContactListCursorLoader extends SQLiteCursorLoader {
public ContactListCursorLoader(Context context) {
super(context);
}
#SuppressLint("NewApi")
#Override
protected Cursor loadCursor() {
return new DBHelper(context).queryContacts();
}
}
}
My cursor is below
public ContactCursor queryContacts() {
Cursor wrapped = getReadableDatabase().query("contacts", null, null, null,
null, null, "time" + " desc");
return new ContactCursor(wrapped);
}
public static class ContactCursor extends CursorWrapper {
public ContactCursor(Cursor c) {
super(c);
}
public Contacts getContacts() {
if (isBeforeFirst() || isAfterLast())
return null;
Contacts contacts = new Contacts();
contacts.setFname(getLong(getColumnIndex("fname")));
return contacts;
}
}
and my db is this
db.execSQL("create table contacts (_id integer primary key autoincrement, num UNSIGNED big int, fname text, sname text, lname text, ischecked int, time int ) ");
Update 1
when I do this it works fine,
.setMultiChoiceItems( new DBHelper(context).queryContacts(), "ischecked", "fname",
So the question now is how can I update the cursor "listCursor" after the loader finishes loading it?

ExpandableListView using SimpleCursorTreeAdapter scrolls to top on update

I have created an ExpandableListAdapter by extending SimpleCursorTreeAdapter. The cursors are managed by loaders. When the list is displayed to user , I start a background service to fetch latest data from server. If the server returns new data I add it to DB and notify the children cursors. The cursors gets requeried and the list updates. At this point if the user has scrolled down in the list, the list scrolls up to top. This is very annoying. I have gone through the entire API for *TreeAdapters and do not see any method to prevent it. This must be a very common problem. How can I fix it ?
Try this code:
public class GroupsAdapter extends SimpleCursorTreeAdapter {
private final String TAG = getClass().getSimpleName().toString();
private final FragmentActivity mActivity;
private final ContactsFragment mFragment;
private static final String[] CONTACTS_PROJECTION = new String[] {
ContactsContract.Users._ID, ContactsContract.Users.USER_ID,
ContactsContract.Users.NAME, ContactsContract.Users.STATUS_TYPE,
ContactsContract.Users.STATUS_MESSAGE,
ContactsContract.Users.HAS_ALERT };
// Note that the constructor does not take a Cursor. This is done to avoid
// querying the database on the main thread.
public GroupsAdapter(final Context context, final ContactsFragment glf,
final int groupLayout, final int childLayout,
final String[] groupFrom, final int[] groupTo,
final String[] childrenFrom, final int[] childrenTo) {
super(context, null, groupLayout, groupFrom, groupTo, childLayout,
childrenFrom, childrenTo);
mActivity = (FragmentActivity) context;
mFragment = glf;
}
#Override
protected Cursor getChildrenCursor(final Cursor groupCursor) {
final String id = groupCursor.getString(groupCursor
.getColumnIndex(ContactsContract.Groups.GROUP_ID));
final CursorLoader cursorLoader = new CursorLoader(mActivity,
ContactsContract.Users.CONTENT_URI, CONTACTS_PROJECTION, "("
+ ContactsContract.UserGroupColumns.GROUP_ID + "=?)",
new String[] { id }, null);
Cursor childCursor = null;
try {
childCursor = cursorLoader.loadInBackground();
childCursor.moveToFirst();
} catch (final Exception e) {
Log.e(TAG, e.getMessage());
}
return childCursor;
}
}
and the fragment:
public class ContactsFragment extends Fragment implements
LoaderCallbacks<Cursor> {
private static final String[] GROUPS_PROJECTION = new String[] {
ContactsContract.Groups._ID, ContactsContract.Groups.NAME,
ContactsContract.Groups.GROUP_ID,
ContactsContract.Groups.USERS_COUNT };
private static final String TAG = "ContactsFragment";
ExpandableListView listView;
GroupsAdapter mAdapter;
public ContactsFragment() {
// Required empty public constructor
}
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(final LayoutInflater inflater,
final ViewGroup container, final Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_contacts, container, false);
}
#Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.contacts_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
listView = (ExpandableListView) getView().findViewById(
android.R.id.list);
// listView.setEmptyView();
// Set up our adapter
mAdapter = new GroupsAdapter(getActivity(), R.layout.group,
R.layout.user, new String[] { ContactsContract.Groups.NAME,
ContactsContract.Groups.USERS_COUNT }, // Name
// for group layouts
new int[] { R.id.group, R.id.count }, new String[] {
ContactsContract.Users.NAME,
ContactsContract.Users.STATUS_MESSAGE }, // Name
// for child layouts
new int[] { R.id.user_name, R.id.status_message });
listView.setAdapter(mAdapter);
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
final Loader<Cursor> loader = getLoaderManager().getLoader(-1);
if (loader != null && !loader.isReset()) {
getLoaderManager().restartLoader(-1, null, this);
} else {
getLoaderManager().initLoader(-1, null, this);
}
getActivity().getContentResolver().registerContentObserver(
ContactsContract.Users.CONTENT_URI, false,
new ContentObserver(null) {
#Override
public void onChange(final boolean selfChange) {
Log.w(TAG, "Change");
}
});
}
#Override
public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
// This is called when a new Loader needs to be created.
// group cursor
final CursorLoader cl = new CursorLoader(getActivity(),
ContactsContract.Groups.CONTENT_URI, GROUPS_PROJECTION, null,
null, null);
return cl;
}
#Override
public void onLoadFinished(final Loader<Cursor> loader, final Cursor cursor) {
// Swap the new cursor in.
final int id = loader.getId();
if (id == -1) {
mAdapter.setGroupCursor(cursor);
}
}
#Override
public void onLoaderReset(final Loader<Cursor> loader) {
// This is called when the last Cursor provided to onLoadFinished()
// is about to be closed.
final int id = loader.getId();
if (id != -1) {
// child cursor
try {
mAdapter.setChildrenCursor(id, null);
} catch (final NullPointerException e) {
Log.w("TAG", "Adapter expired, try again on the next query: "
+ e.getMessage());
}
} else {
mAdapter.setGroupCursor(null);
}
}
}

android getAdapter().getCount() returning 0

I have a spinner which is populated using a CursorLoader. It gets populated correctly. However spinner.getAdapter().getCount() keeps returning 0. why is that :(
My spinner class is
public class CategorySpinner extends Spinner implements LoaderManager.LoaderCallbacks<Cursor> {
Context myContext;
private SimpleCursorAdapter adapter;
public CategorySpinner(Context context, AttributeSet attrs) {
super(context, attrs);
myContext=context;
}
public void fillData(int projectId) {
String[] from = new String[] { Category.CATEGORYNAME };
int[] to = new int[] { R.id.label1 };
int layout = R.layout.category_list_item;
Bundle bundle=new Bundle();
bundle.putInt("ID", projectId);
EditExpenseActivity mActivity=(EditExpenseActivity)myContext;
mActivity.getLoaderManager().initLoader(0, bundle,this);
adapter = new SimpleCursorAdapter(myContext, layout, null, from, to, 0);
adapter.setDropDownViewResource(R.layout.category_list_item);
this.setAdapter(adapter);
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] projection = { Category.FULL_ID,Category.CATEGORYNAME };
Uri uri = Uri.parse(MyContentProvider.CATEGORY_LIST_PATH +args.getInt("ID"));
CursorLoader cursorLoader = new CursorLoader(myContext, uri, projection,null, null, null);
return cursorLoader;
}
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
// data is not available anymore, delete reference
adapter.swapCursor(null);
}
}
The activity that is calling the spinner is EditExpenseActivity
public class EditExpenseActivity extends Activity {
private Context myContext;
private CategorySpinner sp_Category;
private Intent intent;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_edit_expense);
intent=getIntent();
final int mProjectId=intent.getIntExtra("ID",0);
myContext = this;
sp_Category = (CategorySpinner) findViewById(R.id.input_category);
//fill spinner with categories of the project with Id mProjectId
sp_Category.fillData(mProjectId);
//so far so good .. spinner is populated perfectly
int i=sp_Category.getAdapter().getCount();
}
}
Debug shows i value to be 0. why???

How to fill listviews with sqlite data, which are swiped horizontally

My goal is to swipe lists horizontally , which are filled by public class ClientsManagerOpenHandler extends SQLiteOpenHelper.
I try to reach this goal by working with viewpager and ListFragments. If you have an other solution please tell me.
Now the problem:
If I try to call from the following PageListFragment.java, data from ClientsManagerOpenHandler the program crashes at:
dbCursorTerminAnsicht = openHandler.queryTabelle("terminansicht");
Maybe I cannot call an extended SQLiteOpenHelper within ListFragment? But how I get the data from sqlite into my lists, and when I swipe horizontally to change data...
Please help. I have tried anything, but I really need help now.
public class PageListFragment extends ListFragment implements OnClickListener,
LoaderCallbacks<Cursor> {
private Calendar cal = Calendar.getInstance();
private ClientsManagerOpenHandler openHandler;
public static final String PREFS_NAME ="MyPrefsFile";
SharedPreferences prefs;`
private Cursor dbCursorTerminAnsicht;
private Integer intVerdienst = 0;
private String queryVerdienst;
private SimpleCursorAdapter mCursorAdapter;
private ListView listViewTermine;
private final int listNr;
private final String[] fruit = { "Bananen", "Apfle", "Erdbeere",
"Kirschen", "Mangos" };
private Uri[] mMediaSource = {null, MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI, MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI};
public PageListFragment(int nr) {
this.listNr = nr;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//!!!!! after the next line the program crashes. Even I have set breakpoints at ClientsManagerOpenHandler
//I cannot see anything in the debugger (Debugger: Source not found...)
dbCursorTerminAnsicht = openHandler.queryTabelle("terminansicht");
if (listNr == 0) {
ArrayAdapter<String> openHandler = new ArrayAdapter<String>(
getActivity(), android.R.layout.simple_list_item_1, fruit);
setListAdapter(openHandler);
} else if (listNr == 1) {
mCursorAdapter = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_1, null,
new String[] { MediaStore.Audio.Artists.ARTIST },
new int[] { android.R.id.text1 }, 0);
setListAdapter(mCursorAdapter);
getLoaderManager().initLoader(0, null, this);
} else if (listNr == 2) {
openHandler = new ClientsManagerOpenHandler(getActivity());
String query = "projekte, klienten, termine WHERE termine.KLIENTID = klienten._id AND termine.PROJEKTID = projekte._id ORDER BY BEGINN ASC;";
MyDataAdapter myClientsadapter = new MyDataAdapter (
getActivity(),
R.layout.terminzeile,
// android.R.layout.two_line_list_item,
dbCursorTerminAnsicht,
new String[] { openHandler.BEGINN , openHandler.ENDE, openHandler.NACHNAME, openHandler.VORNAME, openHandler.PROJEKT, openHandler.BEZAHLT},
// fields,
// new int[] {R.id.editTextNachname, R.id.editTextVorname }
new int[] {R.id.textViewBeginn, R.id.textViewEnde, R.id.textViewNachname, R.id.textViewVorname, R.id.textViewProjekt,R.id.checkBoxBezahlt }
);
myClientsadapter.setViewBinder(new MyDataAdapter.ViewBinder() {
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
if(columnIndex == 13) {
String strBeginn = cursor.getString(columnIndex);
CheckBox cb = (CheckBox) view;
int intbezahlt = cursor.getInt(13);
int index = cursor.getColumnIndex("SATZ");
Integer intSatz = cursor.getInt(index);
if (index>0) {
if (intbezahlt>0){
intVerdienst = intVerdienst + intSatz;
}
}
cb.setChecked(intbezahlt > 0);
return true;
}
String str = cursor.getString(columnIndex);
return false;
}
});
//TerminlisteRefresh("");
setListAdapter(myClientsadapter);
getLoaderManager().initLoader(0, null, this);
}
}
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
Loader<Cursor> loader = new CursorLoader(getActivity(), mMediaSource[listNr],
null, null, null, null);
return loader;
}
public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {
mCursorAdapter.swapCursor(cursor);
}
public void onLoaderReset(Loader<Cursor> arg0) {
mCursorAdapter.swapCursor(null);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
It appears that you are trying to access openHandler before you have defined it:
dbCursorTerminAnsicht = openHandler.queryTabelle("terminansicht");
...
openHandler = new ClientsManagerOpenHandler(getActivity());
This might work better:
openHandler = new ClientsManagerOpenHandler(getActivity());
dbCursorTerminAnsicht = openHandler.queryTabelle("terminansicht");

Categories

Resources