I have a android list layout. Basically it will list user's info on the screen. Please help me explain how the listView set the data. How the SimpleCursorAdapter links with Loader
Here's code :
public class ChatList extends ListActivity implements LoaderManager.LoaderCallbacks<Cursor>{
private SimpleCursorAdapter adapter;
private final int Adapter_AccountName = 1;
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chatlist);
adapter = new SimpleCursorAdapter(this,
R.layout.main_list_item,
null,
new String[]{DataProvider.COL_NAME, DataProvider.COL_COUNT,DataProvider.PROFILE_COL_LASTMSGAT,DataProvider.PROFILE_COL_IMAGE},
new int[]{R.id.text1, R.id.text2,R.id.text3,R.id.avatar},
0);
adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
#Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
switch(view.getId()) {
// here can add one more line in the main page for each account
case R.id.text2:
int count = cursor.getInt(columnIndex);
if (count > 0) {
((TextView)view).setText(String.format("%d new message%s", count, count==1 ? "" : "s"));
}
return true;
case R.id.text3:
String lastUpdate = cursor.getString(columnIndex);
Date d = DbDatetimeUtility.getDate(cursor.getString(columnIndex));
Date t = DbDatetimeUtility.getCurrentDate();
((TextView)view).setText(DbDatetimeUtility.returnDifferentTime(d,t));
return true;
case R.id.avatar:
byte[] imageByte = cursor.getBlob(columnIndex);
((ImageView)view).setImageBitmap(DbBitmapUtility.getResizedBitmap(DbBitmapUtility.getImage(imageByte),125,125));
return true;
}
return false;
}
});
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(false);
//final ListView listView = getListView();
final ListView listView = getListView();
listView.setAdapter(adapter);
getLoaderManager().initLoader(0, null, this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = new Intent(this, ChatActivity.class);
intent.putExtra(Common.PROFILE_ID, String.valueOf(id));
startActivity(intent);
}
//----------------------------------------------------------------------------
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
CursorLoader loader = new CursorLoader(this,
DataProvider.CONTENT_URI_PROFILE,
new String[]{DataProvider.COL_ID, DataProvider.COL_NAME, DataProvider.COL_COUNT,DataProvider.PROFILE_COL_LASTMSGAT,DataProvider.PROFILE_COL_IMAGE},
null,
null,//new String[]{DataProvider.PROFILE_COL_LASTMSGAT},
DataProvider.PROFILE_COL_LASTMSGAT + " DESC");
return loader;
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}
}
Thanks in advance!
Briefly for now, the main points are:
onCreateLoader gets the data from the SQLite database.
This code adapter = new SimpleCursorAdapter, populates the adapter.
This code listView.setAdapter(adapter); populates the ListView.
There is a nice Stackoverflow answer at Using SimpleCursorAdapter to get Data from Database to ListView
Related
After removing the item from the lvSimple (ListView) I can not update the contents of LisView. The data from the database are removed. Items of ListView too. But i need to "flip through" fragments to see this. It's part of my code.
public class PageFragment extends Fragment {
public boolean onContextItemSelected(MenuItem item) {
if (item.getItemId() == CM_DELETE_ID) {
AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
myDB.deleteRow(acmi.id);
populateListView();
return true;
}
return super.onContextItemSelected(item);
}
public void populateListView() {
String[] fromFieldNames = new String[]{DBAdapter.KEY_DATE, DBAdapter.KEY_AREA, DBAdapter.KEY_PASSENGER};
int[] toViewsID = new int[]{R.id.tvItemDate, R.id.tvItemArea, R.id.tvItemPassenger};
SimpleCursorAdapter myC;
myC = new SimpleCursorAdapter(view.getContext(), R.layout.item, c, fromFieldNames, toViewsID, 0);
myC.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
#Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
if (columnIndex == 1) {
String createDate = cursor.getString(columnIndex);
textView = (TextView) view;
textView.setText(dateFormat(createDate));
return true;
}
return false;
}
});
lvSimple.setAdapter(myC);
myC.notifyDataSetChanged();
lvSimple.invalidateViews();
}
}
I have a Delete button next to each list item in my ListActivity class, and in my delete button i have android:onClick="myClickHandler". Right now, i am working on my code within my myClickHandler function to successfully delete the selected list item. Could someone please give me advice in how i can reference in my code as to which item is being deleted, as well as delete the item upon being clicked? I've provided my ListActivity code.. Thanks for all and any responses!
public class LyricList extends ListActivity {
private static final int ACTIVITY_CREATE=0;
private static final int ACTIVITY_EDIT=1;
private static final int INSERT_ID = Menu.FIRST;
private static final int DELETE_ID = Menu.FIRST + 1;
private LyricsDbAdapter mDbHelper;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lyriclist);
mDbHelper = new LyricsDbAdapter(this);
mDbHelper.open();
fillData();
registerForContextMenu(getListView());
}
private void fillData() {
Cursor lyricsCursor = mDbHelper.fetchAllLyrics();
startManagingCursor(lyricsCursor);
String[] from = new String[]{LyricsDbAdapter.KEY_TITLE};
int[] to = new int[]{R.id.text1};
SimpleCursorAdapter lyrics =
new SimpleCursorAdapter(this, R.layout.lyrics_row, lyricsCursor, from, to);
setListAdapter(lyrics);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, INSERT_ID, 0, R.string.menu_insert);
return true;
}
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch(item.getItemId()) {
case INSERT_ID:
createLyric();
return true;
}
return super.onMenuItemSelected(featureId, item);
}
public void myClickHandler(View v)
{
ListView lvItems = getListView();
for (int i=0; i < lvItems.getChildCount(); i++)
{
//incorrectly implemented...getting errors within this
LinearLayout vwParentRow = (LinearLayout)v.getParent();
Button Delbtn = (Button)vwParentRow.getChildAt(1);
DELETE_ID:
mDbHelper.deleteLyric(lvItems.getChildAt(i));
}
}
private void createLyric() {
Intent i = new Intent(this, NextActivity.class);
startActivityForResult(i, ACTIVITY_CREATE);
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Intent i = new Intent(this, NextActivity.class);
i.putExtra(LyricsDbAdapter.KEY_ROWID, id);
startActivityForResult(i, ACTIVITY_EDIT);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
fillData();
}
}
You need to
Delete it from the DB.
Call requery() on the Cursor.
Call notifyDataSetChanged on the adapter.
Edit: In order to get the ID you should override the bindView function of the adapter, and attach your OnClickListener in there.
How to remove a selected item from ListView using CursorAdapter
Im setting up a main activity with a ListView object, however, the ListView will not respond to touch, onItemClick and onContextItemSelected are not reachable, i have set up setOnItemClickListener and registerForContextMenu, and i dont see my error, here is my code:
public class MainActivity extends Activity implements OnClickListener, OnItemClickListener {
long selectedMovieId;
DbHandler dbhandler;
Movie selectedMovie;
MovieAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn_setting = (Button) findViewById(R.id.page_main_setting);
Button btn_add = (Button) findViewById(R.id.page_main_add);
ListView lv = (ListView) findViewById(R.id.list);
btn_add.setOnClickListener(this);
btn_setting.setOnClickListener(this);
lv.setOnItemClickListener(this);
dbhandler = new DbHandler(this);
registerForContextMenu(lv);
Cursor c = dbhandler.queryAll();
startManagingCursor(c);
adapter = new MovieAdapter(this, c);
lv.setAdapter(adapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_options, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.main_options_exit:
finish();
return true;
case R.id.main_option_delete_all:
dbhandler.deleteAll();
refresh();
return true;
}
return false;
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
// TODO Auto-generated method stub
getMenuInflater().inflate(R.menu.main_context, menu);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
Log.d("context menu", "clicked");
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
selectedMovieId = info.id;
switch (item.getItemId()) {
case R.id.main_context_edit:
Intent intent = new Intent(this, AddEditActivity.class);
intent.putExtra(DbConstants.FROM_CONTEXT, selectedMovie+"");
startActivity(intent);
return true;
case R.id.main_context_delete:
dbhandler.deleteMovie(selectedMovieId);
refresh();
return true;
}
return false;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.page_main_setting:
openOptionsMenu();
break;
case R.id.page_main_add:
DialogInterface.OnClickListener listenerInternet = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(getBaseContext(),
InternetEditActivity.class);
startActivity(intent);
}
};
DialogInterface.OnClickListener listenerManual = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(getBaseContext(),AddEditActivity.class);
intent.putExtra(DbConstants.MANUAL, DbConstants.MANUAL);
startActivity(intent);
}
};
AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle("Please choose an adding method")
.setCancelable(false).setNegativeButton("Cancel", null)
.setNeutralButton("via internet", listenerInternet)
.setPositiveButton("Manual", listenerManual).create();
dialog.show();
break;
}
}
class MovieAdapter extends CursorAdapter /*implements OnTouchListener*/ {
public MovieAdapter(Context context, Cursor c) {
super(context, c);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// inflate the view:
return getLayoutInflater().inflate(R.layout.main_list_layout,
parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
// bind the data
// get the data from the cursor
String subject = cursor.getString(cursor.getColumnIndex(DbConstants.DB_SUBJECT));
String body = cursor.getString(cursor.getColumnIndex(DbConstants.DB_BODY));
String internal_location = cursor.getString(cursor.getColumnIndex(DbConstants.DB_INTERNAL_LOCATION));
int year = cursor.getInt(cursor.getColumnIndex(DbConstants.DB_YEAR));
int status = cursor.getInt(cursor.getColumnIndex(DbConstants.DB_STATUS));
int rating = cursor.getInt(cursor.getColumnIndex(DbConstants.DB_RATING));
TextView subjectText = (TextView) view.findViewById(R.id.list_main_subject);
TextView bodyText = (TextView) view.findViewById(R.id.list_main_body);
TextView yearText = (TextView) view.findViewById(R.id.list_main_year);
TextView statusText = (TextView) view.findViewById(R.id.list_main_status);
ImageView image = (ImageView) view.findViewById(R.id.list_main_imgae);
//RatingBar ratingBar = (RatingBar) view.findViewById(R.id.list_main_ratingBar1);
//ratingBar.setOnTouchListener(this);
subjectText.setText(subject);
bodyText.setText(body);
yearText.setText(String.valueOf(year));
//ratingBar.setRating(rating);
Log.d("status in main", status+"");
Log.d("rating in main", rating+"");
if (status==0){
statusText.setText("watched");
} else if (status==1){
statusText.setText("Not watched");
}
Log.d("ternal loction", internal_location+"!");
if (internal_location!=null){
File imgFile = new File(internal_location);
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
image.setImageBitmap(myBitmap);
}
}
}
/*#Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}*/
} //Movie Adapter close
public void refresh(){
Cursor newCursor = dbhandler.queryAll();
Cursor oldCursor = adapter.getCursor();
adapter.changeCursor(newCursor);
startManagingCursor(newCursor);
stopManagingCursor(oldCursor);
oldCursor.close();
}
#Override
public void onItemClick(AdapterView<?> arg0, View v, int arg2, long id) {
Log.d("list menu", "clicked");
Intent intent = new Intent(this, AddEditActivity.class);
intent.putExtra(DbConstants.FROM_LISTVIEW, id);
startActivity(intent);
}
} //Main Activity close
it has to be somthing to do with the layout of the list, a simple list inserted next to it worked
OnItemClick event is now intercepted by RatingBar.
Add onTouchEvent listener to your RatingBar and return false to say to system that RatingBar does not handle this events.
#Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(MotionEvent event)
return false;
}
Edit: above answer is for subclassing RatingBar.
But you already have onTouchEvent just return false instead of true.
The problem was that there was a Scroll view object in the layout of the adapter, remove it and the problem will be fixed
public class NewFriendsListFragment extends SherlockListFragment implements
LoaderManager.LoaderCallbacks<Cursor> {
int monthchange, daychange;
Dialog dialog;
int pos;
CheckedTextView ctv_name;
private SimpleCursorAdapter mAdapter=null;
private SQLiteCursorLoader loader=null;
String mCurFilter;
private static Handler responseHandler;
boolean loaded=false;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//some more stuff...
setHasOptionsMenu(true);
mAdapter = new FriendListSCA(getSherlockActivity().getApplicationContext(),
R.layout.friend_item, null,null, null, null, null, NAME),
new String[]{NAME,MONTH,UID}, new int[]{R.id.name,R.id.info,R.id.profile_pic});
setListAdapter(mAdapter);
setListShown(false);
registerForContextMenu(getListView());
getLoaderManager().initLoader(0, null, this);
responseHandler = new Handler()
{
//handler code
};
}
public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) {
//loader code
return(loader);
}
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
mAdapter.changeCursor(cursor);
// Showin List
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
}
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.changeCursor(null);
}
#Override
public boolean onContextItemSelected(android.view.MenuItem item) {
AdapterContextMenuInfo info;
try {
info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
} catch (ClassCastException e) {
return false;
}
pos=info.position;
switch (item.getItemId()) {
case R.id.edit_item:
show_dialog();
return true;
}
return(super.onOptionsItemSelected(item));
}
#Override
public void onListItemClick(ListView l, View v, final int position, long id) {
Log.e("onListItemClick","Inside onListItemClick");
ContentValues cv= new ContentValues();
//MORE CODE
loader.update(TABLE_NAME_INCLUDE, cv, _ID+" = ?", new String[]{Integer.toString(position)});
}
private class FriendListSCA extends SimpleCursorAdapter
{
public FriendListSCA(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to,0);
setViewBinder(new FriendsListDataViewBinder());
}
}
public class FriendsListDataViewBinder implements SimpleCursorAdapter.ViewBinder
{
//_ID + "," + UID+","+NAME+","+MONTH+","+DAY+","+WISH
#Override
public boolean setViewValue(View view, Cursor c, int columnIndex)
{
switch (view.getId())
{
case R.id.name:
CheckedTextView ctv= (CheckedTextView)view;
ctv.setText(c.getString(2));
if(c.getInt(5)==0 || c.getInt(4)==-1)
{
ctv.setPaintFlags(ctv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
ctv.setChecked(false);
}
else
{
ctv.setPaintFlags(ctv.getPaintFlags() & (~ Paint.STRIKE_THRU_TEXT_FLAG));
ctv.setChecked(true);
}
return true;
case R.id.info:
if(c.getInt(4)!=-1)
{
((TextView)view).setText(Utility.MONTH_NAME[c.getInt(3)-1] + " " + Integer.toString(c.getInt(4)));
}
else
{
((TextView)view).setText("Tap and hold to manually enter");
}
return true;
case R.id.profile_pic:
if(!loaded)
return true;
((ImageView)view).setImageBitmap(Utility.model.getImage(
Long.toString( c.getLong(1) ), getURL(c.getLong(1)) ));
return true;
}
return false;
}
}
private void show_dialog()
{
//DATE PICKER CODE
okay.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v)
{
ContentValues cv=new ContentValues();
cv.put(MONTH, monthchange);
cv.put(DAY, daychange);
loader.update(TABLE_NAME_INCLUDE, cv, _ID+" = ?" , new String[]{Integer.toString(pos)});
//getLoaderManager().restartLoader(0, null, NewFriendsListFragment.this);
//I tried calling restart loader, but nothing, when I checked
//it turned out the sqlite database wasn't being updated
responseHandler.sendEmptyMessage(1); //just dismisses dialog
}
});
dialog.show();
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Place an action bar item for searching.
MenuItem item = menu.add("Search");
item.setIcon(android.R.drawable.ic_menu_search);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
View searchView = SearchViewCompat.newSearchView(getActivity());
if (searchView != null) {
SearchViewCompat.setOnQueryTextListener(searchView,
new OnQueryTextListenerCompat() {
#Override
public boolean onQueryTextChange(String filtext) {
mCurFilter = !TextUtils.isEmpty(filtext) ? filtext : null;
getLoaderManager().restartLoader(0, null, NewFriendsListFragment.this);
return true;
}
});
item.setActionView(searchView);
}
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
}
}
I'm using a SherlockListFragment from the ActionBarSherlock library to display a list using a CommonsWare Loaderex sqlite cursor loader, and evrything seems to work fine, the names and birthdays and profile pics are all displayed fine, but I can't seem to be able to update any of the data in the table using loader.update(...), nothing happens when I call it.
What's wrong?
You have:
loader.update(TABLE_NAME_INCLUDE, cv, _ID+" = ?", new String[]{Integer.toString(position)});
In all likelihood, that should be:
loader.update(TABLE_NAME_INCLUDE, cv, _ID+" = ?", new String[]{Integer.toString(id)});
(replacing position with id)
I show the data from database like text and image, but my code is not working. I use this tutorial for my project. This my java class:
public class PepakPostView extends ListActivity {
protected TextView postOne;
protected TextView postTwo;
//protected view picture;
protected ListAdapter adapter;
protected int subcatId;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.post);
subcatId = getIntent().getIntExtra("SUBCATEGORY_ID", 0);
SQLiteDatabase db = (new DatabaseHelper(this)).getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT _id, subcatId, postOne, postTwo, picture FROM posts WHERE subcatId = ?",
new String[]{""+subcatId});
SimpleCursorAdapter pepak = new SimpleCursorAdapter(
this,
R.layout.post_list,
cursor,
new String[] {"postOne", "postTwo", "picture"},
new int[] { R.id.postOne, R.id.postTwo, R.id.picture });
pepak.setViewBinder(new MyViewBinder());
}
#Override
public boolean onCreateOptionsMenu(android.view.Menu menu) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu);
MenuInflater blowUp = getMenuInflater();
blowUp.inflate(R.menu.coll_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch(item.getItemId()){
case R.id.about:
Intent i = new Intent("com.pepakbahasajawa.ABOUT");
startActivity(i);
break;
case R.id.exit:
finish();
break;
}
return false;
}
}
and MyViewBinder.java:
public class MyViewBinder implements ViewBinder {
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
int viewId = view.getId();
switch(viewId) {
/*
case R.id.postOne:
TextView postOne = (TextView) view;
postOne.setText(Cursor.getString(columnIndex));
break;
case R.id.postTwo:
TextView postTwo = (TextView) view;
postTwo.setText(Cursor.getString(columnIndex));
break;
*/
case R.id.picture:
ImageView pictureIcon = (ImageView) view;
int picture = cursor.getInt(columnIndex);
switch(picture) {
case 1:
pictureIcon.setImageResource(R.drawable.icon);
break;
case 2:
pictureIcon.setImageResource(R.drawable.home_normal);
break;
}
break;
}
return false;
}
}
How to fix this?
pepak variable is not used in ListView. ListView is empty.
setListAdapter(pepak);//?