Listview with CursorAdapter, i want to notify it on onClick event below .
CursorAdapter
public class HistoryAdapter extends CursorAdapter {
Button button;
TextView text;
final MainActivity mainActivity ;
HistoryDialogue historyDialogue ;
public HistoryAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
mainActivity = (MainActivity) context;
historyDialogue = new HistoryDialogue();
}
#Override
public View newView(final Context context, Cursor cursor, ViewGroup parent) {
View view = LayoutInflater.from(context).inflate(R.layout.historylist, parent, false);
return view;
}
#Override
public void bindView(View view, final Context context, final Cursor cursor) {
text = (TextView) view.findViewById(R.id.text);
button = (Button) view.findViewById(R.id.btn);
final int pos = cursor.getPosition();
cursor.moveToFirst();
String body = cursor.getString(cursor.getColumnIndex(Contract.SaveRunning_Name.NAME));
text.setText(body);
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
// this for delete only items in history list by getting cursor position then use it to get number of ites row
// in database finally delete it ...
ContentResolver resolver = context.getContentResolver();
Cursor c = resolver.query(Contract.SaveRunning_Name.CONTENT_URI,null,null,null,null);
c.moveToPosition(pos);
int position_column =c.getColumnIndex(Contract.SaveRunning_Name._ID);
int position = c.getInt(position_column);
String delete_save = Contract.SaveRunning_Name._ID + " = " + position + ";";
int srun = resolver.delete(Contract.SaveRunning_Name.CONTENT_URI, delete_save, null);
updateEntries();
}
});
}
public void updateEntries(){
mainActivity.addEntries(0,0,true);
}
}
DialogFragment
public class HistoryDialogue extends DialogFragment implements View.OnClickListener {
ListView list ;
Cursor c;
HistoryAdapter adapter;
History history ;
Button button ;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
history = (History) activity;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setCancelable(true);
getDialog().setTitle("History");
View view = inflater.inflate(R.layout.history,null);
list = (ListView) view.findViewById(R.id.listView);
button = (Button) view.findViewById(R.id.button);
button.setOnClickListener(this);
ContentResolver resolver = getActivity().getContentResolver();
c = resolver.query(Contract.SaveRunning_Name.CONTENT_URI, null, null, null, null);
adapter = new HistoryAdapter(getActivity(), c, 0);
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
setChart(position);
dismiss();
}
});
return view ;
}
public void setChart(int position) {
Cursor cursor;
ContentResolver resolver = getActivity().getContentResolver();
cursor = resolver.query(Contract.SaveRunning.CONTENT_URI, null,null, null, null);
cursor.moveToPosition(position);
int HIGH_COLUMN = cursor.getColumnIndex(Contract.SaveRunning.HIGH);
int high = cursor.getInt(HIGH_COLUMN);
int LOW_COLUMN = cursor.getColumnIndex(Contract.SaveRunning.LOW);
int offset = cursor.getInt(LOW_COLUMN);
int limit = high-offset ;
history.limits(limit,offset,false,false);
}
#Override
public void onClick(View v) {
Cursor cursor;
Cursor running ;
ContentResolver resolver = getActivity().getContentResolver();
cursor = resolver.query(Contract.SaveRunning.CONTENT_URI, null,null, null, null);
ContentResolver solver = getActivity().getContentResolver();
running = solver.query(Contract.Running.CONTENT_URI, null,null, null, null);
if(cursor!=null && running!=null) {
cursor.moveToLast();
int HIGH_COLUMN = cursor.getColumnIndex(Contract.SaveRunning.HIGH);
int offset = cursor.getInt(HIGH_COLUMN);
running = resolver.query(Contract.Running.CONTENT_URI, null, null, null, null);
running.moveToLast();
int id = running.getColumnIndex(Contract.Running._ID);
int LAST_RUNNING_ID = running.getInt(id);
int limit = LAST_RUNNING_ID - offset;
history.limits(limit, offset, false, false);
dismiss();
}
}
interface History {
public void limits(int limit,int offset,boolean state,boolean back);
}
}
How can i achieve that ?
thanx in advance
You can use broadcast receiver to notify fragment
OR create callback method to notify fragment
1]create interface and implement it on your fragment
2] pass its object in adapter and use that object to notify fragment
//code example
public interface ICallback {
void onClick();
}
// HistoryAdapter
#Override
public void bindView(View view, final Context context, final Cursor cursor) {
//your code
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
//your code
iCallbackInstance.onClick();
}
});
}
EDIT
// In HistoryAdapter
public class HistoryAdapter extends CursorAdapter {
ICallback iCallbackInstance;
public HistoryAdapter(Context context, Cursor c, int flags, ICallback instance;) {
super(context, c, flags);
mainActivity = (MainActivity) context;
historyDialogue = new HistoryDialogue();
iCallbackInstance = instance;
}
}
//HistoryDialogue
Use
adapter = new HistoryAdapter(getActivity(), c, 0, HistoryDialogue.this)
instead of
adapter = new HistoryAdapter(getActivity(), c, 0)
Related
I have listView in my fragment i use a cursorAdapter to fill the list view but problem is Adapter shows first row data on every item if there are 3 items in cursor listview show three items but all are same i search a lot but i found nothing usefull
fragment:
public class ListPatientFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
private PatientAdapter mPatientAdapter;
private ListView mListView;
private Button mAddButton;
private int mPosition = ListView.INVALID_POSITION;
private static final String SELECTED_KEY = "selected_position";
public ListPatientFragment() {
}
public interface Callback {
/**
* DetailFragmentCallback for when an item has been selected.
*/
public void onItemSelected(Uri dateUri);
}
private static final String[] FORECAST_COLUMNS = {
MedicalContract.PropertyEntry.TABLE_NAME + "." + MedicalContract.PropertyEntry._ID,
MedicalContract.PropertyEntry.COLUMN_DATE,
MedicalContract.PropertyEntry.COLUMN_SEX,
MedicalContract.PropertyEntry.COLUMN_AGE,
MedicalContract.PropertyEntry.COLUMN_CHIEF_COMPLIMENT,
MedicalContract.PropertyEntry.COLUMN_RESIDENT_ILLNESS,
MedicalContract.PatientEntry.COLUMN_PATIENT_SETTING,
MedicalContract.PropertyEntry.COLUMN_NAME_KEY,
MedicalContract.PatientEntry.COLUMN_PATIENT_IDENTIFICATION,
MedicalContract.PatientEntry.COLUMN_PATIENT_SETTING,
MedicalContract.PatientEntry.COLUMN_FIRST_NAME,
MedicalContract.PatientEntry.COLUMN_LAST_NAME
};
static final int COL_PROPERTY_ID = 1;
static final int COL_DATE = 2;
static final int COL_SEX = 3;
// this is correct:
static final int COL_AGE = 4;
//this is correct:
static final int COL_RESIDENT_ILLNESS = 6;
//this is correct:
static final int COL_CHIEF_COMPLIMENT = 5;
static final int COL_PATIENT_IDENTIFICATION = 8;
static final int COL_PATIENT_SETTING = 9;
static final int COL_FIRST_NAME = 10;
static final int COL_LAST_NAME =11;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_list_patient, container, false);
//return inflater.inflate(R.layout.fragment_list_patient, container, false);
String sortOrder = MedicalContract.PropertyEntry.COLUMN_DATE + " DESC";
Uri allPatientUri = MedicalContract.PropertyEntry.buildAllPatientList(System.currentTimeMillis());
Cursor cur = getActivity().getContentResolver().query(allPatientUri,
null, null, null, sortOrder);
mPatientAdapter = new PatientAdapter(getActivity(), cur, 0);
mListView = (ListView) rootView.findViewById(R.id.MainListOfAllPatients);
mListView.setAdapter(mPatientAdapter);
mAddButton =(Button) rootView.findViewById(R.id.New_Patient_Button);
assert mAddButton !=null;
mAddButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Intent MyIntent= new Intent (getActivity(),MedicalActivity.class);
startActivity(MyIntent);
}
});
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView adapterView, View view, int position, long l) {
// CursorAdapter returns a cursor at the correct position for getItem(), or null
// if it cannot seek to that position.
Cursor cursor = (Cursor) adapterView.getItemAtPosition(position);
if (cursor != null) {
Toast.makeText(getActivity(),cursor.getString(COL_DATE),Toast.LENGTH_SHORT).show();
String PatientIdentification = cursor.getString(COL_PATIENT_IDENTIFICATION);
Long PatientDate=cursor.getLong(COL_PROPERTY_ID);
((Callback) getActivity())
.onItemSelected(MedicalContract.PropertyEntry.buildPropertyPatientWithDate(PatientIdentification,PatientDate));
}
mPosition = position;
}
});
return rootView;
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String sortOrder = MedicalContract.PropertyEntry.COLUMN_DATE + " DESC";
Uri listOfAllPatientUri = MedicalContract.PropertyEntry.buildAllPatientList(System.currentTimeMillis());
return new CursorLoader(getActivity(),
listOfAllPatientUri,
FORECAST_COLUMNS,
null,
null,
sortOrder);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mPatientAdapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
}
}
adapter:
public class PatientAdapter extends CursorAdapter {
public PatientAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
}
public static class ViewHolder {
public final ImageView iconView;
public final TextView patientFirstNameView;
public final TextView patientLastNameView;
public final TextView patientAgeView;
public final TextView patientResidentIllnessView;
public ViewHolder(View view) {
iconView = (ImageView) view.findViewById(R.id.list_item_icon);
patientFirstNameView = (TextView) view.findViewById(R.id.patient_first_name);
patientLastNameView = (TextView) view.findViewById(R.id.patient_last_name);
patientAgeView = (TextView) view.findViewById(R.id.patient_age);
patientResidentIllnessView = (TextView) view.findViewById(R.id.patient_resident_illness);
}
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
int layoutId = -1;
layoutId = R.layout.detail_list_patient;
View view = LayoutInflater.from(context).inflate(layoutId, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
view.setTag(viewHolder);
return view;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder viewHolder = (ViewHolder) view.getTag();
if(cursor != null &&cursor.moveToFirst()) {
String patientSex = cursor.getString(ListPatientFragment.COL_SEX);
if (patientSex.equals("Male")) {
viewHolder.iconView.setImageResource(R.mipmap.ic_male_icon);
} else if (patientSex.equals("Female")) {
viewHolder.iconView.setImageResource(R.mipmap.ic_female_icon);
}
String patientFirstName = cursor.getString(ListPatientFragment.COL_FIRST_NAME);
viewHolder.patientFirstNameView.setText(patientFirstName);
String patientLastName = cursor.getString(ListPatientFragment.COL_LAST_NAME);
viewHolder.patientLastNameView.setText(patientLastName);
String patientAge = cursor.getString(ListPatientFragment.COL_AGE);
viewHolder.patientAgeView.setText(patientAge);
String patientIllness = cursor.getString(ListPatientFragment.COL_RESIDENT_ILLNESS);
viewHolder.patientResidentIllnessView.setText(patientIllness);
}
}
}
XML listView:
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/MainListOfAllPatients"
android:background="#color/ColorPrimaryLight"></ListView>
I have a ChatActivity, which loads its data via a CursorLoader. The CursorLoader return a cursor with two registers, but the newView and bindView methods in adapter is never called.
My activity
public class ChatActivity extends BaseActivity implements LoaderManager.LoaderCallbacks<Cursor> {
public static final String EXTRA_AMANTEID = "amanteId";
private EditText messageET;
private ListView messagesContainer;
private Button sendBtn;
private ChatAdapter adapter;
private Long amanteId;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
amanteId = getIntent().getLongExtra(ChatActivity.EXTRA_AMANTEID, 0L);
messagesContainer = (ListView) findViewById(R.id.messagesContainer);
messageET = (EditText) findViewById(R.id.messageEdit);
sendBtn = (Button) findViewById(R.id.chatSendButton);
RelativeLayout container = (RelativeLayout) findViewById(R.id.container);
adapter = new ChatAdapter(this);
getLoaderManager().initLoader(0, null, this);
messagesContainer.setAdapter(adapter);
}
private void scroll() {
messagesContainer.setSelection(messagesContainer.getCount() - 1);
}
#Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
return new CursorLoader(ChatActivity.this, MensagemProvider.CONTENT_URI_CONVERSA, null, null, new String[]{Long.toString(amanteId), Long.toString(amanteId)}, null);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
adapter.swapCursor(cursor);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}
}
My adapter
public class ChatAdapter extends CursorAdapter {
private Cursor cursor;
private int dataEnvioColumnIndex;
private int idMensagemColumnIndex;
private int idRemetenteColumnIndex;
private int idDestinatarioColumnIndex;
private int apelidoRemetenteColumnIndex;
private int apelidoDestinatarioColumnIndex;
private int textoMensagemColumnIndex;
private long idColaboradorLogado;
public ChatAdapter(Context context) {
super(context, null, false);
}
public ChatMessage getItem() {
ChatMessage message = new ChatMessage();
SimpleDateFormat dt = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
Date dataEnvio = new Date(cursor.getLong(dataEnvioColumnIndex));
message.setDate(dt.format(dataEnvio));
message.setId(cursor.getLong(idMensagemColumnIndex));
Long de = cursor.getLong(idRemetenteColumnIndex);
Long logado = BaseApp.getCredentials().getId();
message.setMe(de.equals(logado));
message.setMessage(cursor.getString(textoMensagemColumnIndex));
return message;
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View retView = vi.inflate(R.layout.list_item_chat_message, null);
return retView;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder = createViewHolder(view);;
view.setTag(holder);
ChatMessage chatMessage = getItem();
boolean myMsg = chatMessage.getIsme() ;//Just a dummy check
holder.txtMessage.setText(chatMessage.getMessage());
holder.txtInfo.setText(chatMessage.getDate());
}
private ViewHolder createViewHolder(View v) {
ViewHolder holder = new ViewHolder();
holder.txtMessage = (TextView) v.findViewById(R.id.txtMessage);
holder.content = (LinearLayout) v.findViewById(R.id.content);
holder.contentWithBG = (LinearLayout) v.findViewById(R.id.contentWithBackground);
holder.txtInfo = (TextView) v.findViewById(R.id.txtInfo);
return holder;
}
private static class ViewHolder {
public TextView txtMessage;
public TextView txtInfo;
public LinearLayout content;
public LinearLayout contentWithBG;
}
#Override
public Cursor swapCursor(Cursor cursor) {
if(cursor!=null) {
cursor.moveToFirst();
idMensagemColumnIndex = cursor.getColumnIndex(MensagemProvider.COLUMN_MENSAGEMID);
idRemetenteColumnIndex = cursor.getColumnIndex(MensagemProvider.COLUMN_DE);
idDestinatarioColumnIndex = cursor.getColumnIndex(MensagemProvider.COLUMN_PARA);
apelidoRemetenteColumnIndex = cursor.getColumnIndex(MensagemProvider.COLUMN_APELIDO_REMETENTE);
apelidoDestinatarioColumnIndex = cursor.getColumnIndex(MensagemProvider.COLUMN_APELIDO_DESTINATARIO);
textoMensagemColumnIndex = cursor.getColumnIndex(MensagemProvider.COLUMN_MENSAGEM);
}
notifyDataSetChanged();
return cursor;
}
}
what I'm doing wrong ? Can anybody help me ?
Thanks!
Overriding swapCursor() is asking for trouble. The cursor won't be positioned where the adapter expects it to be positioned (before first). And you don't call super.swapCursor() so the adapter never really hears about the new cursor.
I bet you're trying to "optimize" by getting the column indexes only once each time a new cursor is swapped.
First just try getting rid of the swapCursor() override and making the getColumnIndex() calls in your getItem() method. If that works and you still really want to have getColumnIndex() called only once per cursor, you could try something like setting all your cursor indexes to -1 when you swap the cursor, then calling getColumnIndex() inside getItem() only when the index is -1.
But don't mess with swapCursor(), especially without calling super.swapCursor() and returning its result.
I'm trying to have a multiselect preference with data that is populated from a database via a cursor. I've got this so far
Cursor cursor = getActivity().getContentResolver().query(EntryProvider.WEBSITES_URI,null,null,null,EntryProvider.WEBSITES_SORT_ORDER);
while (cursor.moveToNext()) {
String name = cursor.getString(EntryData.COL_WEBSITE_NAME);
String displayName = cursor.getString(EntryData.COL_WEBSITE_ENABLED);
entries.add(name);
entriesValues.add(displayName);
}
feedSelectionPref = (MultiSelectListPreference)findPreference("feedChooser");
feedSelectionPref.setEntries(entries.toArray(new CharSequence[]{}));
feedSelectionPref.setEntryValues(entriesValues.toArray(new CharSequence[]{}));
and it fill up the prefrence fine, but I cannot figure out how to get the saved values and persist them to the database.
How can I get the new values from the preference? I tried setOnPreferenceChangeListener but it gave me the same values that I filled the list with, not the new ones.
(Would it be easier to just build a listview with checkboxes?)
So I solved the problem by just creating a popup list activity.
public class FeedChooserPopupActivity extends Activity {
ListView listView;
Cursor cursor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_feed_chooser);
initViews();
}
private void initViews(){
setupCursor();
setupListView();
setupButton();
}
private void setupButton() {
((Button)findViewById(R.id.feedOkbutton)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FeedChooserPopupActivity.this.finish();
}
});
}
private void setupCursor() {
cursor = getContentResolver().query(EntryProvider.WEBSITES_URI,null,null,null,EntryProvider.WEBSITES_SORT_ORDER);
}
private void setupListView() {
listView = (ListView)findViewById(R.id.feedListView);
listView.setAdapter(new FeedCursorAdapter(this,
cursor,
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER
));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
if (view != null) {
String websiteName = ((TextView)view.findViewById(R.id.feedTextView)).getText().toString();
CheckBox checkBox = (CheckBox)view.findViewById(R.id.feedCheckBox);
checkBox.setChecked(!checkBox.isChecked());
ContentValues cv = new ContentValues();
int enabled = 0;
if(checkBox.isChecked()){
enabled = 1;
}
cv.put(EntryData.KEY_WEBSITE_ENABLED, enabled);
String where = EntryData.KEY_WEBSITE_NAME+" = '"+websiteName+"'";
getContentResolver().update(EntryProvider.WEBSITES_URI,cv,where,null);
}
}
});
}
private class FeedCursorAdapter extends CursorAdapter {
public FeedCursorAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.feed_chooser_list_item,parent,false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
((TextView)view.findViewById(R.id.feedTextView)).setText(cursor.getString(EntryData.COL_WEBSITE_NAME));
((CheckBox)view.findViewById(R.id.feedCheckBox)).setChecked(
cursor.getInt(EntryData.COL_WEBSITE_ENABLED)==1
);
}
}
can you help me with simple eample? I have listitem with textboxes and 2 iagebutton, how i can bind listeners to my buttons without writing new custom adapter by null(i hope override just simplecursoradapter).
Sorry for my hard english, and i hope, that you give me clear and simple for understanding examples.
public class MainActivity extends FragmentActivity implements LoaderCallbacks<Cursor> {
ListView lvForms;
dbForm table_form;
SimpleCursorAdapter scAdapter;
/**
* Called when the activity is first created.
*/
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
table_form=new dbForm(this);
table_form.open();
String[] from = new String[]{DBHelper.FORM_NAME, DBHelper.FORM_TITLE};
int[] to = new int[]{R.id.tvFormName, R.id.tvFormTitle};
scAdapter = new SimpleCursorAdapter(this, R.layout.listform_item, null, from, to, 0);
lvForms = (ListView) findViewById(R.id.lvForms);
lvForms.setAdapter(scAdapter);
registerForContextMenu(lvForms);
getSupportLoaderManager().initLoader(0, null, this);
}
// обработка нажатия кнопки
public void onButtonClick(View view) {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
}
protected void onDestroy() {
super.onDestroy();
table_form.close();
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle bndl) {
return new MyCursorLoader(this, table_form);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
scAdapter.swapCursor(cursor);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
}
static class MyCursorLoader extends CursorLoader {
dbForm table_form;
public MyCursorLoader(Context context, dbForm table_form) {
super(context);
this.table_form = table_form;
}
#Override
public Cursor loadInBackground() {
Cursor cursor = table_form.getAllData();
return cursor;
}
}
}
UPD: i write custom class
class MySimpleCursorAdapter extends SimpleCursorAdapter {
public MySimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView != null) {
return convertView;
}
return LayoutInflater.from(context).inflate(R.layout.listform_item);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
String name = cursor.getString(cursor.getColumnIndex(DBHelper.FORM_NAME));
TextView text = (TextView) findViewById(R.id.tvFormName);
text.setText(name);
Button yourButton = (Button) findViewById(R.id.ibtnDelete);
yourButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
}
}
but have error on return LayoutInflater.from(context).inflate(R.layout.listform_item); and can you tell me how now use listener for button(for delete item, for example)? how get number of item where we click on button?
Don`t use getView in overriding the simple cursor adapter and other cursor adapters. You must override the newView and bindView methods.
Here is my working code
public View newView(Context _context, Cursor _cursor, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) _context.getSystemService(_context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.listform_item, parent, false);
return view;
}
#Override
public void bindView(View view, Context Context, Cursor cursor) {
String name = cursor.getString(cursor.getColumnIndex(DBHelper.FORM_NAME));
String title = cursor.getString(cursor.getColumnIndex(DBHelper.FORM_TITLE));
TextView formname = (TextView) view.findViewById(R.id.tvFormName);
formname.setText(name);
TextView formtitle = (TextView) view.findViewById(R.id.tvFormTitle);
formtitle.setText(title);
ImageButton yourButton = (ImageButton) view.findViewById(R.id.ibtnDelete);
yourButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (view != null) {
Object obj = view.getTag();
//if(obj != null && obj instanceof Integer) {
dbForm form = new dbForm(context);
form.open();
String st = obj.toString();
form.deleteForm(Long.valueOf(st).longValue());
Toast.makeText(context, "Delete row with id = " + st, Toast.LENGTH_LONG).show();
}
}
});
Object obj = cursor.getString(cursor.getColumnIndex(DBHelper.FORM_ID));
yourButton.setTag(obj);
}
You have to subclass SimpleCursorAdapter.
Override two methods getView and bindView:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView != null) {
return convertView;
}
return LayoutInflater.from(context).inflate( R.layout.listform_item);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
String name = cursor.getString(cursor.getColumnIndex(DBHelper.FORM_NAME));
TextView text = (TextView) viewfindViewById(R.id.tvFormName);
text.setText(name );
Button yourButton = (Button) viewfindViewById(R.id.magic_button);
yourButton.setOnClickListener(new View.OnClickListener(){ //implement listener here});
}
I'm in some trouble with custom cursorAdapter and AsyncTask. I wanted to setup listView and adapter first and after that in asyctask to query data from database. But for a first time cursor in adapter is null and it throws an a exception. How can be handled this such on situation in my custom cursor adapter? Relocation of setAdapter to onPostExecute didn't helped also. Any suggestions will be also great.
Main activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ConversationsListCursorAdapter conversationsListCursorAdapter = new ConversationsListCursorAdapter(context, R.layout.conversations_list_item, null, 0);
conversationsListView = (ListView) findViewById(android.R.id.list);
conversationsListView.setAdapter(conversationsListCursorAdapter);
}
#Override
protected void onResume() {
super.onResume();
new GetConversationsTask().execute((Object[]) null);
}
#Override
protected void onStop() {
Cursor cursor = conversationsListCursorAdapter.getCursor();
if (cursor != null) {
cursor.close();
}
conversationsListCursorAdapter.changeCursor(null);
super.onStop();
}
private class GetConversationsTask extends AsyncTask<Object, Object, Cursor> {
#SuppressLint("NewApi")
#Override
protected Cursor doInBackground(Object... params) {
Uri uri = ClouContentProvider.CONVERSATIONS_CONTENT_URI;
Cursor cursor = null;
if (android.os.Build.VERSION.SDK_INT < 11) {
cursor = getContentResolver().query(uri, null, null, null, null);
} else {
CursorLoader cursorLoader = new CursorLoader(context, uri, null, null, null, null);
cursor = cursorLoader.loadInBackground();
}
return cursor;
}
#Override
protected void onPostExecute(Cursor cursor) {
conversationsListCursorAdapter.changeCursor(cursor);
cursor.close();
}
}
Cursor adapter:
public class ConversationsListCursorAdapter extends CursorAdapter {
private final Cursor mCursor;
private final Context mContext;
private final int mLayout;
private final int mSnippetIndex;
private final int mDateIndex;
private final int mMessageCount;
private final int mRead;
private final LayoutInflater mLayoutInflater;
//private static final String TAG = ConversationsListCursorAdapter.class.getSimpleName();
static class ViewHolder {
TextView tvBody;
TextView tvPerson;
TextView tvCount;
TextView tvDate;
QuickContactBadge ivPhoto;
View vRead;
}
public ConversationsListCursorAdapter(Context context, int layout, Cursor cursor, int flags) {
super(context, cursor, flags);
this.mContext = context;
this.mLayout = layout;
this.mCursor = cursor;
this.mSnippetIndex = mCursor.getColumnIndex(ConversationsProviderMetaData.ConversationsTableMetaData.SNIPPET);
this.mDateIndex = mCursor.getColumnIndex(ConversationsProviderMetaData.ConversationsTableMetaData.DATE);
this.mMessageCount = mCursor.getColumnIndex(ConversationsProviderMetaData.ConversationsTableMetaData.MESSAGE_COUNT);
this.mRead = mCursor.getColumnIndex(ConversationsProviderMetaData.ConversationsTableMetaData.READ);
this.mLayoutInflater = LayoutInflater.from(mContext);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View rowView = mLayoutInflater.inflate(mLayout, parent, false);
ViewHolder holder = new ViewHolder();
holder.tvBody = (TextView) rowView.findViewById(R.id.body);
holder.tvPerson = (TextView) rowView.findViewById(R.id.addr);
holder.tvCount = (TextView) rowView.findViewById(R.id.count);
holder.tvDate = (TextView) rowView.findViewById(R.id.date);
holder.ivPhoto = (QuickContactBadge) rowView.findViewById(R.id.photo);
holder.vRead = (View) rowView.findViewById(R.id.read);
rowView.setTag(holder);
return rowView;
}
#Override
public void bindView(View v, Context context, Cursor cursor) {
ViewHolder holder = (ViewHolder) v.getTag();
String cBody = cursor.getString(mSnippetIndex);
Integer cCount = cursor.getInt(mMessageCount);
Long cDate = cursor.getLong(mDateIndex);
Integer cRead = cursor.getInt(mRead);
holder.tvBody.setText(cBody);
if (cCount < 0) {
holder.tvCount.setText("");
} else {
holder.tvCount.setText("(" + cCount + ")");
}
if (cRead == 0) {
holder.vRead.setVisibility(View.VISIBLE);
} else {
holder.vRead.setVisibility(View.INVISIBLE);
}
holder.tvDate.setText(ClouUtils.getDate(context, cDate));
holder.tvPerson.setText(cursor.getString(mCursor.getColumnIndex(ConversationsProviderMetaData.ConversationsTableMetaData.CANONICAL)));
holder.ivPhoto.setImageResource(R.drawable.ic_contact_picture);
holder.ivPhoto.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(Cursor cursor) {
// First check if it's null
if(cursor !=null){
// use swap to get the old cursor and close it
Cursor oldC = conversationsListCursorAdapter.swapCursor(cursor);
if(oldC != null){
oldC.close();
}
// DO NOT CLOSE THE NEW CURSOR
// this one you must close whenever the list goes onPause(); but not before
}
}