Why does it say the constructor is undefined? - android

I am making an android app for my group project and getting the following error:
The constructor GradesDataSource(AddGradesFragment) is undefined
This is the code containing the error:
package com.petroc.nationaldiploma;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import com.actionbarsherlock.app.SherlockFragment;
public class AddGradesFragment extends SherlockFragment {
private GradesDataSource datasource;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
datasource = new GradesDataSource(this);
Spinner spinner;
View view = inflater.inflate(R.layout.fragment_add_grades, container,
false);
spinner = (Spinner) view.findViewById(R.id.spinner);
List<String> list = new ArrayList<String>();
list.add("Pass");
list.add("Merit");
list.add("Distinction");
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(
getActivity(), android.R.layout.simple_spinner_item, list);
dataAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(dataAdapter);
spinner = (Spinner) view.findViewById(R.id.spinner);
spinner.setOnItemSelectedListener(new CustomOnItemSelectedListener());
// EditText editText = (EditText)
// view.findViewById(R.id.editModuleText1);
return view;
}
}
This is the GradesDataSource class:
package com.petroc.nationaldiploma;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
public class GradesDataSource {
// Database fields
private SQLiteDatabase database;
private MySQLiteHelper dbHelper;
private String[] allColumns = { MySQLiteHelper.COLUMN_ID,
MySQLiteHelper.COLUMN_GRADE, MySQLiteHelper.COLUMN_MODULE };
public GradesDataSource(Context context) {
dbHelper = new MySQLiteHelper(context);
}
public void open() throws SQLException {
database = dbHelper.getWritableDatabase();
}
public void close() {
dbHelper.close();
}
public Grade createGrade(String grade, String module) {
ContentValues values = new ContentValues();
values.put(MySQLiteHelper.COLUMN_GRADE, grade);
values.put(MySQLiteHelper.COLUMN_MODULE, module);
long insertId = database.insert(MySQLiteHelper.TABLE_GRADES, null,
values);
Cursor cursor = database.query(MySQLiteHelper.TABLE_GRADES,
allColumns, MySQLiteHelper.COLUMN_ID + " = " + insertId, null,
null, null, null);
cursor.moveToFirst();
Grade newGrade = cursorToGrade(cursor);
cursor.close();
return newGrade;
}
public void deleteGrade(Grade grade) {
long id = grade.getId();
System.out.println("Grade deleted with id: " + id);
database.delete(MySQLiteHelper.TABLE_GRADES, MySQLiteHelper.COLUMN_ID
+ " = " + id, null);
}
public List<Grade> getAllGrades() {
List<Grade> grades = new ArrayList<Grade>();
Cursor cursor = database.query(MySQLiteHelper.TABLE_GRADES,
allColumns, null, null, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Grade grade = cursorToGrade(cursor);
grades.add(grade);
cursor.moveToNext();
}
// Make sure to close the cursor
cursor.close();
return grades;
}
private Grade cursorToGrade(Cursor cursor) {
Grade grade = new Grade();
grade.setId(cursor.getLong(0));
grade.setGrade(cursor.getString(1));
return grade;
}
}
why am I getting this error? I used this tutorial: http://www.vogella.com/articles/AndroidSQLite/article.html
the resulting app worked fine and I am now adding this code to the app for my group project

Change this line:
datasource = new GradesDataSource(this);
to
datasource = new GradesDataSource(getActivity());
You are passing a reference to the Fragment for which there is no constructor. You want to pass in the context of the Host Activity which is obtained via the getActivity() method.

Instead of
datasource = new GradesDataSource(this);
you should use
datasource = new GradesDataSource(getActivity());

Related

SQLite: get id from ListView

