Parse comment android one to many relations - java

I am trying to use parse to set comments for a specific post , I already have a Post class and a Comment class in the parse.com Data , anyway I tried to set a comment inside a column in the class and then get it , but the problem is , I can only get 1 comment per post , how to do that , is my question , I tried one to many relations , but it didn't work , I tried a pointer row in the Meal class that points to the Comment class , but I didn't know what to do then , here is some sample code :
public void addTheComment() {
// Create the Post object
ParseObject post = new ParseObject("Post");
post.put("textContent", txtComment.getText().toString());
// Create an author relationship with the current user
post.put("comment", getCurrentMeal());
// Save the post and return
post.saveInBackground(new SaveCallback () {
#Override
public void done(ParseException e) {
if (e == null) {
setResult(RESULT_OK);
finish();
} else {
Toast.makeText(getApplicationContext(),
"Error saving: " + e.getMessage(),
Toast.LENGTH_SHORT)
.show();
}
}
});
this adds a comment from edit text through out a button when pressed
and here is the list that shows the comments :
private void updateComments() {
ParseQueryAdapter<ParseObject> adapter =
new ParseQueryAdapter<ParseObject>(this, new ParseQueryAdapter.QueryFactory<ParseObject>() {
public ParseQuery<ParseObject> create() {
// Here we can configure a ParseQuery to our heart's desire.
ParseQuery query = new ParseQuery("Post");
query.whereEqualTo("comment", getCurrentMeal());
return query;
}
});
adapter.setTextKey("comment");
adapter.setImageKey("photo");
ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);
}
and :
public Meal getCurrentMeal() {
return meal;
}

private void updateComments() {
ParseQueryAdapter<ParseObject> adapter =
new ParseQueryAdapter<ParseObject>(this, new ParseQueryAdapter.QueryFactory<ParseObject>() {
public ParseQuery<ParseObject> create() {
// Here we can configure a ParseQuery to our heart's desire.
ParseQuery query = new ParseQuery("Comment");
query.whereContainedIn("parent", Arrays.asList(mealId));
return query;
}
});
adapter.setTextKey("content");
// adapter.setImageKey("photo");
ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);
}
and when pressing the button (activate the method addTheComment) it adds the text from the edit text (txtComment)to insert it into the Comment section where you make a relation to the Post class.
public void addTheComment() {
// Create the comment
ParseObject myComment = new ParseObject("Comment");
myComment.put("content", txtComment.getText().toString());
// Add a relation between the Post with objectId "1zEcyElZ80" and the comment
myComment.put("parent", ParseObject.createWithoutData("Meal", mealId));
// This will save both myPost and myComment
myComment.saveInBackground();
}

Related

ViewModel/LiveData/Observer Design

My app fetches Top Rated or Most Popular movies from themoviedb.org.
I'm trying to implement ViewModel with LiveData to toggle these two buttons. In MainViewModel.java, I have this:
//private static long String TAG = MainViewModel.class.getSimpleName();
public LiveData<List<MovieRoom>> movies;
private AppDatabase database;
/*
Use constructor to initialize all data that UI needs to populate
*/
public MainViewModel(#NonNull Application application) {
super(application);
// how do I know this was initialized correctly?
database = AppDatabase.getInstance(this.getApplication());
//database = AppDatabase.getInstance(application);
//movies is null after calling ViewModelProvider constructor
// what are the values in movies?
// _movieDao = null, mDatabase = null
movies = database.movieDao().getAllMovies();
}
// Loads most popular movies
public void loadData() {
//MainViewModel.FetchMovieTask movies = new MainViewModel.FetchMovieTask();
//movies.execute("popular");
// Assign to movies
}
public void getAllMovies() {
movies = database.movieDao().getAllMovies();
}
public void getPopularMovies() {
movies = database.movieDao().getPopularMovies();
}
public void getTopRatedMovies() {
movies = database.movieDao().getTopRatedMovies();
}
public void getFavoriteMovies() {
movies = database.movieDao().loadFavoriteMovies(true);
}
}
In my MainActivity.java, the buttons have an onclick listener and I have set the observer as the following:
b_pop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//updateMovies("popular");
mViewModel.getPopularMovies();
}
});
mViewModel.movies.observe(this, new Observer<List<MovieRoom>>() {
#Override
public void onChanged(#Nullable List<MovieRoom> movieEntries) {
//Log.d(TAG, "Receiving database update from LiveData");
// mMovieAdapter.mMovies = 0
mMovieAdapter.clear();
// movieEntries = 0
// mMovieAdapter mMovies = 0
mMovieAdapter.setList(movieEntries);
mMovieAdapter.notifyDataSetChanged();
}
});
Problem is, when you reassign the ViewModel's "movies" variable with top rated or most popular list of movies, it doesn't trigger onChanged(). The Top Rated list of movies is the same list of movies as the most popular, but just in different order. So onChanged() is never triggered and I will not be able to set it to the adapter.
I'm learning ViewModel, LiveData and observer from 0 so not sure how to redesign this so that it can work?
Pass the value of newly fetched data to the ViewModel using value on your LiveData:
public void getAllMovies() {
movies.setValue(database.movieDao().getAllMovies().getValue())
}
Also you need MutableLiveData
public MutableLiveData<List<MovieRoom>> movies;

