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?
Related
i want to call stespRecord constructor in stepsDone where should i place the constructor call like StepsRecord rec = new StepsRecord(this);
public class stepsDone extends AppCompatDialogFragment {
public Padomet data;
public StepsRecord rec;
private static final String TAG = "stepsDone";
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.activity_steps_done, null);
rec= new StepsRecord(this);
builder.setView(view)
.setNegativeButton("Do more", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.setPositiveButton("Add to the List", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
float g =data.get();
int d = data.getc();
Log.d(TAG, "HELLLOOOO1111"+g+" uuuuuuuuuuuuuuu "+d);
AddData(g,d);
}
});
ImageView imageView = view.findViewById(R.id.imageView);
Glide.with(this).load(R.drawable.tick2).into(imageView);
return builder.create();
}
public void AddData(float arg1,int arg2) {
rec.addData(arg1, arg2);
}
}
this is the class whose constructor i want to call
public class StepsRecord extends SQLiteOpenHelper {
private static final String TABLE_NAME = "PreviousRecord";
private static final String COL1 = "Goal";
private static final String COL2= "stepsTaken";
public StepsRecord(Context context) {
super(context, TABLE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + "("+ COL1 + " TEXT,"
+ COL2 + " TEXT" + ")";
db.execSQL(createTable);
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
db.execSQL(String.format("DROP IF TABLE EXISTS %s", TABLE_NAME));
onCreate(db);
}
public void addData(float goal, int steps) {
SQLiteDatabase db = this.getWritableDatabase();
String gooals = String.valueOf(goal);
String stepstaken = String.valueOf(steps);
ContentValues contentValues = new ContentValues();
//contentValues.put(COL1, strDate);
contentValues.put(COL1, gooals);
contentValues.put(COL2, stepstaken);
db.insert(TABLE_NAME, null, contentValues);
}
public Cursor getData(){
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM " + TABLE_NAME;
Cursor data = db.rawQuery(query, null);
return data;
}
}
Your help would be appreciated... i have searched on this a lot but have not found any solution may be this is not possible or may be its possible .. if this is possible then please let me know or any other solution of doing.
Now the constructor of StepsRecord needs a context as a parameter, and you are passing this which is referring to your stepsDone object which is a child of Fragment.
Now Fragment class doesn't extend Context, but the Activity class does.
Keeping that in mind you can override onAttach() method in your stepsDone class and you will get a reference to the activity associated with your stepsDone class:
public class stepsDone extends AppCompatDialogFragment {
public Padomet data;
public StepsRecord rec;
private static final String TAG = "stepsDone";
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
.......
.......
}
//here override the onAttach() and initialize the StepsRecord
#Override
public void onAttach(Context context){
super.onAttach(context);
//initialize here
rec= new StepsRecord(context);
}
.........
.........
}
I have a problem with recycler, the problem is: I have AsyncTask which query data from my db, and then updating recycler by CursorLoader, but adapter doesn't fill recycler, Logs says that the data from db is successfully reading and then Adapter constructor successfully takes ArrayList with data, but that's all, logs says that adapter's methods doesn't call.
MainActivity :
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
private SQLiteDatabase db;
private SimpleCursorLoader loader;
private MySimpleAdapter adapter;
private RecyclerView recycler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recycler = (RecyclerView) findViewById(R.id.recycler);
new SimpleTask(SimpleTask.OPEN, null).execute();
}
private class SimpleTask extends AsyncTask<Void, Void, Void> {
public static final int INSERT = 0;
public static final int DELETE = 1;
public static final int OPEN = 2;
private int task;
private String name;
public SimpleTask(int task, String name) {
this.task = task;
this.name = name;
}
#Override
protected Void doInBackground(Void... params) {
switch (task) {
case INSERT :
ContentValues values = new ContentValues();
values.put(SimpleHelper.KEY_NAME, name);
db.insert(SimpleHelper.TABLE_NAME, null, values);
break;
case DELETE :
db.delete(SimpleHelper.TABLE_NAME, SimpleHelper.KEY_NAME + " = ? ", new String[]{name});
break;
case OPEN :
if (db == null) {
try {
db = new SimpleHelper(MainActivity.this).getWritableDatabase();
} catch (SQLiteException e) {
e.printStackTrace();
}
}
break;
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
if (loader == null) {
loader = new SimpleCursorLoader(MainActivity.this, db);
loader.setQueryParams(SimpleHelper.TABLE_NAME, new String[]{SimpleHelper.KEY_NAME},
null, null);
getSupportLoaderManager().initLoader(0, null, MainActivity.this);
}
getSupportLoaderManager().getLoader(0).forceLoad();
}
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return loader;
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
Log.i("MyLog", "onLoadFinished cursor size is " + data.getCount());
List<String> items = new ArrayList<>();
data.moveToFirst();
do {
items.add(data.getString(0));
Log.i("MyLog", data.getString(0));
} while (data.moveToNext());
Log.i("MyLog", "onLoadFinished items size is " + items.size());
if (adapter == null) {
adapter = new MySimpleAdapter(items);
recycler.setAdapter(adapter);
} else {
adapter.updateAdapter(items);
}
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
}
private class MySimpleAdapter extends RecyclerView.Adapter<MySimpleAdapter.MyHolder> {
private List<String> items;
public MySimpleAdapter(List<String> items) {
Log.i("MyLog", "Constructor called with items size " + items.size());
this.items = items;
}
public class MyHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView tvText;
public MyHolder(View itemView) {
super(itemView);
tvText = (TextView) itemView.findViewById(android.R.id.text1);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
new SimpleTask(SimpleTask.DELETE, tvText.getText().toString());
}
}
public void updateAdapter(List<String> items) {
this.items = items;
notifyDataSetChanged();
}
#Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.i("MyLog", "onCreateViewHolder");
View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, null, false);
return new MyHolder(view);
}
#Override
public void onBindViewHolder(MyHolder holder, int position) {
holder.tvText.setText(items.get(position));
Log.i("MyLog", "onBindViewHolder setText : " + items.get(position));
}
#Override
public int getItemCount() {
Log.d("MyLog", "getItemCount called with size : " + items.size());
return items.size();
}
}
SimpleCursorLoader :
public class SimpleCursorLoader extends CursorLoader {
private SQLiteDatabase db;
private String tableName;
private String[] columns;
public SimpleCursorLoader(Context context, SQLiteDatabase db) {
super(context);
this.db = db;
}
public void setQueryParams(String tableName, String[] columns, String selection, String[] selectionArgs) {
this.tableName = tableName;
this.columns = columns;
setSelection(selection);
setSelectionArgs(selectionArgs);
}
#Override
public Cursor loadInBackground() {
Cursor cursor = db.query(tableName, columns, getSelection(), getSelectionArgs(),
null, null, null);
return cursor;
}
DBHelper :
public class SimpleHelper extends SQLiteOpenHelper{
public static final String TABLE_NAME = "users";
public static final String KEY_NAME = "name";
public static final String KEY_ID = "_id";
private static final int DB_VERSION = 1;
private static final String DB_NAME = "SimpleDB";
public SimpleHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + TABLE_NAME + "("
+ KEY_ID + " integer primary key autoincrement, "
+ KEY_NAME + " text)");
for (int i = 0; i < 5; i ++) {
ContentValues values = new ContentValues();
values.put(KEY_NAME, "name" + i+1);
db.insert(TABLE_NAME, null, values);
Log.i("MyLog", "inserted");
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
activity_main.xml :
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Use this.
recycler.setLayoutManager(new LinearLayoutManager(this));
recycler.setHasFixedSize(true);
recycler.setNestedScrollingEnabled(false);
The user at the moment clicks on a row which contains data and a Dialog with text fields is displayed.
I want the user to update the strings by using this Dialog.
How can I do this?
I have an update method already in my Database Class, but I'm not sure how to implement the update in the Dialog
Database Class
package ie.example.artur.projectrepeat;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
/**
* Created by family on 06/07/2016.
*/
public class DatabaseClass extends SQLiteOpenHelper {
public static final String DATABASE_Name = "Product.db2";
public static final String Table_Name = "product_table2";
public static final String COL_1 = "ID";
public static final String COL_2 = "Name";
public static final String COL_3 = "Quantity";
public static final String COL_4 = "Category";
public static final String COL_5 = "Importance";
Context myContext;
public DatabaseClass(Context context) {
super(context, DATABASE_Name, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + Table_Name + " (ID INTEGER PRIMARY KEY AUTOINCREMENT,NAME TEXT,Quantity TEXT,Category INTEGER,Importance TEXT);");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("Drop Table If Exists" + Table_Name);
onCreate(db);
}
public boolean insertData(String name, String quantity, String category,String importance) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL_2, name);
contentValues.put(COL_3, quantity);
contentValues.put(COL_4, category);
contentValues.put(COL_5, importance);
long result = db.insert(Table_Name, null, contentValues);
if (result == -1)
return false;
else
return true;
}
public Cursor getAllData() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("select * from " + Table_Name, null);
return res;
}
public boolean updateData(String id,String name,String quantity,String category,String importance ) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL_1, id);
contentValues.put(COL_2, name);
contentValues.put(COL_3, quantity);
contentValues.put(COL_4, category);
contentValues.put(COL_5, importance);
db.update(Table_Name,contentValues,"id =?",new String[]{id});
return true;
}
/* public Cursor getCursor(){
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setR
}
*/
public Integer DeleteData (String id) {
SQLiteDatabase db = this.getWritableDatabase();
return db.delete(Table_Name,"ID = ?",new String[]{id});
}
public static void DeleteInformation(String item_name, SQLiteDatabase sqLiteDatabase){
String selection = COL_1+" LIKE ?";
String [] selection_args = {item_name};
sqLiteDatabase.delete(Table_Name,selection,selection_args);
}
public Cursor getInformation(SQLiteDatabase sqLiteDatabase)
{
Cursor cursor;
String [] Projections = {COL_1,COL_2,COL_4};
cursor = sqLiteDatabase.query(Table_Name,Projections,null,null,null,null,null);
return cursor;
}
public Cursor getItem(String item_name ,SQLiteDatabase sqLiteDatabase){
String [] Projections = {COL_1,COL_2,COL_3,COL_4,COL_5};
String selection = COL_1+" LIKE ?";
String [] selection_args = {item_name};
Cursor cursor = sqLiteDatabase.query(Table_Name,Projections,selection,selection_args,null,null,null);
return cursor;
}
}
EditActivity
package ie.example.artur.projectrepeat;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class Edit_Activity extends AppCompatActivity implements AdapterView.OnItemClickListener {
ListView listView;
SQLiteDatabase sqLiteDatabase;
DatabaseClass database;
Cursor cursor;
ListDataAdapter listDataAdapter;
Dialog d;
EditText editText_name,editText_Quantity,editText_Category,editTextId,editText_Number;
Button updateBtn;
EditText nameEditText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.data_list_layout);
listView = (ListView) findViewById(R.id.list_view);
listDataAdapter = new ListDataAdapter(getApplicationContext(), R.layout.row_layout);
listView.setAdapter(listDataAdapter);
listView.setOnItemClickListener(this);
database = new DatabaseClass(getApplicationContext());
editText_name = (EditText) findViewById(R.id.editText_name);
editText_Quantity = (EditText) findViewById(R.id.editText_Quantity);
editText_Category = (EditText) findViewById(R.id.editText_Category);
editText_Number = (EditText)findViewById(R.id.editText_Number);
editTextId = (EditText) findViewById(R.id.editText_id);
sqLiteDatabase = database.getReadableDatabase();
Cursor cursor=database.getInformation(sqLiteDatabase);
if (cursor.moveToFirst()) {
do {
String id, product_name, category;
id = cursor.getString(0);
product_name = cursor.getString(1);
category = cursor.getString(2);
DataProvider dataProvider = new DataProvider(id, product_name, category);
listDataAdapter.add(dataProvider);
} while (cursor.moveToNext()
);
}
}
public void loginMethod() {
// Create an instance of the dialog fragment and show it
MyDialog dialog = new MyDialog();
dialog.show(getFragmentManager(),"my_dialog");
}
/*
private void showDialog(){
Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.input);
dialog.setTitle("Here Goes the Title");
Button updateBtn = (Button) d.findViewById(R.id.updateBtn);
dialog.show();
}
*/
#Override
public void onItemClick(AdapterView<?> parent, View view, int position , long id) {
TextView tv = (TextView) view.findViewById(R.id.product_id);
sqLiteDatabase = database.getReadableDatabase();
loginMethod();
/*
listView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// custom dialog
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.input);
dialog.setTitle("Title...");
final EditText nameEditText = (EditText) d.findViewById(R.id.product_name);
Button updateBtn = (Button) d.findViewById(R.id.updateBtn);
/* if (position == -1) {
updateBtn.setEnabled(false);
} else
updateBtn.setEnabled(true);
updateBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
dialog.show();
}
});
*/
/*private void displayInputDialog(final int pos) {
d = new Dialog(this);
d.setTitle("List View");
d.setContentView(R.layout.input);
final EditText nameEditText = (EditText) d.findViewById(R.id.product_name);
Button updateBtn = (Button) d.findViewById(R.id.updateBtn);
if (pos == -1) {
updateBtn.setEnabled(false);
} else
updateBtn.setEnabled(true);
updateBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});*
}*/
}
}
MyDialog Class
package ie.example.artur.projectrepeat;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.graphics.drawable.LayerDrawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
/**
* Created by family on 12/08/2016.
*/
public class MyDialog extends DialogFragment{
LayoutInflater inflater;
View v;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
inflater = getActivity().getLayoutInflater();
v= inflater.inflate(R.layout.input,null);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(v).setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
return builder.create();
}
}
Here is a neat way to handle custom dialog class!
You can make MyDialog class to contain Builder class so that it handles buttonOnClick methods and text data.
my_dialog_layout.xml should contains 4 editTexts(name, category, quantity, importance) and 3 buttons(update, cancel, ok), as it is shown in your second picture. I won't post the xml code since it's not the critical part.
So in OnItemClickListener of the listView in EditActivity, you can
build the dialog
set default text on edit texts
set onClickListener for buttons
MyDialog class
public class MyDialog extends DialogFragment {
public static final String SimpleName = MyDialog.class.getSimpleName();
private EditText name,category, quantity, importance;
private Button update, positive, negative;
private Builder builder;
private static MyDialog instance = new MyDialog();
public static MyDialog getInstance(){
return instance;
}
#Override
public void onCreate(Bundle savedInstanceState) {
this.setCancelable(true);
if (savedInstanceState != null) {
if (builder != null) {
builder = savedInstanceState.getParcelable(Builder.class.getSimpleName());
}
}
setRetainInstance(true);
super.onCreate(savedInstanceState);
}
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
// make the dialog's default background transparent so that you can customize the window
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.my_dialog_layout, container, false);
}
#Override
public void onViewCreated(View view, #Nullable final Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initViews(view);
if (builder != null) {
if (builder.getTextName() != null) {
name.setText(builder.getTextName());
}
if (builder.getTextCategory() != null) {
category.setText(builder.getTextCategory());
}
if (builder.getTextQuantity() != null) {
quantity.setText(builder.getTextQuantity());
}
if (builder.getTextImportance() != null) {
importance.setText(builder.getTextImportance());
}
update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
builder.getOnUpdateClicked().OnClick(view, getDialog());
}
});
positive.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
builder.getOnPositiveClicked().OnClick(view, getDialog());
}
});
negative.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
builder.getOnNegativeClicked().OnClick(view, getDialog());
}
});
}
}
private void initViews(View view) {
name = (EditText) view.findViewById(R.id.editText_name);
category = (EditText) view.findViewById(R.id. editText_category);
quantity = (EditText) view.findViewById(R.id. editText_quantity);
importance = (EditText) view.findViewById(R.id.editText_importance);
update = (Button) view.findViewById(R.id.update);
positive = (Button) view.findViewById(R.id.positive);
negative = (Button) view.findViewById(R.id.negative);
}
private Dialog show(Activity activity, Builder builder) {
this.builder = builder;
if (!isAdded()){
show(((AppCompatActivity) activity).getSupportFragmentManager(), SimpleName);
}
return getDialog();
}
public static class Builder implements Parcelable {
private OnPositiveClicked onPositiveClicked;
private OnNegativeClicked onNegativeClicked;
private OnUpdateClicked onUpdateClicked;
private textName;
private textCategory;
private textQuantity;
private textImportance;
private Context context;
protected Builder(Parcel in) {
textName = in.readString();
textCategory = in.readString();
textQuantity = in.readString();
textImportance = in.readString();
}
public static final Creator<Builder> CREATOR = new Creator<Builder>() {
#Override
public Builder createFromParcel(Parcel in) {
return new Builder(in);
}
#Override
public Builder[] newArray(int size) {
return new Builder[size];
}
};
public Context getContext() {
return context;
}
public Builder setActivity(Context context) {
this.context = context;
return this;
}
public Builder(Context context) {
this.context = context;
}
public Builder setTextName(String textName) {
this.textName = textName;
return this;
}
public String getTextName() {
return textName;
}
public Builder setTextCategory(String textCategory) {
this.textCategory = textCategory;
return this;
}
public String getTextCategory() {
return textCategory;
}
public Builder setTextQuantity(String textQuantity) {
this.textQuantity = textQuantity;
return this;
}
public String getTextQuantity() {
return textQuantity;
}
public Builder setTextImportance(String textImportance) {
this.textImportance = textImportance;
return this;
}
public String getTextImportance() {
return textImportance;
}
public OnPositiveClicked getOnPositiveClicked() {
return onPositiveClicked;
}
public Builder setOnPositiveClicked(OnPositiveClicked onPositiveClicked) {
this.onPositiveClicked = onPositiveClicked;
return this;
}
public OnNegativeClicked getOnNegativeClicked() {
return onNegativeClicked;
}
public Builder setOnNegativeClicked(OnNegativeClicked onNegativeClicked) {
this.onNegativeClicked = onNegativeClicked;
return this;
}
public OnUpdateClicked getOnUpdateClicked() {
return onUpdateClicked;
}
public Builder setOnUpdateClicked(OnUpdateClicked onUpdateClicked) {
this.onUpdateClicked = onUpdateClicked;
return this;
}
public Builder build() {
return this;
}
public Dialog show() {
return getInstance().show(((Activity) context), this);
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(textName);
parcel.writeString(textCategory);
parcel.writeString(textQuantity);
parcel.writeString(textImportance);
}
}
public interface OnPositiveClicked {
void OnClick(View view, Dialog dialog);
}
public interface OnNegativeClicked {
void OnClick(View view, Dialog dialog);
}
}
EditActivity
build and show MyDialog in a listview OnItemClickListner.
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
MyDialog.Builder dialog=null;
// TODO get the strings from database at the position i
String name =
String category =
String quantity =
String importance =
dialog.setTextName(name)
.setTextCategory(category)
.setTextQuantity(quantity)
.setTextImportance(importance)
.setOnPositiveClicked(new MyDialog.OnPositiveClicked() {
#Override
public void OnClick(View view, Dialog dialog) {
}
})
.setOnNegativeClicked(new MyDialog.OnNegativeClicked() {
#Override
public void OnClick(View view, Dialog dialog) {
}
})
.setOnUpdateClicked(new MyDialog.OnUpdateClicked() {
#Override
public void OnClick(View view, Dialog dialog) {
// TODO update database here
}
})
.build();
dialog.show();
}
});
Hope it helps. Let me know if there is a mistake or a better way.
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));
}
});
I am trying to refresh my view when an item in the list is delete. I am currently trying to refresh/reload the view in the onPostExecute method of AsyncTask. So far nothing I have tried has worked. This would seem like an easy task to complete. My custom adapter extends BaseAdapter. I am hoping there is something simple I am missing. Can anyone shed an light??
Cheers.
public class ItemListActivity extends OrmLiteBaseListActivity<DatabaseHelper> {
private final String TAG = getClass().getSimpleName();
private DatabaseHelper dbHelper;
private ListView itemListView;
private ItemListAdapter listAdapter;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.itemslistactivity);
registerForContextMenu(getListView());
itemListView = getListView();
itemListView.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.listview_context_menu, menu);
}
});
listAdapter = new ItemListAdapter(getApplicationContext(), new ArrayList<Item>());
itemListView.setAdapter(listAdapter);
dbHelper = getHelper();
new SelectDataTask().execute(dbHelper);
}
public void add_OnClick(View v) {
Intent intent = new Intent();
intent.setClass(this, AddItemActivity.class);
startActivity(intent);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
Item b = (Item) listAdapter.getItem(info.position);
try {
switch (item.getItemId()) {
case R.id.remove_item:
dbHelper.getItemDao().deleteById(new Integer(b.id));
listAdapter.notifyDataSetChanged();
return true;
}
} catch (SQLException e) {
//FIXME
e.printStackTrace();
Log.e(TAG, e.getMessage());
}
return false;
}
private class SelectDataTask extends AsyncTask<DatabaseHelper, Void, List<Item>> {
private final ProgressDialog dialog = new ProgressDialog(
ItemListActivity.this);
// can use UI thread here
protected void onPreExecute() {
this.dialog.setMessage("Retreiving item data...");
this.dialog.show();
}
#Override
protected List<Item> doInBackground(DatabaseHelper... params) {
List<Item> l = null;
try {
Dao<Item, Integer> dao = params[0].getItemDao();
l = dao.queryForAll();
} catch (SQLException e) {
//TODO -- cleanup
e.printStackTrace();
Log.e(TAG, e.getMessage());
}
return l;
}
// can use UI thread here
#Override
protected void onPostExecute(List<Item> b) {
listAdapter = new MyListAdapter(getApplicationContext(), b);
itemListView.setAdapter(listAdapter);
//TODO -- none of this works
itemListView.invalidateViews();
listAdapter.notifyDataSetChanged();
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
}
}
Check my solution (group CRUD):
public class GroupsPreferenceActivity extends BaseAppActivity {
private DatabaseHelper dbHelper;
private ListView listView;
private GroupAdapter groupAdapter;
private DatabaseModel groupModel;
private OnDeleteListener onDeleteListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.group_preference_layout);
setDbHelper(new DatabaseHelper(getApplicationContext()));
setGroupModel(new DatabaseModel(getDbHelper(), GroupData.class));
setListView((ListView) findViewById(R.id.lv_group));
setGroupAdapter(new GroupAdapter(GroupsPreferenceActivity.this));
getListView().setAdapter(getGroupAdapter());
setOnDeleteListener(new OnDeleteListener() {
#Override
public void onClick(GroupData group) {
removeGroup(group);
}
});
getListView().setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View parent,
int position, long id) {
addGroup(getGroupAdapter().getItem(position));
}
});
getGroupAdapter().setOnDeleteListener(getOnDeleteListener());
doLoadGroups();
}
private void doLoadGroups() {
getGroupAdapter().clear();
List<?> items = getGroupModel().getAll();
for (Object group : items) {
getGroupAdapter().add((GroupData) group);
}
getGroupAdapter().notifyDataSetChanged();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getSupportMenuInflater().inflate(R.menu.groups_preference_menu, menu);
return true;
}
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
super.onMenuItemSelected(featureId, item);
switch (item.getItemId()) {
case R.id.option_item_add_group:
addGroup();
break;
default:
break;
}
return true;
}
private void addGroup() {
addGroup(null);
}
private void addGroup(final GroupData groupData) {
LayoutInflater factory = LayoutInflater
.from(GroupsPreferenceActivity.this);
final View textEntryView = factory.inflate(
R.layout.create_group_dialog_view, null);
final EditText editName = (EditText) textEntryView
.findViewById(R.id.tv_group_name);
String positiveButtonName = getString(R.string.create);
OnClickListener positiveListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
createGroup(editName.getText().toString());
}
};
if (groupData != null) {
positiveButtonName = getString(R.string.update);
editName.setText(groupData.getName());
positiveListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
groupData.setName(editName.getText().toString());
updateGroup(groupData);
}
};
}
AlertDialog.Builder builder = new AlertDialog.Builder(
GroupsPreferenceActivity.this);
String title = getString(R.string.preference_add_group);
builder.setCancelable(true)
.setTitle(title)
.setView(textEntryView)
.setPositiveButton(positiveButtonName, positiveListener)
.setNegativeButton(getString(R.string.cancel),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
final AlertDialog alert = builder.create();
alert.show();
final Button yesButton = alert.getButton(Dialog.BUTTON_POSITIVE);
yesButton.setEnabled(false);
editName.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
yesButton.setEnabled(s.length() > 0);
}
});
}
protected void updateGroup(GroupData groupData) {
getGroupModel().update(groupData);
doLoadGroups();
}
protected void createGroup(String name) {
GroupData groupData = new GroupData();
groupData.setName(name);
getGroupModel().add(groupData);
doLoadGroups();
}
protected void removeGroup(GroupData group) {
getGroupModel().remove(group);
doLoadGroups();
}
public DatabaseHelper getDbHelper() {
return dbHelper;
}
public void setDbHelper(DatabaseHelper dbHelper) {
this.dbHelper = dbHelper;
}
public ListView getListView() {
return listView;
}
public void setListView(ListView listView) {
this.listView = listView;
}
public GroupAdapter getGroupAdapter() {
return groupAdapter;
}
public void setGroupAdapter(GroupAdapter groupAdapter) {
this.groupAdapter = groupAdapter;
}
public DatabaseModel getGroupModel() {
return groupModel;
}
public void setGroupModel(DatabaseModel groupModel) {
this.groupModel = groupModel;
}
public OnDeleteListener getOnDeleteListener() {
return onDeleteListener;
}
public void setOnDeleteListener(OnDeleteListener onDeleteListener) {
this.onDeleteListener = onDeleteListener;
}
}
My DB helpers located: https://github.com/beshkenadze/android-utils/tree/master/src/net/beshkenadze/android/db