This is my first app and i'm having some problem whit ListView
How can I get the ID in the database after clicking on a Item?
I can't use position because the Id may not be continuous and even if it is in order sometimes does not return the correct Id any.
this is my code, Thank you for your help:
import android.content.Intent;
import android.database.Cursor;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
public class livello1 extends AppCompatActivity {
DatabaseHelper myDb;
Button next;
#Override
protected void onCreate(Bundle savedInstanceState) {
myDb = new DatabaseHelper(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.livello1);
populateListView();
registerClick();
}
private void registerClick(){
ListView list =(ListView)findViewById(R.id.listViewMain);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View viewClicked, int position, long id) {
Intent i = new Intent(livello1.this, bossi.note.Edit.class);
i.putExtra("id", position);
//i.putExtra("id", id);
startActivity(i);
}
});
}
private void populateListView(){
Cursor res = myDb.getAllData();
String[] myItems = new String[myDb.numRow()];
int cont = 0;
if(res.getCount() == 0){
// show message
return;
}
while( res. moveToNext()){
myItems[cont] = res.getString(1);
cont ++;
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.da_item, myItems);
ListView list =(ListView)findViewById(R.id.listViewMain);}
There are a lot of solution approaches.
For example, you can store of Id's if ArrayList before ListView initialization.
That is, execute "SELECT id FROM mytable"
Then store in arraylist and use while click method.
Example:
//in class declaration
private ArrayList<Long> ar_ids = new ArrayList<Long>;
//
String sql = "SELECT id FROM table";
Cursor cur = db.rawQuery(sql, null);
String out = "";
ArrayList<Long> ar_ids = new ArrayList<Long>;
if (cur.moveToFirst()) {
do {
ar.add(cur.getString(0));
} while (cur.moveToNext());
}else{
}
}
cur.close();
for click event:
#Override
public void onItemClick(AdapterView<?> parent, View viewClicked, int position, long id) {
Intent i = new Intent(livello1.this, bossi.note.Edit.class);
i.putExtra("id", ar_id.get(position));
//this is awsome!
startActivity(i);
}
and initialize this something like:
private void myfunc() {
String sql = "SELECT id FROM table";
Cursor cur = myDb.rawQuery(sql, null);
String out = "";
ArrayList<Long> ar_ids = new ArrayList<Long>;
if (cur.moveToFirst()) {
do {
ar.add(cur.getString(0));
} while (cur.moveToNext());
}else{
throw new NullPointerException();
}
}
cur.close();
}
private void populateListView(){
myfunc();
Cursor res = myDb.getAllData();
String[] myItems = new String[myDb.numRow()];
int cont = 0;
if(res.getCount() == 0){
// show message
return;
}
while( res. moveToNext()){
myItems[cont] = res.getString(1);
cont ++;
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.da_item, myItems);
ListView list =(ListView)findViewById(R.id.listViewMain);}
well instead of using the ArrayAdapter you can extend a BaseAdapter or ListAdapter or even the ArrayAdapter to make your custom adapter. First of all make a plain java class to map your database data including id to an object. Then make a custom BaseAdapter instead of using the ArrayAdapter. In your BaseAdapter class you have to override various methods including getItem and getItemId methods. Now you can return the whole mapped object from the getItem method and simply obtain the object of selected item of the ListView by using listView.getSelectedItem() method in the Activity or Fragment class. Once you get the object you can access the id easily.
You can find a good example and explanation of a custom adapter here
About mapping the database result to an object, you can get some concept here
Here, you can replace you code class with this one, I have added a cursorAdapter and attached it with your ListView, in adapter I have added a method for getting Id that I call from click listener to retrieve id from cursor, you will have to set column number for _ID in public void getId(int position) from MyCursorAdapter class below.
import android.content.Intent;
import android.database.Cursor;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
public class livello1 extends AppCompatActivity {
DatabaseHelper myDb;
Button next;
private MyCursorAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
myDb = new DatabaseHelper(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.livello1);
populateListView();
registerClick();
}
private void registerClick(){
ListView list =(ListView)findViewById(R.id.listViewMain);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View viewClicked, int position, long id) {
Intent i = new Intent(livello1.this, bossi.note.Edit.class);
//retrieve id from cursor
int _id = adapter.getId(position)
i.putExtra("id", _id);
//i.putExtra("id", id);
startActivity(i);
}
});
}
private void populateListView(){
Cursor res = myDb.getAllData();
adapter = new MyCursorAdapter(this, res, 0);
ListView list =(ListView)findViewById(R.id.listViewMain);
list.setAdapter(adapter);
}
//adapter for list view
class MyCursorAdapter extends CursorAdapter {
Cursor cursor;
// Default constructor
public MyCursorAdapter(Context context, Cursor cursor, int flags) {
super(context, cursor, flags);
this.cursor = cursor;
}
public void bindView(View view, Context context, Cursor cursor) {
String text = cursor.getString(1);
//make sure the TextView id is "#+id/text1" in da_item.xml
TextView tvText = (TextView) view.findViewById(R.id.text1);
tvText.setText(text);
}
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflator inflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
return Inflater.inflate(R.layout.da_item, parent, false);
}
public int getId(int position){
cursor.moveToPosition(position);
int colId = //set id column number here
int id = cursor.getLong(colId);
return id;
}
}
Since the code is untested, you might face a build issue in start, but it should give an idea of what's going on in code. feel free to ask any question if you face any problem in compilation

How to delete row in listview with SimpleCursorAdapter using button

