Related
In my android app i am trying to getting contacts list from my phonebook there is 1000 contacts app is taking to much time to load contacts and also it crashes here is my code
when contacts is loading it not responding app is crashes
private ArrayList<AllInOnetItem> getContacts() {
String phoneNo = "";
ArrayList<AllInOnetItem> contacts = new ArrayList<>();
ContentResolver cr = getActivity().getContentResolver();
//ContentResolver cResolver=context.getContextResolver();
ContentProviderClient mCProviderClient = cr.acquireContentProviderClient(ContactsContract.Contacts.CONTENT_URI);
Cursor cur = null;
try {
cur = mCProviderClient.query(ContactsContract.Contacts.CONTENT_URI,
null, null, null, null);
} catch (RemoteException e) {
e.printStackTrace();
}
if ((cur != null ? cur.getCount() : 0) > 0) {
while (cur != null && cur.moveToNext()) {
String id = cur.getString(
cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(
ContactsContract.Contacts.DISPLAY_NAME));
if (cur.getInt(cur.getColumnIndex(
ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) {
Cursor pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[]{id}, null);
while (pCur.moveToNext()) {
phoneNo = pCur.getString(pCur.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.i(TAG, "Name: " + name);
Log.i(TAG, "Phone Number: " + phoneNo);
}
pCur.close();
}
contacts.add(new AllInOnetItem(name, phoneNo));
}
sortlist(contacts);
if (contactAdapter != null) {
contactAdapter.notifyDataSetChanged();
}
}
if (cur != null) {
cur.close();
}
return contacts;
}
Try Below code:
List<ContactVO> contactVOList = new ArrayList();
private void getContacts() {
AsyncTaskRunner runner = new AsyncTaskRunner();
runner.execute();
}
private class AsyncTaskRunner extends AsyncTask<String, String, String> {
private String resp;
ProgressDialog progressDialog;
#Override
protected String doInBackground(String... params) {
ContactVO contactVO;
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));
if (hasPhoneNumber > 0) {
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
contactVO = new ContactVO();
contactVO.setContactName(name);
Cursor phoneCursor = contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[]{id},
null);
if (phoneCursor.moveToNext()) {
String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
contactVO.setContactNumber(phoneNumber);
}
phoneCursor.close();
Cursor emailCursor = contentResolver.query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?",
new String[]{id}, null);
while (emailCursor.moveToNext()) {
String emailId = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
}
contactVOList.add(contactVO);
}
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
// execution of result of Long time consuming operation
hideProgressBar();
setContactAdapter();
}
#Override
protected void onPreExecute() {
showProgressBar();
}
}
public class ContactVO {
private String ContactImage;
private String ContactName;
private String ContactNumber;
private boolean isChecked;
public String getContactImage() {
return ContactImage;
}
public void setContactImage(String contactImage) {
this.ContactImage = ContactImage;
}
public String getContactName() {
return ContactName;
}
public void setContactName(String contactName) {
ContactName = contactName;
}
public String getContactNumber() {
return ContactNumber;
}
public void setContactNumber(String contactNumber) {
ContactNumber = contactNumber;
}
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean checked) {
isChecked = checked;
}
#Override
public String toString() {
return ContactNumber.replace(" ","");
}
}
public class AllContactsAdapter extends RecyclerView.Adapter<AllContactsAdapter.ContactViewHolder> implements Filterable {
private List<ContactVO> contactVOList,contactListFiltered;
private Context mContext;
public AllContactsAdapter(List<ContactVO> contactVOList, Context mContext){
this.contactVOList = contactVOList;
this.contactListFiltered = contactVOList;
this.mContext = mContext;
}
#Override
public ContactViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.single_contact_view, null);
ContactViewHolder contactViewHolder = new ContactViewHolder(view);
return contactViewHolder;
}
#Override
public void onBindViewHolder(ContactViewHolder holder, int position) {
final ContactVO contactVO = contactListFiltered.get(position);
holder.tvContactName.setText(contactVO.getContactName());
holder.tvPhoneNumber.setText(contactVO.getContactNumber());
holder.cbContact.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
contactVO.setChecked(b);
}
});
if(contactVO.isChecked()){
holder.cbContact.setChecked(true);
}
else {
holder.cbContact.setChecked(false);
}
}
#Override
public int getItemCount() {
return contactListFiltered.size();
}
public List<ContactVO> getContacts(){
return contactVOList;
}
public List<ContactVO> getSelectedContacts(){
List<ContactVO> selectedContactVOList = new ArrayList<>();
for (int i = 0; i < contactVOList.size(); i++) {
if(contactVOList.get(i).isChecked()){
selectedContactVOList.add(contactVOList.get(i));
}
}
return selectedContactVOList;
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
contactListFiltered = contactVOList;
} else {
List<ContactVO> filteredList = new ArrayList<>();
for (ContactVO row : contactVOList) {
// name match condition. this might differ depending on your requirement
// here we are looking for name or phone number match
if (row.getContactName().toLowerCase().contains(charString.toLowerCase()) || row.getContactNumber().contains(charSequence)) {
filteredList.add(row);
}
}
contactListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = contactListFiltered;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
contactListFiltered = (ArrayList<ContactVO>) filterResults.values;
notifyDataSetChanged();
}
};
}
public static class ContactViewHolder extends RecyclerView.ViewHolder{
ImageView ivContactImage;
TextView tvContactName;
TextView tvPhoneNumber;
CheckBox cbContact;
public ContactViewHolder(View itemView) {
super(itemView);
ivContactImage = (ImageView) itemView.findViewById(R.id.ivContactImage);
tvContactName = (TextView) itemView.findViewById(R.id.tvContactName);
tvPhoneNumber = (TextView) itemView.findViewById(R.id.tvPhoneNumber);
cbContact = itemView.findViewById(R.id.cbContact);
}
}
}
private void setContactAdapter() {
contactAdapter = new AllContactsAdapter(contactVOList, getApplicationContext());
rvContacts.setLayoutManager(new LinearLayoutManager(SendSMSActivity.this));
rvContacts.setAdapter(contactAdapter);
rlContacts.setVisibility(View.VISIBLE);
}
You can fetch your contacts in background thread. For background task you can use WorkManager, Firebase JobDispatcher, AsyncTask etc. If you will use AsyncTask then you have to keep in mind of memory leaking problem with context.
I have two activities MainActivity and Addlogactivity i am updating a data in Addlogactivity which should be displayed in mainactivity recyclerview the data is not updating in database
MianActivityClass :
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>{
RecyclerView recyclerView;
Intent addDisplay;
Mainrow_Adapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView)findViewById(R.id.listView);
addDisplay = new Intent(this,AddLog.class);
Toolbar toolbar = (Toolbar)findViewById(R.id.maintoolbar);
setSupportActionBar(toolbar);
toolbar.setTitle("Account's");
getSupportLoaderManager().initLoader(1,null,this);
adapter = new Mainrow_Adapter(this,null);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
public void createID(View view)
{
ContentValues values = new ContentValues();
values.put(DataProvider.Pname,"1");
values.put(DataProvider.Pphone,"1");
values.put(DataProvider.Paddress,"1");
values.put(DataProvider.PCategory,"1");
values.put(DataProvider.Pamount,"1");
getContentResolver().insert(DataProvider.ContentUri_Person,values);
long id = DataProvider.insertId;
addDisplay.putExtra("ID",id);
Toast.makeText(MainActivity.this,String.valueOf(id), Toast.LENGTH_SHORT).show();
startActivity(addDisplay);
finish();
}
#Override
protected void onResume() {
super.onResume();
adapter.notifyDataSetChanged();
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] Prjection = {DataProvider.PID,DataProvider.Pname,DataProvider.Pphone,DataProvider.Paddress,DataProvider.PCategory,DataProvider.Pamount};
return new CursorLoader(this,DataProvider.ContentUri_Person,Prjection,null,null,null);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data)
{
adapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader)
{
adapter.swapCursor(null);
}
}
AddLog activity class :
public class AddLog extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>{
TextView TotalAmount,Date;
EditText name,mobile,city,detailname,detailamount;
RecyclerView adddetailtolist;
DetailsAdapter adapter;
Intent returnback;
double totamount;
long logid;
String Debt = "Debt";
String Paid = "Paid";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_log);
Toolbar toolbar = (Toolbar)findViewById(R.id.addlogtoolbar);
setSupportActionBar(toolbar);
toolbar.setTitle("Add Log");
returnback = new Intent(this,MainActivity.class);
Intent intent = getIntent();
logid = intent.getExtras().getLong("ID");
TotalAmount = (TextView)findViewById(R.id.totalAmount);
Date = (TextView)findViewById(R.id.addlogDate);
name = (EditText)findViewById(R.id.AddName);
mobile = (EditText)findViewById(R.id.AddPhone);
city = (EditText)findViewById(R.id.Addcity);
detailname = (EditText)findViewById(R.id.Detailname);
detailamount = (EditText)findViewById(R.id.Detailamount);
adddetailtolist = (RecyclerView)findViewById(R.id.addloglist);
Date.setText(getDate());
getSupportLoaderManager().initLoader(1,null,this);
adapter = new DetailsAdapter(this,null);
adddetailtolist.setAdapter(adapter);
adddetailtolist.setLayoutManager(new LinearLayoutManager(this));
}
private String getDate()
{
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE,dd-MMM-yyyy");
String date = simpleDateFormat.format(calendar.getTime());
return date;
}
public void addDetails(View view)
{
String Name = detailname.getText().toString();
String Amount = detailamount.getText().toString();
String date = Date.getText().toString();
ContentValues contentValues = new ContentValues();
contentValues.put(DataProvider.Dname,Name);
contentValues.put(DataProvider.DCategory,Debt);
contentValues.put(DataProvider.Damount,Amount);
contentValues.put(DataProvider.Ddate,date);
contentValues.put(DataProvider.Per_In,logid);
Uri uri = getContentResolver().insert(DataProvider.ContentUri_Details,contentValues);
Toast.makeText(AddLog.this, uri.toString()+"Value Inserted", Toast.LENGTH_SHORT).show();
NumberFormat currency = changeamount();
TotalAmount.setText(currency.format(getAmount()));
}
private double getAmount()
{
ContentProviderClient client = getContentResolver().acquireContentProviderClient(DataProvider.ContentUri_Details);
SQLiteDatabase db = ((DataProvider)client.getLocalContentProvider()).sqLiteDatabase;
String query = "SELECT SUM(DAmount) FROM Details WHERE Per_In = "+logid;
Cursor cursor = db.rawQuery(query, null);
cursor.moveToFirst();
double amount = cursor.getDouble(0);
cursor.close();
client.release();
return amount;
}
public NumberFormat changeamount()
{
Locale locale = new Locale("en","IN");
NumberFormat currencyformat = NumberFormat.getCurrencyInstance(locale);
return currencyformat;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuinflate = getMenuInflater();
menuinflate.inflate(R.menu.addlogmenu,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.done:
saveData();
}
return super.onOptionsItemSelected(item);
}
private void saveData()
{
String name1 = name.getText().toString();
String phone = mobile.getText().toString();
String address = city.getText().toString();
if (TextUtils.isEmpty(name1)||TextUtils.isEmpty(phone)||TextUtils.isEmpty(address))
{
if (TextUtils.isEmpty(name1))
{
name.setError("Feild can not be Empty");
}
else if (TextUtils.isEmpty(phone))
{
mobile.setError("Feild can not be Empty");
}
else if (TextUtils.isEmpty(address))
{
city.setError("Feild can not be Empty");
}
}
else
{
ContentValues values = new ContentValues();
values.put(DataProvider.Pname,name1);
values.put(DataProvider.Pphone,phone);
values.put(DataProvider.Paddress,address);
values.put(DataProvider.PCategory,"Debt");
values.put(DataProvider.Pamount,totamount);
String where = DataProvider.PID+"=?";
String[] whereargs = {String.valueOf(logid)};
int a = getContentResolver().update(DataProvider.ContentUri_Person,values,where,whereargs);
Toast.makeText(AddLog.this, String.valueOf(1)+"Value updated", Toast.LENGTH_SHORT).show();
startActivity(returnback);
finish();
}
}
#Override
public Loader<Cursor> onCreateLoader(final int id, Bundle args)
{
String[] Projection = new String[]{DataProvider.DID,DataProvider.Dname,DataProvider.DCategory,DataProvider.Damount,DataProvider.Ddate};
String selection = DataProvider.Per_In+"=?";
String[] selectionargs = new String[]{String.valueOf(logid)};
return new CursorLoader(this,DataProvider.ContentUri_Details,Projection,selection,selectionargs,null);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data)
{
adapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader)
{
adapter.swapCursor(null);
}
}
Content Provider class:
public class DataProvider extends ContentProvider
{
static final String ProviderName = "com.example.mrudu.accounts.provider";
static final String URLPerson = "content://"+ProviderName+"/Person_Detail";
static final String URLDetails = "content://"+ProviderName+"/Details";
static final Uri ContentUri_Person = Uri.parse(URLPerson);
static final Uri ContentUri_Details = Uri.parse(URLDetails);
//Tables
private static String PTableName = "Person_Detail";
private static String DTableName = "Details";
public static long insertId = 0;
//Person_Detail Coloumns
public static String PID = "_id";
public static String Pname = "PName";
public static String Pphone = "PMobile";
public static String Paddress = "PCity";
public static String PCategory = "PCategory";
public static String Pamount = "PAmount";
//Details coloumn
public static String DID = "_id";
public static String Dname = "DName";
public static String Damount = "DAmount";
public static String Ddate = "DDate";
public static String DCategory = "DCategory";
public static String Per_In = "Per_In";
private static final int Person = 1;
private static final int Person_ID = 2;
private static final int Details = 3;
private static final int Details_Id = 4;
static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static
{
uriMatcher.addURI(ProviderName,PTableName,Person);
uriMatcher.addURI(ProviderName,PTableName+"/#",Person_ID);
uriMatcher.addURI(ProviderName,DTableName,Details);
uriMatcher.addURI(ProviderName,DTableName+"/#",Details_Id);
}
public static SQLiteDatabase sqLiteDatabase;
private static String Databasename = "Accounts";
private static int DatabaseVersion = 1;
private class DatabaseHelper extends SQLiteOpenHelper
{
public DatabaseHelper(Context context)
{
super(context, Databasename, null, DatabaseVersion);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase)
{
String Create_Person = " Create Table "+PTableName+"("+PID+" INTEGER PRIMARYKEY ,"+Pname+" TEXT ,"+Pphone+" TEXT ,"+Paddress+" TEXT ,"+PCategory+" TEXT ,"+Pamount+" REAL"+")";
String Create_Details = " Create Table "+DTableName+"("+DID+" INTEGER PRIMARYKEY ,"+Dname+" TEXT ,"+DCategory+" TEXT ,"+Damount+" REAl ,"+Ddate+" TEXT ,"+Per_In+" INTEGER )";
sqLiteDatabase.execSQL(Create_Person);
sqLiteDatabase.execSQL(Create_Details);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1)
{
sqLiteDatabase.execSQL("Drop TABLE if exists"+PTableName);
sqLiteDatabase.execSQL("Drop TABLE if exists"+DTableName);
onCreate(sqLiteDatabase);
}
}
#Override
public boolean onCreate()
{
Context context = getContext();
DatabaseHelper databaseHelper = new DatabaseHelper(context);
sqLiteDatabase = databaseHelper.getWritableDatabase();
return (sqLiteDatabase==null)?false:true;
}
#Override
public Uri insert(Uri uri, ContentValues values)
{
switch (uriMatcher.match(uri))
{
case Person:
long rowId = sqLiteDatabase.insert(PTableName,null,values);
insertId = rowId;
if (rowId>0)
{
Uri _uri = ContentUris.withAppendedId(ContentUri_Person,rowId);
getContext().getContentResolver().notifyChange(_uri,null);
return _uri;
}
break;
case Details:
long rowId1 = sqLiteDatabase.insert(DTableName,null,values);
if (rowId1>0)
{
Uri _uri = ContentUris.withAppendedId(ContentUri_Details,rowId1);
getContext().getContentResolver().notifyChange(_uri,null);
return _uri;
}
break;
}
return null;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder)
{
SQLiteQueryBuilder sqLiteQueryBuilder = new SQLiteQueryBuilder();
switch (uriMatcher.match(uri))
{
case Person_ID:
sqLiteQueryBuilder.setTables(PTableName);
sqLiteQueryBuilder.appendWhere(PID+ "="+ uri.getPathSegments().get(1));
break;
case Person:
sqLiteQueryBuilder.setTables(PTableName);
break;
case Details_Id:
sqLiteQueryBuilder.setTables(DTableName);
sqLiteQueryBuilder.appendWhere(Per_In +"="+ uri.getPathSegments().get(1));
break;
case Details:
sqLiteQueryBuilder.setTables(DTableName);
break;
default:
throw new UnsupportedOperationException("Not yet implemented");
}
Cursor cursor = sqLiteQueryBuilder.query(sqLiteDatabase,projection,selection,selectionArgs,null,null,sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(),uri);
return cursor;
}
#Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs)
{
int count = 0;
switch (uriMatcher.match(uri))
{
case Person:
count = sqLiteDatabase.update(PTableName,values,selection,selectionArgs);
break;
case Person_ID:
count = sqLiteDatabase.update(PTableName,values,PID+" = "+uri.getPathSegments().get(1)+(!TextUtils.isEmpty(selection)?" AND (" + selection + ')':""),selectionArgs);
break;
case Details:
count = sqLiteDatabase.update(DTableName,values,selection,selectionArgs);
break;
case Details_Id:
count = sqLiteDatabase.update(DTableName,values,Per_In+" = "+uri.getPathSegments().get(1)+(!TextUtils.isEmpty(selection)?" AND (" + selection + ')':""),selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri );
}
getContext().getContentResolver().notifyChange(uri,null);
return count;
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Implement this to handle requests to delete one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public String getType(Uri uri) {
// TODO: Implement this to handle requests for the MIME type of the data
// at the given URI.
throw new UnsupportedOperationException("Not yet implemented");
}
Cursor Recyclerview Adapter class:
public abstract class CursorRecyclerViewAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
private Context mContext;
private Cursor mCursor;
private boolean mDataValid;
private int mRowIdColumn;
private DataSetObserver mDataSetObserver;
public CursorRecyclerViewAdapter(Context context, Cursor cursor) {
mContext = context;
mCursor = cursor;
mDataValid = cursor != null;
mRowIdColumn = mDataValid ? mCursor.getColumnIndex("_id") : -1;
mDataSetObserver = new NotifyingDataSetObserver();
if (mCursor != null) {
mCursor.registerDataSetObserver(mDataSetObserver);
}
}
public Cursor getCursor() {
return mCursor;
}
#Override
public int getItemCount() {
if (mDataValid && mCursor != null) {
return mCursor.getCount();
}
return 0;
}
#Override
public long getItemId(int position) {
if (mDataValid && mCursor != null && mCursor.moveToPosition(position)) {
return mCursor.getLong(mRowIdColumn);
}
return 0;
}
#Override
public void setHasStableIds(boolean hasStableIds) {
super.setHasStableIds(true);
}
public abstract void onBindViewHolder(VH viewHolder, Cursor cursor);
#Override
public void onBindViewHolder(VH viewHolder, int position) {
if (!mDataValid) {
throw new IllegalStateException("this should only be called when the cursor is valid");
}
if (!mCursor.moveToPosition(position)) {
throw new IllegalStateException("couldn't move cursor to position " + position);
}
onBindViewHolder(viewHolder, mCursor);
}
/**
* Change the underlying cursor to a new cursor. If there is an existing cursor it will be
* closed.
*/
public void changeCursor(Cursor cursor) {
Cursor old = swapCursor(cursor);
if (old != null) {
old.close();
}
}
/**
* Swap in a new Cursor, returning the old Cursor. Unlike
* {#link #changeCursor(Cursor)}, the returned old Cursor is <em>not</em>
* closed.
*/
public Cursor swapCursor(Cursor newCursor) {
if (newCursor == mCursor) {
return null;
}
final Cursor oldCursor = mCursor;
if (oldCursor != null && mDataSetObserver != null) {
oldCursor.unregisterDataSetObserver(mDataSetObserver);
}
mCursor = newCursor;
if (mCursor != null) {
if (mDataSetObserver != null) {
mCursor.registerDataSetObserver(mDataSetObserver);
}
mRowIdColumn = newCursor.getColumnIndexOrThrow("_id");
mDataValid = true;
notifyDataSetChanged();
} else {
mRowIdColumn = -1;
mDataValid = false;
notifyDataSetChanged();
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
}
return oldCursor;
}
private class NotifyingDataSetObserver extends DataSetObserver {
#Override
public void onChanged() {
super.onChanged();
mDataValid = true;
notifyDataSetChanged();
}
#Override
public void onInvalidated() {
super.onInvalidated();
mDataValid = false;
notifyDataSetChanged();
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
}
}
}
Main Adapter class:
public class Mainrow_Adapter extends CursorRecyclerViewAdapter<Mainrow_Adapter.ViewHolder>
{
public Mainrow_Adapter(Context context, Cursor cursor) {
super(context, cursor);
}
public static class ViewHolder extends RecyclerView.ViewHolder
{
TextView mName,mAmount;
public ViewHolder(View itemView) {
super(itemView);
mName = (TextView)itemView.findViewById(R.id.mainrowname);
mAmount = (TextView)itemView.findViewById(R.id.mainrowAmount);
}
}
#Override
public Mainrow_Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.mainrow_layout,parent,false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(Mainrow_Adapter.ViewHolder viewHolder, Cursor cursor)
{
PersonDetails personDetails = PersonDetails.from(cursor);
viewHolder.mName.setText(personDetails.getName());
viewHolder.mAmount.setText(String.valueOf(personDetails.getAmount()));
}
}
Ok,
then move below three lines from onCreate method to onResume(),
getSupportLoaderManager().initLoader(1,null,this);
adapter = new Mainrow_Adapter(this,null);
recyclerView.setAdapter(adapter);
Hope this will work
I am working on a project where user adds data at runtime.The problem is whenever user inserts the fist element it is adding to the database and displaying in recyclerview.But when user adds more data the recyclerview keeps displaying firstelement over and over again.
If the user adds Apple it is adding to database and recyclerview is displaying Apple.Now if the user adds orange it is adding to database but the recyclerview is displaying Apple two times.
I am using Cursorloader to load data,Contentprovider to add data,and CustomCursoradapter(https://gist.github.com/skyfishjy/443b7448f59be978bc59) to set the data to recyclerview
addDetails() method execute when user adds data
public class AddLog extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>{
TextView TotalAmount,Date;
EditText name,mobile,city,detailname,detailamount;
RecyclerView adddetailtolist;
DetailsAdapter adapter;
Intent returnback;
double totamount;
long logid;
String Debt = "Debt";
String Paid = "Paid";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_log);
Toolbar toolbar = (Toolbar)findViewById(R.id.addlogtoolbar);
setSupportActionBar(toolbar);
toolbar.setTitle("Add Log");
returnback = new Intent(this,MainActivity.class);
Intent intent = getIntent();
logid = intent.getExtras().getLong("ID");
TotalAmount = (TextView)findViewById(R.id.totalAmount);
Date = (TextView)findViewById(R.id.addlogDate);
name = (EditText)findViewById(R.id.AddName);
mobile = (EditText)findViewById(R.id.AddPhone);
city = (EditText)findViewById(R.id.Addcity);
detailname = (EditText)findViewById(R.id.Detailname);
detailamount = (EditText)findViewById(R.id.Detailamount);
adddetailtolist = (RecyclerView)findViewById(R.id.addloglist);
Date.setText(getDate());
getSupportLoaderManager().initLoader(1,null,this);
adapter = new DetailsAdapter(this,null);
adddetailtolist.setAdapter(adapter);
adddetailtolist.setLayoutManager(new LinearLayoutManager(this));
}
private String getDate()
{
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE,dd-MMM-yyyy");
String date = simpleDateFormat.format(calendar.getTime());
return date;
}
public void addDetails(View view)
{
String Name = detailname.getText().toString();
String Amount = detailamount.getText().toString();
String date = Date.getText().toString();
ContentValues contentValues = new ContentValues();
contentValues.put(DataProvider.Dname,Name);
contentValues.put(DataProvider.DCategory,Debt);
contentValues.put(DataProvider.Damount,Amount);
contentValues.put(DataProvider.Ddate,date);
contentValues.put(DataProvider.Per_In,logid);
Uri uri = getContentResolver().insert(DataProvider.ContentUri_Details,contentValues);
Toast.makeText(AddLog.this, uri.toString()+"Value Inserted", Toast.LENGTH_SHORT).show();
NumberFormat currency = changeamount();
TotalAmount.setText(currency.format(getAmount()));
}
private double getAmount()
{
ContentProviderClient client = getContentResolver().acquireContentProviderClient(DataProvider.ContentUri_Details);
SQLiteDatabase db = ((DataProvider)client.getLocalContentProvider()).sqLiteDatabase;
String query = "SELECT SUM(DAmount) FROM Details WHERE Per_In = "+logid;
Cursor cursor = db.rawQuery(query, null);
cursor.moveToFirst();
double amount = cursor.getDouble(0);
cursor.close();
client.release();
return amount;
}
public NumberFormat changeamount()
{
Locale locale = new Locale("en","IN");
NumberFormat currencyformat = NumberFormat.getCurrencyInstance(locale);
return currencyformat;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuinflate = getMenuInflater();
menuinflate.inflate(R.menu.addlogmenu,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.done:
saveData();
}
return super.onOptionsItemSelected(item);
}
private void saveData()
{
String name1 = name.getText().toString();
String phone = mobile.getText().toString();
String address = city.getText().toString();
if (TextUtils.isEmpty(name1)||TextUtils.isEmpty(phone)||TextUtils.isEmpty(address))
{
if (TextUtils.isEmpty(name1))
{
name.setError("Feild can not be Empty");
}
else if (TextUtils.isEmpty(phone))
{
mobile.setError("Feild can not be Empty");
}
else if (TextUtils.isEmpty(address))
{
city.setError("Feild can not be Empty");
}
}
else
{
ContentValues values = new ContentValues();
values.put(DataProvider.Pname,name1);
values.put(DataProvider.Pphone,phone);
values.put(DataProvider.Paddress,address);
values.put(DataProvider.PCategory,"Debt");
values.put(DataProvider.Pamount,totamount);
String where = DataProvider.PID+"=?";
String[] whereargs = {String.valueOf(logid)};
int a = getContentResolver().update(DataProvider.ContentUri_Person,values,where,whereargs);
Toast.makeText(AddLog.this, String.valueOf(1)+"Value updated", Toast.LENGTH_SHORT).show();
startActivity(returnback);
finish();
}
}
#Override
public Loader<Cursor> onCreateLoader(final int id, Bundle args)
{
String[] Projection = new String[]{DataProvider.DID,DataProvider.Dname,DataProvider.DCategory,DataProvider.Damount,DataProvider.Ddate};
String selection = DataProvider.Per_In+"=?";
String[] selectionargs = new String[]{String.valueOf(logid)};
return new CursorLoader(this,DataProvider.ContentUri_Details,Projection,selection,selectionargs,null);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data)
{
adapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader)
{
adapter.swapCursor(null);
}
}
Content Provider class:
public class DataProvider extends ContentProvider
{
static final String ProviderName = "com.example.mrudu.accounts.provider";
static final String URLPerson = "content://"+ProviderName+"/Person_Detail";
static final String URLDetails = "content://"+ProviderName+"/Details";
static final Uri ContentUri_Person = Uri.parse(URLPerson);
static final Uri ContentUri_Details = Uri.parse(URLDetails);
//Tables
private static String PTableName = "Person_Detail";
private static String DTableName = "Details";
public static long insertId = 0;
//Person_Detail Coloumns
public static String PID = "_id";
public static String Pname = "PName";
public static String Pphone = "PMobile";
public static String Paddress = "PCity";
public static String PCategory = "PCategory";
public static String Pamount = "PAmount";
//Details coloumn
public static String DID = "_id";
public static String Dname = "DName";
public static String Damount = "DAmount";
public static String Ddate = "DDate";
public static String DCategory = "DCategory";
public static String Per_In = "Per_In";
private static final int Person = 1;
private static final int Person_ID = 2;
private static final int Details = 3;
private static final int Details_Id = 4;
static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static
{
uriMatcher.addURI(ProviderName,PTableName,Person);
uriMatcher.addURI(ProviderName,PTableName+"/#",Person_ID);
uriMatcher.addURI(ProviderName,DTableName,Details);
uriMatcher.addURI(ProviderName,DTableName+"/#",Details_Id);
}
public static SQLiteDatabase sqLiteDatabase;
private static String Databasename = "Accounts";
private static int DatabaseVersion = 1;
private class DatabaseHelper extends SQLiteOpenHelper
{
public DatabaseHelper(Context context)
{
super(context, Databasename, null, DatabaseVersion);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase)
{
String Create_Person = " Create Table "+PTableName+"("+PID+" INTEGER PRIMARYKEY ,"+Pname+" TEXT ,"+Pphone+" TEXT ,"+Paddress+" TEXT ,"+PCategory+" TEXT ,"+Pamount+" REAL"+")";
String Create_Details = " Create Table "+DTableName+"("+DID+" INTEGER PRIMARYKEY ,"+Dname+" TEXT ,"+DCategory+" TEXT ,"+Damount+" REAl ,"+Ddate+" TEXT ,"+Per_In+" INTEGER )";
sqLiteDatabase.execSQL(Create_Person);
sqLiteDatabase.execSQL(Create_Details);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1)
{
sqLiteDatabase.execSQL("Drop TABLE if exists"+PTableName);
sqLiteDatabase.execSQL("Drop TABLE if exists"+DTableName);
onCreate(sqLiteDatabase);
}
}
#Override
public boolean onCreate()
{
Context context = getContext();
DatabaseHelper databaseHelper = new DatabaseHelper(context);
sqLiteDatabase = databaseHelper.getWritableDatabase();
return (sqLiteDatabase==null)?false:true;
}
#Override
public Uri insert(Uri uri, ContentValues values)
{
switch (uriMatcher.match(uri))
{
case Person:
long rowId = sqLiteDatabase.insert(PTableName,null,values);
insertId = rowId;
if (rowId>0)
{
Uri _uri = ContentUris.withAppendedId(ContentUri_Person,rowId);
getContext().getContentResolver().notifyChange(_uri,null);
return _uri;
}
break;
case Details:
long rowId1 = sqLiteDatabase.insert(DTableName,null,values);
if (rowId1>0)
{
Uri _uri = ContentUris.withAppendedId(ContentUri_Details,rowId1);
getContext().getContentResolver().notifyChange(_uri,null);
return _uri;
}
break;
}
return null;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder)
{
SQLiteQueryBuilder sqLiteQueryBuilder = new SQLiteQueryBuilder();
switch (uriMatcher.match(uri))
{
case Person_ID:
sqLiteQueryBuilder.setTables(PTableName);
sqLiteQueryBuilder.appendWhere(PID+ "="+ uri.getPathSegments().get(1));
break;
case Person:
sqLiteQueryBuilder.setTables(PTableName);
break;
case Details_Id:
sqLiteQueryBuilder.setTables(DTableName);
sqLiteQueryBuilder.appendWhere(Per_In +"="+ uri.getPathSegments().get(1));
break;
case Details:
sqLiteQueryBuilder.setTables(DTableName);
break;
default:
throw new UnsupportedOperationException("Not yet implemented");
}
Cursor cursor = sqLiteQueryBuilder.query(sqLiteDatabase,projection,selection,selectionArgs,null,null,sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(),uri);
return cursor;
}
#Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs)
{
int count = 0;
switch (uriMatcher.match(uri))
{
case Person:
count = sqLiteDatabase.update(PTableName,values,selection,selectionArgs);
break;
case Person_ID:
count = sqLiteDatabase.update(PTableName,values,PID+" = "+uri.getPathSegments().get(1)+(!TextUtils.isEmpty(selection)?" AND (" + selection + ')':""),selectionArgs);
break;
case Details:
count = sqLiteDatabase.update(DTableName,values,selection,selectionArgs);
break;
case Details_Id:
count = sqLiteDatabase.update(DTableName,values,Per_In+" = "+uri.getPathSegments().get(1)+(!TextUtils.isEmpty(selection)?" AND (" + selection + ')':""),selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri );
}
getContext().getContentResolver().notifyChange(uri,null);
return count;
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Implement this to handle requests to delete one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public String getType(Uri uri) {
// TODO: Implement this to handle requests for the MIME type of the data
// at the given URI.
throw new UnsupportedOperationException("Not yet implemented");
}
}
Detils class:
public class Details
{
String name,date;
double amount;
public Details(String name, double amount, String date) {
this.name = name;
this.amount = amount;
this.date = date;
}
public Details() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public static Details from(Cursor cursor)
{
cursor.moveToFirst();
do {
Details details = new Details(cursor.getString(1),cursor.getDouble(3),cursor.getString(4));
return details;
}while (cursor.moveToNext());
}
}
Adapter class :
public class DetailsAdapter extends CursorRecyclerViewAdapter<DetailsAdapter.View_Holder>
{
public DetailsAdapter(Context context, Cursor cursor) {
super(context, cursor);
}
public static class View_Holder extends RecyclerView.ViewHolder
{
TextView mName,mAmount,mDate;
public View_Holder(View itemView)
{
super(itemView);
mName = (TextView)itemView.findViewById(R.id.DetailName);
mAmount = (TextView)itemView.findViewById(R.id.DetailAmount);
mDate = (TextView)itemView.findViewById(R.id.DetailDate);
}
}
#Override
public DetailsAdapter.View_Holder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.addloglistlayout,parent,false);
View_Holder viewHolder = new View_Holder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(DetailsAdapter.View_Holder viewHolder, Cursor cursor)
{
Details details = Details.from(cursor);
viewHolder.mName.setText(details.getName());
viewHolder.mAmount.setText(String.valueOf(details.getAmount()));
viewHolder.mDate.setText(details.getDate());
}
}
Cursor Recyclerview Adapter class:
public abstract class CursorRecyclerViewAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
private Context mContext;
private Cursor mCursor;
private boolean mDataValid;
private int mRowIdColumn;
private DataSetObserver mDataSetObserver;
public CursorRecyclerViewAdapter(Context context, Cursor cursor) {
mContext = context;
mCursor = cursor;
mDataValid = cursor != null;
mRowIdColumn = mDataValid ? mCursor.getColumnIndex("_id") : -1;
mDataSetObserver = new NotifyingDataSetObserver();
if (mCursor != null) {
mCursor.registerDataSetObserver(mDataSetObserver);
}
}
public Cursor getCursor() {
return mCursor;
}
#Override
public int getItemCount() {
if (mDataValid && mCursor != null) {
return mCursor.getCount();
}
return 0;
}
#Override
public long getItemId(int position) {
if (mDataValid && mCursor != null && mCursor.moveToPosition(position)) {
return mCursor.getLong(mRowIdColumn);
}
return 0;
}
#Override
public void setHasStableIds(boolean hasStableIds) {
super.setHasStableIds(true);
}
public abstract void onBindViewHolder(VH viewHolder, Cursor cursor);
#Override
public void onBindViewHolder(VH viewHolder, int position) {
if (!mDataValid) {
throw new IllegalStateException("this should only be called when the cursor is valid");
}
if (!mCursor.moveToPosition(position)) {
throw new IllegalStateException("couldn't move cursor to position " + position);
}
onBindViewHolder(viewHolder, mCursor);
}
/**
* Change the underlying cursor to a new cursor. If there is an existing cursor it will be
* closed.
*/
public void changeCursor(Cursor cursor) {
Cursor old = swapCursor(cursor);
if (old != null) {
old.close();
}
}
/**
* Swap in a new Cursor, returning the old Cursor. Unlike
* {#link #changeCursor(Cursor)}, the returned old Cursor is <em>not</em>
* closed.
*/
public Cursor swapCursor(Cursor newCursor) {
if (newCursor == mCursor) {
return null;
}
final Cursor oldCursor = mCursor;
if (oldCursor != null && mDataSetObserver != null) {
oldCursor.unregisterDataSetObserver(mDataSetObserver);
}
mCursor = newCursor;
if (mCursor != null) {
if (mDataSetObserver != null) {
mCursor.registerDataSetObserver(mDataSetObserver);
}
mRowIdColumn = newCursor.getColumnIndexOrThrow("_id");
mDataValid = true;
notifyDataSetChanged();
} else {
mRowIdColumn = -1;
mDataValid = false;
notifyDataSetChanged();
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
}
return oldCursor;
}
private class NotifyingDataSetObserver extends DataSetObserver {
#Override
public void onChanged() {
super.onChanged();
mDataValid = true;
notifyDataSetChanged();
}
#Override
public void onInvalidated() {
super.onInvalidated();
mDataValid = false;
notifyDataSetChanged();
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
}
}
}
Thank you
Probably from method in Details causing issue due to cursor.moveToFirst(); and do-while loop. change it as:
public static Details from(Cursor cursor)
{
Details details = new Details(cursor.getString(1),
cursor.getDouble(3),
cursor.getString(4));
return details;
}
I have checked your adapter and all, so you are already moving your cursor to particular position from Adapter, so you don't need to set it moveToFist, so just remove the line cursor.moveToFirst() from Details Class and check result.
I am new to android development and must take the value of the id in the clicked item database.
Already searched several posts but not found the answer .
Below is my code Listview :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.seleciona_jogador_act);
final BancoController bc = new BancoController(this);
final ArrayList<JogadorEntidade> jogadorEntidade = bc.arrayJogador(this);
listView = (ListView) findViewById(R.id.lvSelecionar);
final SelecionaAdapter adapter = new SelecionaAdapter(this, R.layout.adapter_seleciona, jogadorEntidade);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setBackgroundTintList(ColorStateList.valueOf(background));
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
alertInserirJogador(SelecionaJogadorAct.this);
}
});
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//I NEED THIS CODE
Context context = getApplicationContext();
CharSequence text = "ID: " + ", Posicao: " + position;
int duration = Toast.LENGTH_SHORT;
Toast.makeText(context, text, duration).show();
//bc.deletaRegistro(id_player);
Intent intent = getIntent();
SelecionaJogadorAct.this.finish();
startActivity(intent);
}
});
}
My Adapter:
public class SelecionaAdapter extends ArrayAdapter<JogadorEntidade> {
Context context;
int layoutID;
ArrayList<JogadorEntidade> alJogador;
public SelecionaAdapter(Context context, int layoutID, ArrayList<JogadorEntidade> alJogador){
super(context, layoutID, alJogador);
this.context = context;
this.alJogador = alJogador;
this.layoutID = layoutID;
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
View row = convertView;
PlayerHolder holder = null;
if (row == null){
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutID, parent, false);
holder = new PlayerHolder();
holder.txtNome = (TextView)row.findViewById(R.id.txtNomeSelecionar);
holder.txtVitorias = (TextView)row.findViewById(R.id.txtVitóriasSelecionar);
holder.txtDerrotas = (TextView)row.findViewById(R.id.txtDerrotasSelecionar);
row.setTag(holder);
}else {
holder = (PlayerHolder)row.getTag();
}
JogadorEntidade jogadorEntidade = alJogador.get(position);
holder.txtNome.setText(jogadorEntidade.getNome());
holder.txtVitorias.setText("V: " + jogadorEntidade.vitórias);
holder.txtDerrotas.setText("D: " + jogadorEntidade.derrotas);
return row;
}
static class PlayerHolder{
TextView txtNome;
TextView txtVitorias;
TextView txtDerrotas;
}
JogadorEntidade:
public class JogadorEntidade {
public String nome;
public Integer id_jogador;
public String vitórias;
public String derrotas;
public Integer getId_jogador() {
return id_jogador;
}
public void setId_player(int id_player) {
this.id_jogador = id_player;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getVitórias() {
return vitórias;
}
public void setVitórias(String vitórias) {
this.vitórias = vitórias;
}
public String getDerrotas() {
return derrotas;
}
public void setDerrotas(String derrotas) {
this.derrotas = derrotas;
}
public JogadorEntidade(String nome, String vitórias, String derrotas){
super();
this.nome = nome;
this.vitórias = vitórias;
this.derrotas = derrotas;
}
public JogadorEntidade(){}
public void insereJogador(JogadorEntidade jogadorEntidade) {
db = banco.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(banco.NOME_JOGADOR, jogadorEntidade.getNome());
values.put(banco.VITORIAS, jogadorEntidade.getVitórias());
values.put(banco.DERROTAS, jogadorEntidade.getDerrotas());
db.insert(CriaBanco.TABELA_JOGADOR, null, values);
db.close();
}
public Cursor carregaJogador() {
Cursor cursor;
String[] campos = {banco.NOME_JOGADOR, banco.VITORIAS, banco.DERROTAS};
db = banco.getReadableDatabase();
cursor = db.query(banco.TABELA_JOGADOR, campos, null, null, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
}
db.close();
return cursor;
}
public void deletaRegistro(int id){
String where = CriaBanco.ID_JOGADOR + "=" + id;
db = banco.getReadableDatabase();
db.delete(CriaBanco.TABELA_JOGADOR, where, null);
db.close();
}
public ArrayList<JogadorEntidade> arrayJogador(Context context) {
ArrayList<JogadorEntidade> al = new ArrayList<JogadorEntidade>();
BancoController bancoController = new BancoController(context);
Cursor cursor;
cursor = bancoController.carregaJogador();
if (cursor != null) {
if (cursor.moveToFirst()) {
String nome = cursor.getString(cursor.getColumnIndex(banco.NOME_JOGADOR));
String vitorias = cursor.getString(cursor.getColumnIndex(banco.VITORIAS));
String derrotas = cursor.getString(cursor.getColumnIndex(banco.DERROTAS));
JogadorEntidade jogadorEntidade = new JogadorEntidade(nome, vitorias, derrotas);
al.add(jogadorEntidade);
while (cursor.moveToNext()) {
nome = cursor.getString(cursor.getColumnIndex(banco.NOME_JOGADOR));
vitorias = cursor.getString(cursor.getColumnIndex(banco.VITORIAS));
derrotas = cursor.getString(cursor.getColumnIndex(banco.DERROTAS));
jogadorEntidade = new JogadorEntidade(nome, vitorias, derrotas);
al.add(jogadorEntidade);
}
}
}
return al;
}
First you need to request the id when making the query (if the id is the one created in the database the column mame is _id or you can use tablename._id or whatever you need):
String[] campos = {"_id", banco.NOME_JOGADOR, banco.VITORIAS, banco.DERROTAS};
Then you need to add the id to the object when you read the cursor:
public ArrayList<JogadorEntidade> arrayJogador(Context context) {
ArrayList<JogadorEntidade> al = new ArrayList<JogadorEntidade>();
BancoController bancoController = new BancoController(context);
Cursor cursor;
cursor = bancoController.carregaJogador();
if (cursor != null) {
if (cursor.moveToFirst()) {
String nome = cursor.getString(cursor.getColumnIndex(banco.NOME_JOGADOR));
String vitorias = cursor.getString(cursor.getColumnIndex(banco.VITORIAS));
String derrotas = cursor.getString(cursor.getColumnIndex(banco.DERROTAS));
long id = cursor.getLong(cursor.getColumnIndex("_id",0));
JogadorEntidade jogadorEntidade = new JogadorEntidade(id, nome, vitorias, derrotas);
al.add(jogadorEntidade);
while (cursor.moveToNext()) {
nome = cursor.getString(cursor.getColumnIndex(banco.NOME_JOGADOR));
vitorias = cursor.getString(cursor.getColumnIndex(banco.VITORIAS));
derrotas = cursor.getString(cursor.getColumnIndex(banco.DERROTAS));
long id = cursor.getLong(cursor.getColumnIndex("_id",0));
jogadorEntidade = new JogadorEntidade(id, nome, vitorias, derrotas);
al.add(jogadorEntidade);
}
}
}
return al;
}
Anyway this is not the way to go in android. You should read all the list and then show it. You should use the viewholder pattern and only load the player when you are going to show it. Also instead of using a list you should move to recyclerviews. Listviews can be consider deprecated at this point. See the tutorial: http://developer.android.com/training/material/lists-cards.html
I have code to get phone contact from server in android , I use menu item to make it , this is my code
Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
int row = cursor.getCount();
friend_item = new MenuItem [row];
//int i=0;
while(cursor.moveToNext()){
nama = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
phone = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
// friend_item[i] = new MenuItem(nama,phone);
//i++;
}
cursor.moveToFirst();
while(!cursor.isAfterLast()){
Log.d("", "" + cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
phone = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
phoneList.add(phone);
cursor.moveToNext();
}
cursor.close();
String [] phonearray = (String[]) phoneList.toArray(new String[phoneList.size()]);
// friendarray();
String friends=phonearray[0]+"";
for(int a=1; a<phonearray.length; a++){
friends = friends + ","+ phonearray[a];
}
Log.d("" , "" + friends);
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("phone", mPhoneNumber));
params.add(new BasicNameValuePair("friend", friends));
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(Constants.url_phone_contact, "POST", params);
// Check your log cat for JSON reponse
Log.d("All Friend: ", json.toString());
try {
friend = json.getJSONArray("friend");
friend_item = new MenuItem[friend.length()];
// looping through All Products
for (int a = 0; a < friend.length(); a++) {
JSONObject c = friend.getJSONObject(a);
//Storing each json item in variable
phone_friend= c.getString("phone");
id_friend = c.getString("id_ref");
Log.e("id_user", id_friend);
namaFriend = getName(phone_friend);
if(phone_friend == null){
Toast.makeText(getApplicationContext(), "contact not found", Toast.LENGTH_LONG).show();
}else{
friend_item[a] = new MenuItem(namaFriend, phone_friend);
// creating new HashMap
HashMap<String, String> map1 = new HashMap<String, String>();
// adding each child node to HashMap key => value
//map1.put("phone", mPhoneNumber);
map1.put("id_ref", id_friend);
map1.put("nama_friend", namaFriend);
// adding HashList to ArrayList
friendList.add(map1);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
//i++;*/
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
pDialog.dismiss();
if(friend_item != null && friend_item.length > 0){
mainlist.setAdapter(new ListMenuAdapter(friend_item));
} else
Toast.makeText(getApplicationContext(), "You don't have friend using Shoop! yet, please invite them :)", Toast.LENGTH_LONG).show();
}
}
to get name from android device , I use this code
private String getName(String number) {
// define the columns I want the query to return
String[] projection = new String[] {
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER};
// encode the phone number and build the filter URI
Uri contactUri = Uri.withAppendedPath(ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI, Uri.encode(number));
// query time
Cursor c = getContentResolver().query(contactUri, projection, null,
null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME +" ASC");
// if the query returns 1 or more results
// return the first result
if (c.moveToFirst()) {
String name = c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
return name;
}
// return the original number if no match was found
return number;
}
this List menu adapter
private class ListMenuAdapter extends BaseAdapter{
private MenuItem [] item;
protected ListMenuAdapter(MenuItem... item){
this.item = item;
}
public int getCount() {
return item.length;
}
public Object getItem(int pos) {
return item[pos];
}
public long getItemId(int position) {
return position;
}
public ViewGroup getViewGroup(int position, View view, ViewGroup parent){
if(view instanceof ViewGroup){
return (ViewGroup) view;
}
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
ViewGroup viewgroup = (ViewGroup)inflater.inflate(R.layout.custom_content_friend, null);
return viewgroup;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewGroup group = getViewGroup(position, convertView, parent);
MenuItem menu = item[position];
TextView name = (TextView) group.findViewById(R.id.content_friend_myname);
TextView phone = (TextView) group.findViewById(R.id.content_friend_desc);
if(menu.my_name == null || menu.phone == null){
Toast.makeText(getApplicationContext(), "Contact not found", Toast.LENGTH_LONG).show();
}else{
name.setText(menu.my_name);
phone.setText(menu.phone);
}
return group;
}
}
private class MenuItem{
private String my_name, phone;
protected MenuItem(String my_name, String phone){
this.my_name = my_name;
this.phone= phone;
}
}
and now , I want to get List view that contain name and phone with sorting ascending by name , How to do that?? thanks for ur advice
- First use an ArrayList instead of Array to store the data which will further being used by the Adapter.
- Use java.util.Comparator<T> to sort the name and phone (ie. contacts) according to the name.
- Use Collections.sort(List<?> l , Comparator c) to invoke the sorting.
- And also call notifyDataSetChanged() on the Adapter after setting the ListView with the adapter.
Eg:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
class Car {
private String name;
private String brand;
private double cost;
public Car(String name, String brand, double cost) {
this.name = name;
this.brand = brand;
this.cost = cost;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getCost() {
return cost;
}
public void setCost(double cost) {
this.cost = cost;
}
public String toString() {
return getName();
}
}
public class Hog {
ArrayList<Car> cars = new ArrayList<Car>();
public void setIt() {
cars.add(new Car("Padmini", "Fiat", 100008.00));
cars.add(new Car("XYlo", "Mahindra", 100000.00));
cars.add(new Car("Swift", "Maruti", 200000.00));
}
public void sortIt() {
Collections.sort(cars, new NameComparator());
System.out.println(cars);
Collections.sort(cars, new BrandComparator());
System.out.println(cars);
Collections.sort(cars, new CostComparator());
System.out.println(cars);
}
class NameComparator implements Comparator<Car> {
public int compare(Car c1, Car c2) {
return c1.getName().compareTo(c2.getName());
}
}
class BrandComparator implements Comparator<Car> {
public int compare(Car c1, Car c2) {
return c1.getBrand().compareTo(c2.getBrand());
}
}
class CostComparator implements Comparator<Car> {
public int compare(Car c1, Car c2) {
return new Double(c1.getCost()).compareTo(new Double(c2.getCost()));
}
}
public static void main(String[] args) {
Hog h = new Hog();
h.setIt();
h.sortIt();
}
}
In your activity class write this:
public class MyActivity extends Activity {
....
private ListView listView01;
private ArrayList<MenuItem> list;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ...
listView01 = (ListView)findViewById(R.id.listView1);
list=new ArrayList<MyActivity.MenuItem>();
// code to fill your ArrayList
Collections.sort(list, myComparator);
listView01.setAdapter(new ListMenuAdapter());
}
Comparator<MenuItem> myComparator = new Comparator<MenuItem>()
{
public int compare(MenuItem arg0,MenuItem arg1)
{
return arg0.my_name.compareTo(arg1.my_name);
}
};
}