How to change recycler view item dynamically?

I have created a RecyclerView to show each node that I have connected. In the RecyclerView I have added two buttons and one TextView. The TextView will show the current status of the node i.e. whether the node in currently on or off. The nodes are sending their current status over MQTT, I am able to detect the current status of every node on my app but I am unable to update the TextView according to it. How can I update the TextView?
I have tried adding new item and deleting the previous one, but none of them works for me. I have added the code where I am detecting from which node the status message is coming.
//From this section I am getting details of my all node stored into the database
public void addData()
{
pumpList = new ArrayList<>();
StringRequest stringRequest = new StringRequest(Request.Method.GET, REQUEST_URL,
new Response.Listener<String>()
{
#Override
public void onResponse(String response)
{
try
{
JSONArray pumpData = new JSONArray(response);
for(int i = 0; i < pumpData.length(); i++)
{
JSONObject pump = pumpData.getJSONObject(i);
String name = pump.getString("name");
String device_id = pump.getString("device_id");
String stat = pump.getString("stat");
Log.d("HTTP",String.valueOf(name));
Log.d("HTTP",String.valueOf(device_id));
Log.d("HTTP",String.valueOf(stat));
pumpList.add(new pumpData(name,device_id,stat));
}
pumpAdapter adapter = new pumpAdapter(getActivity(),pumpList);
recyclerView.setAdapter(adapter);
progressDialog.dismiss();
}
catch (JSONException e)
{
e.printStackTrace();
progressDialog.dismiss();
}
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
Toast.makeText(getActivity(),error.getMessage(),Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
});
Volley.newRequestQueue(getActivity()).add(stringRequest);
}
//When I get a message over MQTT then I am showing from which device the MQTT Message is Coming from
public void changeDataByFiltering(String MQTT_TOPIC, String MQTT_PAYLOAD)
{
for(pumpData pD: pumpList)
{
insertStringSubscribe INSSUB = new insertStringSubscribe();
String mqtt_topic_from_list = INSSUB.insertString(pD.getDeviceID());
if(mqtt_topic_from_list.trim().toLowerCase().equals(MQTT_TOPIC.trim().toLowerCase()))
[enter image description here][1]{
if(MQTT_PAYLOAD.trim().toLowerCase().equals(payloadON.trim().toLowerCase()))
{
Toast.makeText(mCtx, pD.getName()+": ON",Toast.LENGTH_SHORT).show();
}
if(MQTT_PAYLOAD.trim().toLowerCase().equals(payloadOFF.trim().toLowerCase()))
{
Toast.makeText(mCtx, pD.getName()+": OFF",Toast.LENGTH_SHORT).show();
}
}
}
}
I assume that we have a List<String> data as our data source and we have rvadapter which is our RecyclerView.Adapter . and we will do as below to update an item:
data.set(position,"newdata");
rvadapter.notifyItemChanged(position);
Also, you can change the range of items. and insert new item or delete item but have to call notify... related function in rvadapter
but if you recreate the data for example :
data = new ... then you have to use notifydatasetchanged;

#Askfirebase Get the previous item values(POJO) in firebase recycler adapter in android

AskFirebase How to get the previous item values(POJO) in firebase recycler adapter without using database query.
// Set up FirebaseRecyclerAdapter with the Query
Query postsQuery = getQuery(mDatabase);
mAdapter = new FirebaseRecyclerAdapter<Post, PostViewHolder>(Post.class, R.layout.item_post,
PostViewHolder.class, postsQuery) {
#Override
protected void populateViewHolder(final PostViewHolder viewHolder, final Post model, final int position) {
final DatabaseReference postRef = getRef(position);
Log.e(TAG, "populateViewHolder: " + position);
// Set click listener for the whole post view
final String postKey = postRef.getKey();
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Launch PostDetailActivity
Intent intent = new Intent(getActivity(), PostDetailActivity.class);
intent.putExtra(PostDetailActivity.EXTRA_POST_KEY, postKey);
startActivity(intent);
}
});
// Determine if the current user has liked this post and set UI accordingly
if (model.stars.containsKey(getUid())) {
viewHolder.starView.setImageResource(R.drawable.ic_toggle_star_24);
} else {
viewHolder.starView.setImageResource(R.drawable.ic_toggle_star_outline_24);
}
// Bind Post to ViewHolder, setting OnClickListener for the star button
viewHolder.bindToPost(model, new View.OnClickListener() {
#Override
public void onClick(View starView) {
// Need to write to both places the post is stored
Log.e(TAG, "new: ");
DatabaseReference globalPostRef = mDatabase.child("posts").child(postRef.getKey());
DatabaseReference userPostRef = mDatabase.child("user-posts").child(model.uid).child(postRef.getKey());
// Run two transactions
onStarClicked(globalPostRef);
onStarClicked(userPostRef);
}
});
}
};
mRecycler.setAdapter(mAdapter);
Suppose their are five cell list whenever i am facing second cell in the list that time i want to put a condition based on first cell value. So how i can fatch the value of first cell?
I already try to using arraylist to store the POJO of Post . But the problem is whenever some item is deleted from firebase table that item onDataChange call but populateViewHolder doesn't call. Their is also a way to get previous data using database query that is
DatabaseReference ref = getRef(position-1);
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
Log.e(TAG, "CHild exist: ");
} else {
Log.e(TAG, "no CHild exist: ");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
But i don't want to use this database query is their any other way?
The Design Firebase data structure for topic Answer and Comment its like your problem.
gdtdg6765rf and hjgdhs567hd are unique key get by firebase
hjgdhs567hd is answer
gdtdg6765rf is comment to answer hjgdhs567hd
created is -1*UNIX Timestamp for ordering
date, time and toanswer was saved in comments by answer belong to
if to delete answer set all flags "deleted=1" where child "toanswer=deleted answer key" to populate again
#eurosecom above image is my layout where their is a recycler view which populate through FirebaseRecyclerAdapter . Now those green cell is my single cell. you see a red circle which denote the date. in case of position==0 I just simple visible the layout, and in case of position>0 i want to put the condition based on previous item date.
Now in my FirebaseRecyclerAdapter i have to put the condition so i have to fetch the previous position date. So as i am already doing a network oparetion using Query to fetch the msg list i don't want to put addListenerForSingleValueEvent in the populateview again as because it will again fetch the val from database. So is their any other way to get the previous item?

not able to retrieve string from parse database with query

I'm trying to retrieve a information from a parse object but the strings I store them in keep equaling null.
Here is how I saved the object
// get current user
ParseObject studentClasses = new ParseObject("StudentClasses");
// register their periods into database
studentClasses.put("student_id", ParseUser.getCurrentUser());
studentClasses.put("first_period", ClassSelected_Period[PERIOD1]);
studentClasses.put("second_period", ClassSelected_Period[PERIOD2]);
studentClasses.put("third_period", ClassSelected_Period[PERIOD3]);
studentClasses.put("fourth_period", ClassSelected_Period[PERIOD4]);
studentClasses.put("fifth_period", ClassSelected_Period[PERIOD5]);
studentClasses.put("sixth_period", ClassSelected_Period[PERIOD6]);
studentClasses.put("seventh_period", ClassSelected_Period[PERIOD7]);
// save the information into database
studentClasses.saveInBackground();
It saves it perfectly fine my database. The student_id is a pointer to the user and the rest of the columns are strings.
I want to retrieve all those strings and put them in an array when I query parse for them it doesn't work
Here is my query
// check if a user is not cached
ParseUser currentUser = ParseUser.getCurrentUser();
if (currentUser == null)
{
// prompt user to Register screen
// create intent to start activity
Intent intent = new Intent(MainActivity.this, RegisterActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// start new activity
startActivity(intent);
// stop current activity
finish();
}
// query database for user's classes
ParseQuery<ParseObject> query = ParseQuery.getQuery("StudentClasses");
query.whereEqualTo("student_id", ParseUser.getCurrentUser());
query.getFirstInBackground(new GetCallback<ParseObject>()
{
#Override
public void done (ParseObject parseObject, ParseException e)
{
if (e == null)
{
// retrieved the object
userClasses[PERIOD1] = parseObject.getString("first_period");
userClasses[PERIOD2] = parseObject.getString("second_period");
userClasses[PERIOD3] = parseObject.getString("third_period");
userClasses[PERIOD4] = parseObject.getString("fourth_period");
userClasses[PERIOD5] = parseObject.getString("fifth_period");
userClasses[PERIOD6] = parseObject.getString("sixth_period");
userClasses[PERIOD7] = parseObject.getString("seventh_period");
}
else
{
// failed lookup. Do something here
Toast.makeText(getApplicationContext(),"Exception Thrown" ,Toast.LENGTH_SHORT).show();
}
}
});
I looked at the parse docs and it looks like it should work but it doesn't save the strings
Any help or comments is appreciated thanks!
EDIT: I showed more of my code for the query part to show there is a current user
Here i am assuming that, there is data stored in your parse database.. and it works fine.. so to retrieve it try following..
ParseQuery<ParseObject> query = ParseQuery.getQuery("StudentClasses");
query.whereEqualTo("student_id", ParseUser.getCurrentUser());
query.findInBackground(new FindCallback<ParseObject>()
{
#Override
public void done (List<ParseObject> list, ParseException e)
{
if (e == null)
{
for(int i=0; i < list.size(); i++) {
userClasses[PERIOD1] = list.get(i).getString("first_period");
userClasses[PERIOD2] = list.get(i).getString("second_period");
userClasses[PERIOD3] = list.get(i).getString("third_period");
userClasses[PERIOD4] = list.get(i).getString("fourth_period");
userClasses[PERIOD5] = list.get(i).getString("fifth_period");
userClasses[PERIOD6] = list.get(i).getString("sixth_period");
userClasses[PERIOD7] = list.get(i).getString("seventh_period");
}
}
else
{
Toast.makeText(getApplicationContext(),"Exception Thrown" ,Toast.LENGTH_SHORT).show();
}
}
});
hope it helps!
Well try when getting content to use the function
parseObject.get("the_name_of_the_column")
Which actually should work and works fine for me
Here what you need to understand is in your code studentClasses.saveInBackground(); is async call and you need to query inside SaveCallback. Then you can assure that the saved data is in the database when your query runs.
You got null data because you query before the data is saved in parse.
ParseObject studentClasses = new ParseObject("StudentClasses");
// register their periods into database
studentClasses.put("student_id", ParseUser.getCurrentUser());
studentClasses.put("first_period", ClassSelected_Period[PERIOD1]);
studentClasses.put("second_period", ClassSelected_Period[PERIOD2]);
studentClasses.put("third_period", ClassSelected_Period[PERIOD3]);
studentClasses.put("fourth_period", ClassSelected_Period[PERIOD4]);
studentClasses.put("fifth_period", ClassSelected_Period[PERIOD5]);
studentClasses.put("sixth_period", ClassSelected_Period[PERIOD6]);
studentClasses.put("seventh_period", ClassSelected_Period[PERIOD7]);
// save the information into database
studentClasses.saveInBackground(new SaveCallback() {
public void done(ParseException e) {
if (e == null) {
ParseQuery<ParseObject> query = ParseQuery.getQuery("StudentClasses");
query.whereEqualTo("student_id", ParseUser.getCurrentUser());
query.getFirstInBackground(new GetCallback<ParseObject>()
{
#Override
public void done (ParseObject parseObject, ParseException e)
{
if (e == null)
{
// retrieved the object
userClasses[PERIOD1] = parseObject.getString("first_period");
userClasses[PERIOD2] = parseObject.getString("second_period");
userClasses[PERIOD3] = parseObject.getString("third_period");
userClasses[PERIOD4] = parseObject.getString("fourth_period");
userClasses[PERIOD5] = parseObject.getString("fifth_period");
userClasses[PERIOD6] = parseObject.getString("sixth_period");
userClasses[PERIOD7] = parseObject.getString("seventh_period");
}
else
{
// failed lookup. Do something here
Toast.makeText(getApplicationContext(),"Exception Thrown" ,Toast.LENGTH_SHORT).show();
}
}
});
} else {
// myObjectSaveDidNotSucceed();
}
}
});
Hope this helps
After getting some sleep then doing more research and tinkering I found the problem. The problem isn't in my code; it's in my network... well not entirely. You see my code runs ... at well run-time (As fast as my phone can process it); however, the method
query.findInBackground(new FindCallback<ParseObject>()
runs asynchronously meaning that it does not run at the speed of my other code. Which makes sense if you think about it because it has to send and wait for a response from a database. That's why when I made a toast inside it, the data was there in the string but when I tried to make a toast a few lines later, outside of the method, the data was not there. It was null.
Here's an example. I make a toast at the end of on create with this code
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initialise and set toolbar as actionbar
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
// initialize nav bars
initNavBars();
// initialize drawer layout
NavigationView navView = (NavigationView) findViewById(R.id.navigation_view);
// initialize nav drawer
navDrawer = (DrawerLayout) findViewById(R.id.drawer);
initNavDrawer(navDrawer);
// initialize layout manager for recycler view
RecyclerView.LayoutManager mainLayoutManager = new LinearLayoutManager(this);
// initialize data for all classes before setting adapter
initClassData(); // <---- MY PARSE QUERY IS IN THIS METHOD
// set the adapter for recycler view
RecyclerView.Adapter mainAdapter = new MainRecyclerAdapter(classrooms);
// initialize recycler view elements
RecyclerView mainRecyclerView = (RecyclerView) findViewById(R.id.main_recycler_view);
// add layout manager to recycler view
mainRecyclerView.setLayoutManager(mainLayoutManager);
// add adapter to recycler view
mainRecyclerView.setAdapter(mainAdapter);
Toast.makeText(getApplicationContext(), userClasses[PERIOD1], Toast.LENGTH_SHORT).show(); // <----- HERE IS MY TOAST
}
When I run it, the toast is empty because the string is still null, but if I run it with this code
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initialise and set toolbar as actionbar
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
// initialize nav bars
initNavBars();
// initialize drawer layout
NavigationView navView = (NavigationView) findViewById(R.id.navigation_view);
// initialize nav drawer
navDrawer = (DrawerLayout) findViewById(R.id.drawer);
initNavDrawer(navDrawer);
// initialize layout manager for recycler view
RecyclerView.LayoutManager mainLayoutManager = new LinearLayoutManager(this);
// initialize data for all classes before setting adapter
initClassData(); // <---- PARSE QUERY IS STILL IN THIS METHOD
// set the adapter for recycler view
RecyclerView.Adapter mainAdapter = new MainRecyclerAdapter(classrooms);
// initialize recycler view elements
RecyclerView mainRecyclerView = (RecyclerView) findViewById(R.id.main_recycler_view);
// add layout manager to recycler view
mainRecyclerView.setLayoutManager(mainLayoutManager);
// add adapter to recycler view
mainRecyclerView.setAdapter(mainAdapter);
final Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run()
{
// Do something after 5s = 5000ms
Toast.makeText(getApplicationContext(), userClasses[PERIOD1], Toast.LENGTH_SHORT).show();
}
}, 5000);
}
In this example I forced the toast to wait five seconds to allow
query.getFirstInBackground(new GetCallback<ParseObject>()
to finish querying the database and when I run it, the toast displays the string correctly.
So if your program relies on a parse query to get important data, you have to structure your code in a way to allow for a second or two to pass to let the parse query return.
Or you could alternatively store the data locally and then you can use the database as a backup for the data and check to make sure it is the same every time the user wants to switch it or somethings.
Thank you Ajay and Rasika I would still be trying to figure why it was not working if it weren't you.

Android changing XML layout Changes data fields

Here's a head scratcher...(at least for me)
I have a contact list that displays a list of contacts from my Db. When a user clicks on one of the contacts an edit activity comes up. It all works perfectly as laid out currently, but I need to have the edit activity display the last name entry before the first name. Thinking that all the fields should have a one to one relationship, I went ahead and moved the editText(XML) for the last name above the first name in the edit activity thinking that this should be referenced by the id of the EditText. After doing so, the program is now displaying the first name in the last name field and vise-versa. I have tried wiping the user data on the emulator with no difference. I already realize this is probably one of those UH-DUH! type questions, but if anyone can point out the obvious for me, it would be appreciated. All the code shown is in the now-working state:
I've removed some chunks that would have nothing to do with my issue.
Thanks to anyone having a look at this for me!
Ken
XML:
<EditText
android:id="#+id/contact_edit_first_name"
android:inputType="textPersonName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="#string/contact_edit_first_name"
android:imeOptions="actionNext"
android:background="#color/warn" >
</EditText>
<EditText
android:id="#+id/contact_edit_last_name"
android:inputType="textPersonName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="top"
android:hint="#string/contact_edit_last_name"
android:imeOptions="actionNext"
android:background="#color/warn" >
</EditText>
This is the contact activity that displays the listView rows, and calls
createContact which sends an intent to add, edit or delete rows.
public class ContactsActivity extends ListActivity implements
LoaderManager.LoaderCallbacks<Cursor> {
private SimpleCursorAdapter adapter;
/** Called when the activity is first created. */
#Override
public void onCreate //DO THE ON CREATE STUFF -removed
fillData();
registerForContextMenu(getListView());
Button add_contact = (Button) findViewById(R.id.add_contact_button);
add_contact.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
createContact();
}
});
}
// Create the options menu to INSERT from the XML file
// removed - not relevant
// return true for the menu to be displayed
}
// When the insert menu item is selected, call CreateContact
//Removed
createContact();
return true;
}
return super.onOptionsItemSelected(item);
}
private void createContact() {
Intent i = new Intent(this, ContactEditActivity.class);
startActivity(i);
}
//The onListItemClick sends a URI which flags the contactEditActivity
//that this is an edit rather than a new insert.
#Override
protected void onResume() {
super.onResume();
//Starts a new or restarts an existing Loader in this manager
getLoaderManager().restartLoader(0, null, this);
}
//The fillData method binds the simpleCursorAadapter to the listView.
private void fillData() {
//The desired columns to be bound:
String[] from = new String[] { ContactsDB.COLUMN_LAST_NAME, ContactsDB.COLUMN_FIRST_NAME };
//The XML views that the data will be bound to:
int[] to = new int[] {R.id.label2, R.id.label};
// The creation of a loader using the initLoader method call.
getLoaderManager().initLoader(0, null, this);
adapter = new SimpleCursorAdapter(this, R.layout.contact_row, null, from,
to, 0);
setListAdapter(adapter);
}
// Sort the names by last name, then by first name
String orderBy = ContactsDB.COLUMN_LAST_NAME + " COLLATE NOCASE ASC"
+ "," + ContactsDB.COLUMN_FIRST_NAME + " COLLATE NOCASE ASC" ;
// Creates a new loader after the initLoader () call
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
//ETC
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data); //Call requires Min API 11
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
// swap the cursor adapter
}
And Finally, this is the contact edit code that is likely the source of my grief...maybe not. Could be the save state doesn't map to the id's?
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_contact_edit);
Log.i(TAG, "INSIDE ONCREATE");
mCategory = (Spinner) findViewById(R.id.category);
mLastName = (EditText) findViewById(R.id.contact_edit_last_name);
mFirstName = (EditText) findViewById(R.id.contact_edit_first_name);
mHomePhone = (EditText) findViewById(R.id.contact_edit_home_phone);
mCellPhone = (EditText) findViewById(R.id.contact_edit_cell_phone);
//****************ECT. ETC.
//DECLARE THE BUTTONS AND SET THE DELETE ENABLED FALSE - REMOVED - NOT PERTINANT
Bundle extras = getIntent().getExtras();
// Check if the URI is from a new instance or a saved record
}
// Set the save button to check the required fields, save the contact and finish
saveButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (TextUtils.isEmpty(mLastName.getText().toString()) ||
TextUtils.isEmpty(mFirstName.getText().toString())) {
makeToast();
} else {
setResult(RESULT_OK);
finish();
}
}
});
// Set the delete button to delete the contact and finish - REMOVED - NOT PERTINANT
private void fillData(Uri uri) {
// QUERY PARAMETER projection - A list of which columns to return.
// Passing null will return all columns, which is inefficient (but used now!)
// null, null and null are: selection, selection args, and sort order for specific items
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
String category = cursor.getString(cursor
.getColumnIndexOrThrow(ContactsDB.COLUMN_CATEGORY));
for (int i = 0; i < mCategory.getCount(); i++) {
String s = (String) mCategory.getItemAtPosition(i);
Log.i("CATEGORY", s); ////////////////////////////////////////////
if (s.equalsIgnoreCase(category)) {
mCategory.setSelection(i);
}
};
mLastName.setText(cursor.getString(cursor
.getColumnIndexOrThrow(ContactsDB.COLUMN_LAST_NAME)));
mFirstName.setText(cursor.getString(cursor
.getColumnIndexOrThrow(ContactsDB.COLUMN_FIRST_NAME)));
mHomePhone.setText(cursor.getString(cursor
.getColumnIndexOrThrow(ContactsDB.COLUMN_PHONE_NUMBER)));
mCellPhone.setText(cursor.getString(cursor
.getColumnIndexOrThrow(ContactsDB.COLUMN_CELL_NUMBER)));
mWorkPhone.setText(cursor.getString(cursor
.getColumnIndexOrThrow(ContactsDB.COLUMN_WORK_NUMBER)));
mFax.setText(cursor.getString(cursor
//****************ECT. ETC.
//close the cursor
}
}
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveState();
outState.putParcelable(whateverContentProvider.CONTENT_ITEM_TYPE, contactUri);
}
#Override
protected void onPause() {
super.onPause();
saveState();
}
private void saveState() {
String category = (String) mCategory.getSelectedItem();
String someLAST = mLastName.getText().toString().valueOf(findViewById(R.id.contact_edit_last_name));
String lastName = mLastName.getText().toString();
String firstName = mFirstName.getText().toString();
String someFIRST = mFirstName.getText().toString().valueOf(findViewById(R.id.contact_edit_first_name));
String homePhone = mHomePhone.getText().toString();
String somePhone = mHomePhone.getText().toString().valueOf(findViewById(R.id.contact_edit_home_phone));
String cellPhone = mCellPhone.getText().toString();
String workPhone = mWorkPhone.getText().toString();
//****************ECT. ETC.
//Some logging I used to show that the first name field still came up first
//after changing the order of the editTexts.
Log.i("LAST NAME", lastName);
Log.i("SOME LAST", someLAST);
Log.i("FIRST NAME", firstName);
Log.i("SOME FIRST", someFIRST);
Log.i("Home Phone", homePhone);
Log.i("SOME PHONE", somePhone);
// Save if first name and last name are entered
// The program will save only last name when a user presses back button with text in last name
if (lastName.length() == 0 || firstName.length() == 0) {
return;
}
// ContentValues class is used to store a set of values that the contentResolver can process.
ContentValues values = new ContentValues();
values.put(ContactsDB.COLUMN_CATEGORY, category);
values.put(ContactsDB.COLUMN_LAST_NAME, lastName);//ANNIE
values.put(ContactsDB.COLUMN_FIRST_NAME, firstName);
values.put(ContactsDB.COLUMN_PHONE_NUMBER, homePhone);
//****************ECT. ETC.
if (contactUri == null) {
// Create a new contact
contactUri = getContentResolver().insert(whateverContentProvider.CONTENT_URI, values);
} else {
// Update an existing contact
getContentResolver().update(contactUri, values, null, null);
}
}
//MAKE A TOAST DOWN HERE - REMOVED - NOT PERTINANT
}
Have you tried cleaning the project (regenerating de R).
Also, try restarting your IDE.
This may seem stupid but actually can solve the issue...
try cleaning your project. Weird things happen sometimes within Eclipse.

Categories