I added a delete button in my ListView row and am trying to find a way to make the delete button work inside of my ListView. I can have my code delete the item from the database, I just need help finding where and how to attach a click event to the row's delete button.
I tried creating a custom cursor adapter, but ran into tons of errors when using my application. Any help is greatly appreciated!
Here's my code:
ListRecipients.java
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class ListRecipients extends Activity
{
ListView list;
Cursor cursor;
SimpleCursorAdapter adapter;
//CursorAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.list);
DbHelper dbhelper = new DbHelper(getApplicationContext());
SQLiteDatabase db = dbhelper.getWritableDatabase();
String[] from = new String[] { DbHelper.NAME, DbHelper.PHONE, DbHelper.MESSAGE };
String[] column = new String[] {DbHelper.ID, DbHelper.NAME, DbHelper.PHONE, DbHelper.MESSAGE };
int[] toViewIDs = new int[] { R.id.text_list_name, R.id.text_list_phoneNum, R.id.text_list_message };
cursor = db.query(DbHelper.TABLE_NAME, column, null, null, null, null, null);
adapter = new SimpleCursorAdapter(this, R.layout.list_item, cursor, from, toViewIDs, 0);
//adapter = new CursorAdapter(this, cursor);
list = (ListView)findViewById(R.id.listview_list);
list.setAdapter(adapter);
cursor.moveToFirst();
while (cursor.moveToNext())
{
String name = cursor.getString(cursor.getColumnIndex(DbHelper.NAME));
String phone = cursor.getString(cursor.getColumnIndex(DbHelper.PHONE));
String message = cursor.getString(cursor.getColumnIndex(DbHelper.MESSAGE));
Toast.makeText(getApplicationContext(), "Name = " + name + "\nPhone = " + phone + "\nMessage = " + message, Toast.LENGTH_SHORT).show();
}
}
}
CustomCursorAdapter.java
import android.content.Context;
import android.database.Cursor;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.Toast;
public class UserCustomAdapter extends CursorAdapter {
Cursor cursor;
LayoutInflater inflater;
Context context;
public UserCustomAdapter(Context context, Cursor cursor) {
super(context, cursor);
this.cursor = cursor;
this.context = context;
inflater = LayoutInflater.from(context);
}
#Override
public void bindView(View view, Context context, final Cursor cursor) {
final String itemId = cursor.getString(cursor.getColumnIndex("ID"));
Button btnDeleteRecipient = (Button) view.findViewById(R.id.btn_list_delete);
btnDeleteRecipient.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Log.i("ListRecipient", "Delete clicked");
//deleteRecordWithId(itemId);
cursor.requery();
notifyDataSetChanged();
}
});
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = inflater.inflate(R.layout.list_item, null);
return v;
}
}
This Idea is Old,
Try to implement Listview with check box and put only a single delete button wherever you like.
When user select multiple check box then get all checked item and then delete that rows only.
here you can find complete example .

i have images in drawable folder and their names stored in sqlite how to display these images from drawable according to there names? [duplicate]

