I checked a lot of stack overflow question, and none of them helped.
How to refresh my listView after deleting item with onLongClickListener?
As you'll see nor adapter.notifyDataSetChanged(), nor listView.invalidateViews() don't work.
This is implementation with just necessary methods to figure out idea.
public class MainActivity extends AppCompatActivity {
public FloatingActionButton fabAddWord;
public Toolbar toolbar;
public ListView listView;
private RjecnikCursorAdapter adapter;
private RjecnikDB dbRjecnik;
private SQLiteDatabase db;
private Cursor cursor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
fabAddWord = (FloatingActionButton) findViewById(R.id.fabAddWord);
listView = (ListView) findViewById(R.id.listView);
dbRjecnik = new RjecnikDB(this);
db = dbRjecnik.getWritableDatabase();
String query = "SELECT * FROM " + RjecnikDB.TABLE;
cursor = db.rawQuery(query, null);
adapter = new RjecnikCursorAdapter(this, cursor);
listView.setAdapter(adapter);
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
deleteOnLongClick(cursor.getString(cursor.getColumnIndex(RjecnikDB.COLUMN_RIJEC)));
adapter.notifyDataSetChanged();
listView.invalidateViews();
return true;
}
});
}
public void deleteOnLongClick(String rijec) {
SQLiteDatabase db = dbRjecnik.getWritableDatabase();
db.delete(RjecnikDB.TABLE, RjecnikDB.COLUMN_RIJEC + " = ?", new String[] {rijec} );
this.adapter.notifyDataSetChanged();
this.listView.invalidateViews();
db.close();
}
CustomAdapter
public class RjecnikCursorAdapter extends CursorAdapter {
public RjecnikCursorAdapter (Context context, Cursor cursor) {
super(context, cursor, 0);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.item_word, parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView tvSingleLineWord = (TextView) view.findViewById(R.id.tvSingleLineWord);
// Extract properties from cursor
String rijec = cursor.getString(cursor.getColumnIndex(RjecnikDB.COLUMN_RIJEC));
// Populate fields with extracted properties
tvSingleLineWord.setText(rijec);
}
}
The Adapter have a data cache, so data in ListView will not change when data in database changed. You should change the cursor.
#Override
public void changeCursor(Cursor cursor) {
mIndexer.setCursor(cursor);
super.changeCursor(cursor);
}
put code below to your OnItemLongClickListener
cursor = db.rawQuery(query, null);
adapter.changeCurosr(cursor);
You have to use just notifyDataSetChanged() to refresh your listView data, invalidateViews() will only redraw the visible items yet nothing on them has changed (changing font for example).
Note that is recommanded to run your notifyDataSetChanged() on UI thread.
EDIT 2 : you can use BaseAdapter instead of CursorAdapter like below
public class RjecnikCursorAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<String> rjecnikList;
public RjecnikCursorAdapter(Activity activity, List<String> rjecnikList) {
this.activity = activity;
this.rjecnikList = rjecnikList;
}
#Override
public int getCount() {
return rjecnikList.size();
}
#Override
public Object getItem(int location) {
return rjecnikList.get(location);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.item_word, null);
TextView tvSingleLineWord = (TextView) view.findViewById(R.id.tvSingleLineWord);
tvSingleLineWord.setText(String.valueOf(rjecnikList.get(position)));
return convertView;
}
}
And in your activity :
public class MainActivity extends AppCompatActivity {
public FloatingActionButton fabAddWord;
public Toolbar toolbar;
public ListView listView;
public List<String> mylist;
private RjecnikCursorAdapter adapter;
private RjecnikDB dbRjecnik;
private SQLiteDatabase db;
private Cursor cursor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
fabAddWord = (FloatingActionButton) findViewById(R.id.fabAddWord);
listView = (ListView) findViewById(R.id.listView);
dbRjecnik = new RjecnikDB(this);
db = dbRjecnik.getWritableDatabase();
String query = "SELECT * FROM " + RjecnikDB.TABLE;
cursor = db.rawQuery(query, null);
mylist = new ArrayList<>();
if (cursor.moveToFirst()){
do{
//change this with your column data
String data = cursor.getString(cursor.getColumnIndex("data");
mylist.add(data);
}while(cursor.moveToNext());
}
cursor.close();
adapter = new RjecnikCursorAdapter(this, mylist);
listView.setAdapter(adapter);
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
deleteOnLongClick(cursor.getString(cursor.getColumnIndex(RjecnikDB.COLUMN_RIJEC)));
mylist.remove(position);
adapter.notifyDataSetChanged();
listView.invalidateViews();
return true;
}
});
}
public void deleteOnLongClick(String rijec) {
SQLiteDatabase db = dbRjecnik.getWritableDatabase();
db.delete(RjecnikDB.TABLE, RjecnikDB.COLUMN_RIJEC + " = ?", new String[] {rijec} );
this.adapter.notifyDataSetChanged();
this.listView.invalidateViews();
db.close();
}
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
I'm trying to implement search in my app, and activity crashes when I click on search icon. The error is: https://i.imgur.com/CDOE9fT.png
Here is the code of Activity:
public class SearchActivity extends AppCompatActivity implements OnItemClickListener, AdapterView.OnItemClickListener {
DBHelper dbHelper;
SQLiteDatabase database;
ArrayList<Reminder> ReminderList = new ArrayList<>();
ListView listView;
MaterialSearchView searchView;
#Override
protected void onCreate(Bundle savedInstanceState) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Material search");
toolbar.setTitleTextColor(Color.parseColor("#FFFFFF"));
dbHelper = new DBHelper(this);
database = dbHelper.getWritableDatabase();
//listView = (ListView) findViewById(R.id.ListOfReminders);
listView = (ListView)findViewById(R.id.ListOfReminders);
Cursor cursor = database.query(TABLE_REMINDERS, null, null, null, null, null, null);
if (cursor.moveToFirst()) {
do {
int idIndex = cursor.getInt(cursor.getColumnIndex(DBHelper.KEY_ID));
String nameIndex = cursor.getString(cursor.getColumnIndex(KEY_NAME));
String hourIndex = cursor.getString(cursor.getColumnIndex(DBHelper.KEY_HOUR));
String dateIndex = cursor.getString(cursor.getColumnIndex(DBHelper.KEY_DATE));
String name = nameIndex;
String hour = hourIndex;
String date = dateIndex;
ReminderList.add(new Reminder(idIndex, name, hour, date));
ReminderListAdapter2 adapter = new ReminderListAdapter2(this, R.layout.reminder_view2, ReminderList);
adapter.setListener(this);
listView.setAdapter(adapter);
} while (cursor.moveToNext());
} else
Log.d("mLog", "0 rows in db");
searchView = (MaterialSearchView)findViewById(R.id.search_view);
searchView.setOnSearchViewListener(new MaterialSearchView.SearchViewListener() {
#Override
public void onSearchViewShown() {
}
#Override
public void onSearchViewClosed() {
listView = (ListView)findViewById(R.id.ListOfReminders);
ReminderListAdapter2 adapter = new ReminderListAdapter2(SearchActivity.this, android.R.layout.simple_list_item_1,ReminderList);
listView.setAdapter(adapter);
}
}); searchView.setOnQueryTextListener(new MaterialSearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
if(newText != null && !newText.isEmpty()){
ArrayList<Reminder> lstFound = new ArrayList<>();
for(Reminder item:ReminderList){
if(item.getName().contains(newText))
lstFound.add(new Reminder(item.getId(), item.getName(), item.getHour(), item.getDate()));
}
ReminderListAdapter2 adapter = new ReminderListAdapter2(SearchActivity.this,android.R.layout.simple_list_item_1,lstFound);
listView.setAdapter(adapter);
} else {
ReminderListAdapter2 adapter = new ReminderListAdapter2(SearchActivity.this,android.R.layout.simple_list_item_1,ReminderList);
listView.setAdapter(adapter);
}
return true;
}});
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.menu_item,menu);
MenuItem item = menu.findItem(R.id.action_search);
searchView.setMenuItem(item);
return true;
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
#Override
public void OnItemClick(View view, int position, int id, String name, String date, String hour) {
}}
Code of adapter:
public class ReminderListAdapter2 extends ArrayAdapter<Reminder> {
private Context mContext;
private int mResource;
OnItemClickListener listener;
public ReminderListAdapter2(#NonNull Context context, int resource, #NonNull ArrayList<Reminder> objects) {
super(context, resource, objects);
mContext = context;
mResource = resource;
}
public void setListener(OnItemClickListener listener) {
this.listener = listener;
}
#NonNull
#Override
public View getView(final int position, #Nullable View convertView, #NonNull ViewGroup parent) {
final int id = getItem(position).getId();
final String name = getItem(position).getName();
final String hour = getItem(position).getHour();
final String date = getItem(position).getDate();
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(mResource, parent, false);
final TextView resId = convertView.findViewById(R.id.textId);
final TextView resName = convertView.findViewById(R.id.textName);
final TextView resHour = convertView.findViewById(R.id.textHour);
final TextView resDate = convertView.findViewById(R.id.textDate);
resId.setText(String.valueOf(id));
resName.setText(name);
resHour.setText(hour);
resDate.setText(date);
return convertView;
}}
Why object reference is null? Sorry if it is a stupid error, it's first app.
I tried to change lstFound.add(new Reminder(item.getId(), item.getName(), item.getHour(), item.getDate())); with lstFound.add(this);, but it is also null reference.
According to documentation:
To display a more custom view for each item in your dataset, implement a ListAdapter. For example, extend BaseAdapter and create and configure the view for each data item in
If so the first argument of layout inflater method should be layout instead of int
e.g convertView = getLayoutInflater().inflate(R.layout.list_item, container, false);
In your case you are trying to inflate int instead of layout
convertView = inflater.inflate(mResource, parent, false);
Closed.
The error was in ReminderListAdapter2 adapter = new ReminderListAdapter2(SearchActivity.this, android.R.layout.simple_list_item_1,ReminderList);
androidR.layout.simple_list_item_1 need to be changed to R.layout.reminderview2
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.
first of all thank you all for your answers and sorry for the bad English used, have a controller class to populate a listview and an adapter class that extends CursorAdapter, my problem is that when I setAdapter, my class adapter is not running the Newview method BindView certainly not running. Here is the code used for this, they hope can help. regards
public class ListaAdaptador extends CursorAdapter {
public static class ContenedorView
{
TextView nombre;
TextView apellidos;
TextView dni;
TextView telefono;
ImageView img;
}
public ListaAdaptador(Context a, Cursor c)
{
super(a, c);
}
#Override
public int getCount() {
return 0;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.list_item,parent,false);
ContenedorView contenedor = null;
contenedor = new ContenedorView();
contenedor.nombre = (TextView) view.findViewById(R.id.txt_item_nombre);
contenedor.apellidos =(TextView) view.findViewById(R.id.txt_item_apellidos);
contenedor.dni = (TextView) view.findViewById(R.id.txt_item_dni);
contenedor.telefono = (TextView) view.findViewById(R.id.txt_item_telefono);
contenedor.img = (ImageView) view.findViewById(R.id.ImageViewItem);
view.setTag(contenedor);
return view;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
ContenedorView contenedor = (ContenedorView) view.getTag();
contenedor.nombre.setText(cursor.getString(cursor.getColumnIndex("nombre")));
contenedor.apellidos.setText(cursor.getString(cursor.getColumnIndex("apellidos")));
contenedor.dni.setText(cursor.getString(cursor.getColumnIndex("dni")));
contenedor.telefono.setText(cursor.getString(cursor.getColumnIndex("telefono")));
contenedor.img.setImageResource(R.drawable.img_nodisp);
}
}
clase ListaControlador
public class ListadoControlador extends ListActivity {
EditText aproximacion;
ListView lv;
ImageButton buscar;
SQLiteDatabase db;
Cursor cursor;
ListaAdaptador adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listado);
aproximacion = (EditText) findViewById(R.id.EditText01);
buscar =(ImageButton)findViewById(R.id.btnBuscar);
lv=getListView();
prepararBaseDeDatos();
obtenemosValores();
}
public void prepararBaseDeDatos()
{
AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this,"registro",null,1);
db = admin.getWritableDatabase();
}
public void obtenemosValores()
{
cursor = db.rawQuery("select _id,nombre,apellidos,dni,telefono from paciente", null);
adapter = new ListaAdaptador(ListadoControlador.this,cursor);
lv.setAdapter(adapter);
}
Remove the three Override methods getCount(), getItem() and getItemId() from your ListaAdaptador class. You don't need them since you're using a CursorAdapter.
in my Application i have an Activity that has a ListView and a button. i am using loader to automatically loading data to listview from my table in the database.and i am using the button to change the table rows.
i want the loader to automatically load the data from table when a change happens to the table.
right now my code loads the data into listview but it doesn't update it when table changes after that.
here are my classes :
item
public class Item {
public int id;
public String name;
}
MainActivity :
public class MainActivity extends Activity implements
LoaderManager.LoaderCallbacks<List<Item>> {
ItemAdapter adapter;
List<Item> items;
Button button;
TextView tv;
ListView listview;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
button = (Button) findViewById(R.id.button);
listview = (ListView) findViewById(R.id.listview);
items = new ArrayList<Item>();
adapter = new ItemAdapter(this, items);
listview.setAdapter(adapter);
getLoaderManager().initLoader(0, savedInstanceState, this).forceLoad();
}
//button code for changing db
public void change(View view) {
ItemHelper helper = new ItemHelper(this);
Item item = new Item();
item.name = "Samsung P6800";
helper.insert(item);
}
#Override
public Loader<List<Item>> onCreateLoader(int id, Bundle args) {
final ItemHelper helper = new ItemHelper(getApplicationContext());
return new AsyncTaskLoader<List<Item>>(MainActivity.this) {
#Override
public List<Item> loadInBackground() {
return helper.read();
}
};
}
#Override
public void onLoadFinished(Loader<List<Item>> loader, List<Item> data) {
adapter.addAll(data);
adapter.notifyDataSetChanged();
}
#Override
public void onLoaderReset(Loader<List<Item>> loader) {
adapter.clear();
adapter.notifyDataSetChanged();
}
ItemHelper
public class ItemHelper {
public static final String DB_NAME = "Test";
private static Context m_context;
private static SQLiteDatabase m_db;
private static DatabaseHelper m_helper;
String[] columns = { "id", "name" };
public ItemHelper(Context context) {
m_context = context;
m_helper = new DatabaseHelper(m_context, DB_NAME, null, 1);
}
private static class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, DB_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
public void insert(Item item) {
m_db = m_helper.getWritableDatabase();
ContentValues initialValues = new ContentValues();
initialValues.put("name", item.name);
m_db.insert("item", null, initialValues);
m_db.close();
}
public List<Item> read() {
List<Item> items = new ArrayList<Item>();
m_db = m_helper.getReadableDatabase();
Cursor cursor = m_db.query("item", columns, null, null, null, null,
null);
if (cursor.moveToFirst()) {
do {
Item item = new Item();
item.id = cursor.getInt(cursor.getColumnIndexOrThrow("id"));
item.name = cursor.getString(cursor
.getColumnIndexOrThrow("name"));
items.add(item);
} while (cursor.moveToNext());
}
m_db.close();
return items;
}
}
ItemAdapter
public class ItemAdapter extends ArrayAdapter<Item> {
private Context context;
private List<Item> items;
private LayoutInflater vi;
public ItemAdapter(Context context, int resource) {
super(context, resource);
// TODO Auto-generated constructor stub
}
public ItemAdapter(Context context, List<Item> items) {
super(context, 0, items);
this.context = context;
this.items = items;
vi = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
Item item = items.get(position);
if (item != null) {
view = vi.inflate(R.layout.item_info, parent, false); // custom xml
// for
// desired
// view
TextView tv1 = (TextView) view.findViewById(R.id.tvID);
tv1.setText(""+item.id);
TextView tv2 = (TextView) view.findViewById(R.id.tvName);
tv2.setText(item.name);
}
return view;
}
#Override
public Item getItem(int position) {
return items.get(position);
}
}
how can i do it ? ( i don't want to use content providers )
finally i used ContentProviders to solve this issue.
i created a method inside my database helper class that returns a Cursor according to it's parameters,
and used it inside ContentProvider to get Data.
public Cursor getCursor(int status, boolean isAccepted) {
m_db = m_helper.getReadableDatabase();
String sql = "SELECT id as _id , rid , isaccepted , status FROM torder";
Cursor cursor = m_db.rawQuery(sql, null);
return cursor;
}
also in helper when i insert data to db i notify the content provider :
public void notifyProvider(int status) {
ContentValues values = new ContentValues();
values.put("status", status);
Uri uri = m_context.getContentResolver().insert(
OrderProvider.CONTENT_URI, values);
}
public void insert(Order order) {
int flag = (order.isAccepted()) ? 1 : 0;
String[] args = { String.valueOf(order.getId()),
String.valueOf(order.getR_id()), String.valueOf(flag),
String.valueOf(order.getStatus()) };
m_db.execSQL(
"INSERT OR REPLACE INTO torder(id,rid,isaccepted,status) VALUES(?,?,?,?)",
args);
// save to orderdetails
List<OrderDetails> orderDetailsList = order.getOrders();
OrderDetailsHelper helper = OrderDetailsHelper.getInstance(m_context);
helper.open();
helper.insertAll(orderDetailsList);
helper.close();
notifyProvider(1);
}
Change your change method:
public void change(View view) {
ItemHelper helper = new ItemHelper(this);
Item item = new Item();
item.name = "Samsung P6800";
helper.insert(item);
getLoaderManager().restartLoader(0, null, this);
}
Top rows of three buttons shows the top three values of the database but from the next rows again top three values were shown in the three buttons ?
public class ButtonTest extends Activity {
/** Called when the activity is first created. */
NoteHelper helper = null;
Cursor ourCursor = null;
NoteAdapter adapter = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.main);
ListView list = (ListView) findViewById(R.id.list);
helper = new NoteHelper(this);
ourCursor = helper.getAll();
startManagingCursor(ourCursor);
adapter = new NoteAdapter(ourCursor);
list.setAdapter(adapter);
}
catch (Exception e) {
Log.e("ERROR", "ERROR IN CODE :" + e.toString());
e.printStackTrace();
}
}
#Override
public void onDestroy() {
super.onDestroy();
helper.close();
}
class NoteAdapter extends CursorAdapter {
NoteAdapter(Cursor c) {
super(ButtonTest.this, c);
}
#Override
public void bindView(View row, Context ctxt, Cursor c) {
NoteHolder holder = (NoteHolder) row.getTag();
holder.populateFrom(c, helper);
}
#Override
public View newView(Context ctxt, Cursor c, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.row, parent, false);
NoteHolder holder = new NoteHolder(row);
row.setTag(holder);
return (row);
}
}
My NoteHolder Class Is
static class NoteHolder {
private Button b1 = null;
private Button b2 = null;
private Button b3 = null;
NoteHolder(View row) {
b1 = (Button) row.findViewById(R.id.one);
b2 = (Button) row.findViewById(R.id.two);
b3 = (Button) row.findViewById(R.id.three);
}
void populateFrom(Cursor c, NoteHelper helper) {
if (!c.moveToFirst()) return;
b1.setText(helper.getNote(c));
c.moveToNext();
b2.setText(helper.getNote(c));
c.moveToNext();
b3.setText(helper.getNote(c));
}
}
My SQLiteHelper Class is
class NoteHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "note.db";
private static final int SCHEMA_VERSION = 1;
public SQLiteDatabase dbSqlite;
public NoteHelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE Notes (_id INTEGER PRIMARY KEY AUTOINCREMENT,note TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public Cursor getAll() {
return (getReadableDatabase().rawQuery("SELECT _id,note From Notes",
null));
}
public String getNote(Cursor c) {
return(c.getString(1));
}
public Cursor getById(String id) {
return (getReadableDatabase().rawQuery(
"SELECT _id,note From Notes", null));
}
}
}
My main.xml is
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:padding="6dip"
android:background="#1F8B26">
<ListView android:layout_height="wrap_content" android:id="#+id/list"
android:layout_width="fill_parent"></ListView>
First I want to say is that Gridview will be more suitable in your case
second you are getting multiple rows because cursor adapter will create those many view that it has rows and for each row you are again reading rows in populateFrom() method so that your rows are being repeated.
Instead of Cursor adapter use Base adapter
Solution
1) first create arraylist from your cursor
2) after getting arraylist create a object of NoteAdapter which is below
3) set adapter in gridview
private class NoteAdapter extends BaseAdapter implements OnClickListener {
ArrayList<Note> arrNote;
LayoutInflater inflater;
public NoteAdapter(ArrayList<Note> arr) {
this.arrNote = arr;
inflater = ExploreDestination.this.getLayoutInflater();
}
#Override
public int getCount() {
return arrNote.size();
}
#Override
public Object getItem(int index) {
return arrNote.get(index);
}
#Override
public long getItemId(int id) {
return id;
}
#Override
public View getView(int position, View v, ViewGroup arg2) {
v = inflater.inflate(R.layout.Notebutton, null);
v.setTag(arrNote.get(position));
((Button)v).setText(arrNote.get(position).getTitle());
v.setOnClickListener(this);
return v;
}
#Override
public void onClick(View v) {
//do your work
}
}