This question already has an answer here:
i have android app that retrieve data from sqlite and display the data in BaseAdapter .. what is the best way ??
(1 answer)
Closed 8 years ago.
I have an android application that use SQLite to store and retrieve data.
In my project i have images in drawable folder that i stored their names in SQLite database, what i want is to display these images according to their names in a ListView.
I know that i need to add the fields name into the code but how to link the image to its name ?
this is my code:
MatchScheduleList.java
package com.devleb.expandablelistdemo3;
import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.app.ListActivity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v4.widget.SimpleCursorAdapter;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class MatchScheduleList extends Activity {
private static final String DB_NAME = "world_cup.db";
// *****Tables name**************************//
private static final String TABLE_NAME = "match_list";
// *****Tbale name******************************//
public static final String PLACE_ID = "_id";
public static final String STAD_NAME = "stad_name";
public static final String TEAM1 = "team1";
public static final String TEAM2 = "team2";
public static final String STAGE = "stage";
public static final String MATCH_DATE = "match_date";
public static final String GROUP = "group";
public static final String[] ALL_KEYS = new String[] { PLACE_ID, STAD_NAME,
TEAM1, TEAM2, STAGE, MATCH_DATE, GROUP };
// *****Tbale name******************************//
private SQLiteDatabase database;
private ListView listView;
private ArrayList<String> matchList;
private ExternalDbOpenHelper extDB;
int[] img = { R.drawable.brazil_flag, R.drawable.croatian_flag,
R.drawable.mexico_flag, R.drawable.cameroon_flag, R.drawable.spain,
R.drawable.netherlands_flag, R.drawable.czech_republic_flag,
R.drawable.australia, R.drawable.colombia_flag, R.drawable.gress,
R.drawable.cote_divoire_flag, R.drawable.japan,
R.drawable.uruguay_flag, R.drawable.costa_rica_flag,
R.drawable.england_flag, R.drawable.italy_flag,
R.drawable.switzerland, R.drawable.ecuador_flag,
R.drawable.france_flag, R.drawable.honduras_flag,
R.drawable.argentina_flag, R.drawable.bousna, R.drawable.iran_flag,
R.drawable.nigeria_flag, R.drawable.germany_flag,
R.drawable.portugal, R.drawable.ghana_flag,
R.drawable.united_states_flag, R.drawable.belgium_flag,
R.drawable.algeria_flag, R.drawable.russia_flag,
R.drawable.korea_flag };
int nextImageIndex = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_match_schedule_list);
ExternalDbOpenHelper extDB = new ExternalDbOpenHelper(this, DB_NAME);
database = extDB.openDataBase();
int imgid = img[nextImageIndex];
nextImageIndex = (nextImageIndex + 1) % img.length;
populateLitsFromDB();
}
public Cursor getAllRows() {
String where = null;
Cursor c = database.query(true, TABLE_NAME, ALL_KEYS, where, null,
null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
private void populateLitsFromDB() {
// TODO Auto-generated method stub
Cursor cursor = getAllRows();
// allo0w activity to manage life cicle of the cursor
startManagingCursor(cursor);
// setup mapping from cursor to view fields
String[] fromFieldNames = new String[] { MATCH_DATE, TEAM1, TEAM2,STAD_NAME, GROUP};
int[] toViewFields = new int[] { R.id.txtDate, R.id.textName1, R.id.textName2, R.id.textLocation, R.id.textGroup};
// create adapter to map columns of the DB INTO ELEMENT IN THE LIST
SimpleCursorAdapter myCursorAdapter = new SimpleCursorAdapter(this,
R.layout.row_list_match_schedule, cursor, fromFieldNames,
toViewFields);
Log.d("in the getAllRows", myCursorAdapter.toString());
// set the adapter for te listView
ListView myList = (ListView) findViewById(R.id.list);
myList.setAdapter(myCursorAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.match_schedule_list, menu);
return true;
}
}
Try this:
String imgName = "ic_launcher"; // specify here your image name fetched from db
String uri = "drawable/" + imgName;
int icon = getResources().getIdentifier(uri, "drawable", getPackageName());
imageView.setImageResource(icon);

Duplicate contacts in resultant List View using cursor adapter

I am creating simple contact application where i want to display only name and number in the list view.
I used cursor adapter to load the contact name and number alone in the list of columns(FROM string array) in Simple Cursor Adapter. However my output lists out contact email id and duplicate names. Here is my code. Please help me to figure out where i went wrong to extract name and number alone.
import android.app.ListActivity;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
public class ListViewLoader extends ListActivity implements
LoaderCallbacks<Cursor> {
SimpleCursorAdapter mAdapter;
static final String[] PROJECTION = new String[] {
ContactsContract.Data._ID, ContactsContract.Data.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER };
static final String SELECTION = "((" + ContactsContract.Data.DISPLAY_NAME
+ " NOTNULL) AND (" + ContactsContract.Data.DISPLAY_NAME
+ " != '' ) AND ("
+ ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER
+ " != 0 ))";;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ProgressBar progressBar = new ProgressBar(this);
progressBar.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
progressBar.setIndeterminate(true);
getListView().setEmptyView(progressBar);
ViewGroup root = (ViewGroup) findViewById(android.R.id.content);
root.addView(progressBar);
String[] fromColumns = { ContactsContract.Data.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER };
int[] toViews = { android.R.id.text1, android.R.id.text2 };
mAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_2, null, fromColumns,
toViews, 0);
setListAdapter(mAdapter);
getLoaderManager().initLoader(0, null, this);
}
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(this, ContactsContract.Data.CONTENT_URI,
PROJECTION, SELECTION, null, null);
}
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mAdapter.swapCursor(data);
}
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
}
}
My Output that lists out email ids which i do not want to get populated:
A
a#gmail.com
B
b#gmail.com
C
c#gmail.com
D
d#gmail.com
A
(000)000-000
B
(111)111-111
(Since I do not have enough reputation, I am unable to upload my output image. Sorry for that)

NullPointerException in onLoaderFinished using SimpleCursorAdapter

I have switched from a ResourceCursorAdapter where I used newView and bindView to a SimpleCursorAdapter where I am using only the getView method.
Now I have an error in onLoaderFinished. Although it gives me NullPointerException on adapter.swapCursor(cursor) both my adapter and cursor object are NOT null. I will post all of my code below. Any help is greatly appreciated (not got much hair left to pull out).
import android.annotation.SuppressLint;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.ResourceCursorAdapter;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
public class ContactSelect extends FragmentActivity implements LoaderManager.LoaderCallbacks<Cursor> {
private static final int LOADER_ID = 1;
private MyAdapter adapter;
private ListView list;
private View row;
private SparseBooleanArray checkedState = new SparseBooleanArray();
#SuppressLint({ "NewApi", "NewApi" })
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_contact_select);
adapter = new MyAdapter(this, R.layout.contacts_select_row, null, null, null, 0);
getSupportLoaderManager().initLoader(LOADER_ID, null, this);
list = (ListView)findViewById(R.id.list);
list.setAdapter(adapter);
list.setEmptyView(findViewById(R.id.empty));
}
#SuppressLint("NewApi")
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
final String projection[] = new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME};
final Uri uri = ContactsContract.Contacts.CONTENT_URI;
final String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1" +
" AND " + ContactsContract.Contacts.IN_VISIBLE_GROUP + " =1";
final String order = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
final CursorLoader loader = new CursorLoader(this, uri, projection, selection, null, order);
return loader;
}
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
for(int i=0;i<cursor.getCount();i++){
checkedState.put(i, false);
}
adapter.swapCursor(cursor);
}
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}
private class MyAdapter extends SimpleCursorAdapter implements OnClickListener{
private CheckBox markedBox;
private TextView familyText;
private Context context;
private Cursor cursor;
public MyAdapter(Context context, int layout, Cursor c, String[] from,
int[] to, int flags) {
super(context, layout, c, from, to, flags);
this.context = context;
this.cursor = getCursor();
}
#Override
public View getView(int position, View view, ViewGroup group) {
final LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = li.inflate(R.layout.contacts_select_row, group, false);
view.setTag(cursor.getPosition());
view.setOnClickListener(this);
familyText = (TextView)view.findViewById(R.id.contacts_row_family_name);
markedBox = (CheckBox)view.findViewById(R.id.contacts_row_check);
familyText.setText(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)));
boolean currentlyChecked = checkedState.get(cursor.getPosition());
markedBox.setChecked(currentlyChecked);
setProgressBarIndeterminateVisibility(false);
return super.getView(position, view, group);
}
public void onClick(View view) {
int rowId = (Integer)view.getTag();
Log.d("OnClick", String.valueOf(rowId));
boolean currentlyChecked = checkedState.get(rowId);
markedBox.setChecked(!currentlyChecked);
checkedState.put(rowId, !currentlyChecked);
Log.d("checkedState", "checkedState(" + rowId + ") = " + checkedState.get(rowId));
}
}
}
A call of the swapCursor method of the SimpleCursorAdapter class will trigger a function which maps the column names from the String array provided to the constructor(the 4th parameter) to an array of integers representing the columns indexes. As you pass null in the constructor of MyAdapter for the String array representing the columns names from the cursor, this will throw a NullPointerException later when the swapCursor will try to make the mapping(the NullPointerException should appear in a method findColumns, which is the actual method that uses the column names String array).
The solution is to pass a valid String array, you may also want to do this for the int array representing the ids for the views in which to place the data:
String[] from = {ContactsContract.Contacts.DISPLAY_NAME};
int[] to = {R.id.contacts_row_family_name, R.id.contacts_row_check};
adapter = new MyAdapter(this, R.layout.contacts_select_row, null, from, to, 0);
I don't know what you are trying to do but your implementation of the getView method is not quite right:
You do the normal stuff for the getView method(creating layouts, searching views, binding data) and then you simply return the view from the superclass(?!?), you'll probably just see the default layout with nothing in it.
The way you wrote the getView method is not very efficient, you may want to look into view recycling and the view holder pattern.
cursor.getPosition() will not do what you want as you don't move the cursor to the correct position. By default cursors based adapters will do this for you in the getView method, but, as you overrode the method it's your job to move the cursor's position.
You should leave the getView method and use the two methods newView and bindView as they offer a better separation of the logic.
adapter = new MyAdapter(this, R.layout.contacts_select_row, null, null, null, 0);
and your MyAdapter class you are passing null cursor
public MyAdapter(Context context, int layout, Cursor c, String[] from,
int[] to, int flags) {
super(context, layout, c, from, to, flags);
this.context = context;
this.cursor = getCursor();
}

Categories

Resources