Need Help Refreshing my database ListView in my app - java

My app layout apparently isn't a normal layout so I a having trouble setting my List Adapter to auto updated when an edit is made.
I make my edits to my database in this Java File which is controlled in its own activity and layout.
public void onClick(View view){
if (view == findViewById(R.id.addsave)) {
RecipeRepo repo = new RecipeRepo(this);
Recipe recipe = new Recipe();
if (editTextName.getText().toString().equals("")) {
editTextName.setError("Recipe name required!");
return;
} else {
recipe.name = editTextName.getText().toString();
}
if (textImagePath.getText().toString().equals("") ) {
recipe.image = ("");
}else{
recipe.image = textImagePath.getText().toString();
}
recipe.category = staticSpinner.getSelectedItem().toString();
if (editTextIngredients.getText().toString().equals("")) {
editTextIngredients.setError("Ingredient required!");
return;
} else {
recipe.ingredients = editTextIngredients.getText().toString();
}
if (editTextInstruct.getText().toString().equals("")) {
editTextIngredients.setError("Instruction required!");
return;
} else {
recipe.instructions = editTextInstruct.getText().toString();
}
recipe.cooktemp = editTextCookTemp.getText().toString();
recipe.cooktime = editTextCookTime.getText().toString();
recipe.serves = editTextServings.getText().toString();
recipe.recipe_Id = _Recipe_Id;
if (_Recipe_Id == 0) {
_Recipe_Id = repo.insert(recipe);
Toast.makeText(this, "New Recipe Added", Toast.LENGTH_SHORT).show();
finish();
it actually inserts and updates in this java file
int insert(Recipe recipe){
//Open connection to write data
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(Recipe.KEY_SERVES, recipe.serves);
values.put(Recipe.KEY_COOKTIME, recipe.cooktime);
values.put(Recipe.KEY_COOKTEMP, recipe.cooktemp);
values.put(Recipe.KEY_INSTRUCT, recipe.instructions);
values.put(Recipe.KEY_INGREDIENTS, recipe.ingredients);
values.put(Recipe.KEY_CATEGORY, recipe.category);
values.put(Recipe.KEY_IMAGE, recipe.image);
values.put(Recipe.KEY_NAME, recipe.name);
//Inserting Row
long recipe_Id = db.insert(Recipe.TABLE, null, values);
db.close();// Closing database connection
return (int) recipe_Id;
}
void delete(int recipe_Id){
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete(Recipe.TABLE, Recipe.KEY_ID + "=?", new String[] {String.valueOf(recipe_Id)});
db.close();
}
void update(Recipe recipe){
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(Recipe.KEY_SERVES, recipe.serves);
values.put(Recipe.KEY_COOKTIME, recipe.cooktime);
values.put(Recipe.KEY_COOKTEMP, recipe.cooktemp);
values.put(Recipe.KEY_INSTRUCT, recipe.instructions);
values.put(Recipe.KEY_INGREDIENTS, recipe.ingredients);
values.put(Recipe.KEY_CATEGORY, recipe.category);
values.put(Recipe.KEY_IMAGE, recipe.image);
values.put(Recipe.KEY_NAME, recipe.name);
db.update(Recipe.TABLE, values, Recipe.KEY_ID + "=?", new String[]{String.valueOf(recipe.recipe_Id)});
db.close();
}
and lastly it gets put into the list view from this Java file and separate layout. Which is where my adapters are but i cannot get the notifyDataSetChanged() to work here at all... as in it wont even come up.
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
RecipeRepo repo = new RecipeRepo(this);
if (id == R.id.nav_meat) {
final ArrayList<HashMap<String, String>> recipeList = repo.getRecipeMeat();
if(recipeList.size()!=0) {
ListView lv = (ListView) findViewById(R.id.list);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
recipe_Id = (TextView) view.findViewById(R.id.recipe_Id);
String recipeId = recipe_Id.getText().toString();
Intent objIndent = new Intent(getApplicationContext(), RecipeDetail.class);
objIndent.putExtra("recipe_Id", Integer.parseInt(recipeId));
startActivity(objIndent);
}
});
ListAdapter adapter = new SimpleAdapter(SousChef.this, recipeList, R.layout.view_recipe_entry, new String[]{"id", "category", "name"}, new int[]{R.id.recipe_Id, R.id.recipe_list_category, R.id.recipe_list_name});
lv.setAdapter(adapter);
}else {
Toast.makeText(this, "No recipe!", Toast.LENGTH_SHORT).show();
}
} else if (id == R.id.nav_veg) {
final ArrayList<HashMap<String, String>> recipeList = repo.getRecipeVeg();
if(recipeList.size()!=0) {
ListView lv = (ListView) findViewById(R.id.list);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
recipe_Id = (TextView) view.findViewById(R.id.recipe_Id);
String recipeId = recipe_Id.getText().toString();
Intent objIndent = new Intent(getApplicationContext(), RecipeDetail.class);
objIndent.putExtra("recipe_Id", Integer.parseInt(recipeId));
startActivity(objIndent);
}
});
ListAdapter adapter = new SimpleAdapter(SousChef.this, recipeList, R.layout.view_recipe_entry, new String[]{"id", "category", "name"}, new int[]{R.id.recipe_Id, R.id.recipe_list_category, R.id.recipe_list_name});
lv.setAdapter(adapter);
}else {
Toast.makeText(this, "No recipe!", Toast.LENGTH_SHORT).show();
}
So any advise on setting this up to automatically update would be a huge help. I have been racking my brain over this for a couple days now looking at different examples and what not, but no setup is quite like this one which doesnt allow me to have everything in one file.
And thank you in advance.
category picking image:
Category picking Image

There are for sure more answers but this is one that might help,
Quick Example for the proposed solution
SHORT EXPLANATION
inside MainActivity
//create a public static adapter
public static ListAdapter adapter
inside onCreateView()
//Create your adapter and set it to the right ListView
ListView lv = findViewById(R.id.listView_in_xml);
adapter = new SimpleAdapter(...)
lv.setAdapter(adapter)
inside CustomAdapter which in your case I assume is SimpleAdapter
//add a public method to be called so that the Adapter updates and displays the new data
public void updateMethod(){
//update your List<Recipe> that I would guess you have calling the database again
//if needed update your getCount() return value so that it returns the number of childs in your ListView which most of the cases is just the List<Recipe>.size()
//notifyDataSetChanged()
}
inside your DB HANDLER CLASS
//in every update, add, delete or any method that requires the ListView to Update just call the created method,
MainActivity.CustomAdapter.updateMethod();
PROBLEMS
You will have to make sure the public static adapter has been initialized and is not null, or simply check whether the adapter is not null and update, because if the adapter is null that activity has not launched yet thus no need to trigger the updateMethod().
OTHER SOLUTIONS
Instead of creating a public static adapter create a public static boolean, then whenever data changes set that boolean to true from the database.
Finally, whenever you resume your activity check against that boolean and update your ListViewAdapter if needed.
MORE COMPLICATED SOLUTIONS WHICH I KNOW WORK CAUSE I USE IT
Use TaskAsyncTaskLoader which utilizes a Loader in your MainActivity and implements LoaderManager.LoaderCallbacks.
Optionally, you can make the Loader be, public static Loaderand inside your DBHandler you trigger the loader to load the data again or use any other logic you want.
Proofs of Working suggested solution,

You can Broadcast Intent from the change database file after you get the response in the onCreate() of adapter loading class
Intent intent = new Intent("key_to_identify_the_broadcast");
Bundle bundle = new Bundle();
bundle.putString("edttext", "changed");
intent.putExtra("bundle_key_for_intent", bundle);
context.sendBroadcast(intent);
and then you can receive the bundle in your fragment by using the BroadcastReceiver class
private final BroadcastReceiver mHandleMessageReceiver = new
BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle =
intent.getExtras().getBundle("bundle_key_for_intent");
if(bundle!=null){
String edttext = bundle.getString("edttext");
}
//you can call any of your methods for using this bundle for your use case
}
};
in onCreate() of your adapter adding class you need to register the broadcast receiver first otherwise this broadcast receiver will not be triggered
IntentFilter filter = new IntentFilter("key_to_identify_the_broadcast");
getActivity().getApplicationContext().
registerReceiver(mHandleMessageReceiver, filter);
Finally you can unregister the receiver to avoid any exceptions
#Override
public void onDestroy() {
try {
getActivity().getApplicationContext().
unregisterReceiver(mHandleMessageReceiver);
} catch (Exception e) {
Log.e("UnRegister Error", "> " + e.getMessage());
}
super.onDestroy();
}

Related

Why my sqlite insert method is not working

Save data with SQLite
Hi guys, I'm new to Android and i'm working in a Notes App, until now I have done with the main interphace and recieve the inputs from the Edittext, but when it comes to saving data to my SQLite DB, my code is failling, can you please tell me what I been doing wrong ?.
FormActivity method
public void saveToDB(View view) {
try {
String subjet = asunto.getText().toString();
String body = cuerpo.getText().toString();
int day = myCalendar.get(Calendar.DAY_OF_MONTH);
int month = myCalendar.get(Calendar.MONTH);
int year = myCalendar.get(Calendar.YEAR);
Note note = new Note(subject,body,day,month,year); // Create an instance of Note class
DBHelper db = new DBHelper(this,"TaskList.db",null,1); // New Instance of DBHelper class
db.InsertIntoTable(note); // pass the newly created Note instance to DBHelper insert method
db.close(); // we close Database
Toast.makeText(this,"Note saved !!",Toast.LENGTH_SHORT).show(); // Notify the user of the operation success
Intent intent = new Intent(FormActivity.this,MainActivity.class); // Lets return to MainActivity again
startActivity(intent);
}
catch (Exception e){
Toast.makeText(this,"Unable to save note",Toast.LENGTH_SHORT).show();
}
}
DBHelper insert method
public Long InsertIntoTable(Note note){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
/* We organize the values in the respective rows */
values.put(col_subject,note.getSubject());
values.put(col_note,note.getBody());
values.put(col_day,note.getDay());
values.put(col_month,note.getMonth());
values.put(col_year, note.getYear());
// Time to insert data to Database
long rowID = db.insert(table_name,null,values);
return rowID;
}
I put a Toast, to prevent my app from crashing in case and to see if the operation succed, but it fails everytime.
RecyclerAdapter class
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.itemview,null);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int i) {
Note note = noteList.get(i);
viewHolder.asunto.setText(note.getAsunto());
viewHolder.nota.setText(note.getCuerpo());
viewHolder.fecha.setText(note.getDia() + "/" + note.getMes() + "/" + note.getAno());
viewHolder.etiqueta.setText(note.getTag());
}
This is in my stacktrace:
E/RecyclerView: No adapter attached; skipping layout

Customize intent in share button with splitting string or how to split string and replace odd commas

Description: I want to use share button. With share button user sending a list as a message. In the list each item has Title + Description
The problem: System get all items from a list and put it in the line one after another by using a comma.
I have: TitleItemOne,DescriptionItemOne,TitleItemTwo,DescriptionItemTwo
I need:
TitleItemOne - DescriptionItemOne
TitleItemTwo - DescriptionItemTwo
Or:
Maybe it is easier to replace all ODD comma "," with "-" so it will that style which i am looking for.
That's the code (needed code in Sharebutton method)
/**
* Displays list of list that were entered and stored in the app.
*/
public class CatalogActivity extends AppCompatActivity implements
LoaderManager.LoaderCallbacks<Cursor> {
private static final String TAG = "myLogs";
/** Identifier for the pet data loader */
private static final int LIST_LOADER = 0;
/** Adapter for the ListView */
ListCursorAdapter mCursorAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_catalog);
Log.v(TAG, "Зашли в catalog activity oncreate");
// Setup FAB to open EditorActivity
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(CatalogActivity.this, EditorActivity.class);
startActivity(intent);
}
});
// Find the ListView which will be populated with the list data
ListView listListView = (ListView) findViewById(R.id.list);
// Find and set empty view on the ListView, so that it only shows when the list has 0 items.
View emptyView = findViewById(R.id.empty_view);
listListView.setEmptyView(emptyView);
// Setup an Adapter to create a list item for each row of list data in the Cursor.
// There is no items data yet (until the loader finishes) so pass in null for the Cursor.
mCursorAdapter = new ListCursorAdapter(this, null);
listListView.setAdapter(mCursorAdapter);
// Setup the item click listener
listListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
ShoppingListBdHelper helper = new ShoppingListBdHelper(view.getContext());
if (helper.setCompleted(id)) {
mCursorAdapter.setCompleted(view);
}
}
});
// Kick off the loader
getSupportLoaderManager().initLoader(LIST_LOADER, null, this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu options from the res/menu/menu_catalog.xml file.
// This adds menu items to the app bar.
getMenuInflater().inflate(R.menu.menu_catalog, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// User clicked on a menu option in the app bar overflow menu
switch (item.getItemId()) {
// Respond to a click on the "Insert dummy data" menu option
case R.id.action_share_button:
shareButton(mCursorAdapter.getCursor());
return true;
// Respond to a click on the "Delete all entries" menu option
case R.id.action_delete_all_entries:
deleteAllItems();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Share button
*/
private void shareButton(Cursor cursor) {
Log.v(TAG, "--- WE ARE IN SHARE BUTTON METHOD ---");
List<String> test;
test = new ArrayList<String>();
cursor.moveToFirst();
while(!cursor.isAfterLast()) {
Log.d(TAG, "field: " + cursor.getString(cursor.getColumnIndex(ListContract.ListEntry.COLUMN_ITEM_NAME)));
test.add(cursor.getString(cursor.getColumnIndex(ListContract.ListEntry.COLUMN_ITEM_NAME))); //add the item
test.add(cursor.getString(cursor.getColumnIndex(ListContract.ListEntry.COLUMN_ITEM_DESCRIPTION))); //add the item
cursor.moveToNext();
}
cursor.moveToFirst();
Log.v(TAG, "--- OUR LIST INCLUDES: " + test.toString());
Intent myIntent = new Intent();
myIntent.setAction(Intent.ACTION_SEND);
myIntent.putStringArrayListExtra("test", (ArrayList<String>) test);
myIntent.putExtra(android.content.Intent.EXTRA_TEXT, test.toString());
Log.v(TAG, "--- INTENT EXTRAS ARE: " + myIntent.getExtras());
myIntent.setType("text/plain");
startActivity(Intent.createChooser(myIntent, "Share using"));
}
/**
* Helper method to delete all list in the database.
*/
private void deleteAllItems() {
Log.v(TAG, "Сработал метод удаления всех данных");
long rowsDeleted = getContentResolver().delete(ListContract.ListEntry.CONTENT_URI, null, null);
Log.v("CatalogActivity", rowsDeleted + " rows deleted from list database");
}
#Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
Log.v(TAG, "Начал работать loader cursor");
// Define a projection that specifies the columns from the table we care about.
String[] projection = {
ListContract.ListEntry._ID,
ListContract.ListEntry.COLUMN_ITEM_NAME,
ListContract.ListEntry.COLUMN_ITEM_DESCRIPTION,
ListContract.ListEntry.COLUMN_ITEM_COMPLETED
};
// This loader will execute the ContentProvider's query method on a background thread
return new CursorLoader(this, // Parent activity context
ListContract.ListEntry.CONTENT_URI, // Provider content URI to query
projection, // Columns to include in the resulting Cursor
null, // No selection clause
null, // No selection arguments
null); // Default sort order
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// Update {#link ListCursorAdapter} with this new cursor containing updated pet data
mCursorAdapter.swapCursor(data);
Log.v(TAG, "Cursor adapter загрузился");
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
// Callback called when the data needs to be deleted
mCursorAdapter.swapCursor(null);
}
}
you can format your strings to html or using "\n"
string to html :
you can use Html.fromHtml() to use HTML tag in your string :
Html.fromHtml("<h2>Title</h2><br><p>Description here</p>"));
for using "\n" you can use System.getProperty("line.separator") wich is OS dependent line separator
Change
test.add(cursor.getString(cursor.getColumnIndex(ListContract.ListEntry.COLUMN_ITEM_NAME))); //add the item test.add(cursor.getString(cursor.getColumnIndex(ListContract.ListEntry.COLUMN_ITEM_DESCRIPTION)));
To
test.add(cursor.getString(cursor.getColumnIndex(ListContract.ListEntry.COLUMN_ITEM_NAME)) + "-" + (cursor.getString(cursor.getColumnIndex(ListContract.ListEntry.COLUMN_ITEM_DESCRIPTION)));
Note:
I may not have all the parenthesis correctly closed, but you get the idea

Android Using a Thread to Execute SQLite Queries

I am trying to create a database of restaurants and their items for an app as a starter project to get familiar with android. I have a list from a previous activity where a user clicks on the name of the restaurant and the items are shown. I created a helperDB class to handle the insert statements and database setup, although when I called my insert method from inside a new thread, they do not seem to execute. I have provided the code below:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_bar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Intent intent = getIntent();
String barName = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
final TextView tv = (TextView) findViewById(R.id.name);
tv.setText(barName);
restaurants = new ArrayList<String>();
mydb = new DBHelper(this);
new Thread(new Runnable() {
#Override
public void run() {
mydb.insertDrink("cake", "McD's", 8);
mydb.insertDrink("muffin", "The Woods", 8);
restaurants = mydb.getDrinks("The Woods");
System.out.println(restaurants);
}
}).start();
ArrayAdapter arrayAdapter=new ArrayAdapter(this,android.R.layout.simple_list_item_1, restaurants);
obj = (ListView)findViewById(R.id.listview);
obj.setAdapter(arrayAdapter);
}
The code for the insert statement and getDrinks method are as follows:
public boolean insertDrink(String drink, String name, int price){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("drink", drink);
contentValues.put("name", name);
contentValues.put("price", price);
db.insert("Bars", null, contentValues);
return true;
}
public ArrayList<String> getDrinks(String name){
ArrayList<String> arrayList = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery("select * from Bars", null);
res.moveToFirst();
while(res.isAfterLast() == false){
arrayList.add(res.getString(res.getColumnIndex(BAR_COLUMN_DRINK)));
res.moveToNext();
}
return arrayList;
}
I know that I am not supposed to access any android toolkits from any thread besides the UI thread, although I don't think I am doing that. If this is not the normal way to populate a SQLite android database, I of course am willing to learn where to do that as well.
although when I called my insert method from inside a new thread, they
do not seem to execute.
How can you say that? Are you seeing data entries in database? Or by looking only for restaurant ArrayList?
My doubt is you are not getting your Restaurant ArrayList because your Thread runs asynchronously.
And your next statement after Thread executed without waiting to fill restaurnat arrayList.
Solution:
Use AsyncTask call your database stuff in doInBackground() and get result in onPostExecute() and set adapter with result in the same method.
I suggest you to use AsyncTask.
Maybe something like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_bar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Intent intent = getIntent();
String barName = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
final TextView tv = (TextView) findViewById(R.id.name);
tv.setText(barName);
new AsyncTask<Void, Void, ArrayList<String>> {
protected Long doInBackground() {
DBHelper mydb = new DBHelper(ThisActivityClassName.this);
mydb.insertDrink("cake", "McD's", 8);
mydb.insertDrink("muffin", "The Woods", 8);
return mydb.getDrinks("The Woods");
}
protected void onPostExecute(ArrayList<String> restaurants) {
ArrayAdapter arrayAdapter=new ArrayAdapter(this,android.R.layout.simple_list_item_1, restaurants);
obj = (ListView)findViewById(R.id.listview);
obj.setAdapter(arrayAdapter);
}
}.execute();
}

Android - How to make an Activity for each item in a ListView and pass Java Object to next screen

I have a ListView of contacts and each contact is a Java object with a bunch of information associated with it. Some of that info is shown in the ListView, but the rest is meant for the DetailView. I'm trying to write a method that will take me to a DetailView for any contact I click on, but I also need to take the object with me. I store all of the contacts in an ArrayList in my MainActivity.java
My questions: Do I need to take the contact object with me or is there actually some way to access my ArrayList in another Activity?
If I can/have to take it with me, how would I do so, since the putExtra() methods don't take objects as arguments.
The beginning of my MainActivity looks like this:
public class MainActivity extends Activity implements AdapterView.OnItemClickListener {
ListView list;
I have a very basic onClickListener right now but don't know what to put into it:
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(MainActivity.this, DetailView.class);
intent.putExtra("contact", i);
startActivity(intent);
}
I feel like my initial definition of the MainActivity class doesn't correspond to the onItemClick method or something, which is why it doesn't execute and take me to another screen.
Intent intent = new Intent(ActivityA.this, DetailView.class);
intent.putExtra("extra_name","extra");
startActivity(intent);
Then in the other Activity :
/*onCreate*/
Object extra = getIntent().getExtra().get("extra_name");
I would recommend to pass an ID of some sort pointing to the description, passing complex data structure with intents is not recommended
Simply, use Intent.putExtra() to pass the information and getIntent().getExtras() to receive the information.
// call a new intent
myIntent = new Intent(ActivityA.this, ActivityB.class);
// put an extra (like this following string)
String userid = "User A";
myIntent.putExtra("TAG_CONTACT_ID", userid);
startActivity(myIntent);
// receive the info in your onCreate method in ActivityB
Bundle extras = getIntent().getExtras();
if(extras != null) {
String newUserID = extras.getString("TAG_CONTACT_ID");
}
See this short example for more information.
If you want to pass an Integer, you can do it as the following: myIntent.putExtra("value", i); and take it with: int myValue = extras.getInt("value");.
Hope this help.
Try something like this:
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Contact c = (Contact)contacts.get(position);
Intent i = new Intent();
i.putExtras("contact", c);
i.setClass(this, Activity2.class);
startActivity(i);
}
Create java object with parcelable
Check the below code to create parcelable object in Android.
public class ObjFeedImages implements Parcelable {
public int image_id;
public boolean like_status = false;
public String image_url = null;
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(new String[] {
String.valueOf(image_id),
String.valueOf(like_status),
image_url, });
}
public ObjFeedImages(Parcel in) {
String[] data = new String[3];
int i = 0;
in.readStringArray(data);
image_id = Integer.parseInt(data[i++]);//
like_status = Boolean.parseBoolean(data[i++]);
image_url = data[i++];
}
public static final Parcelable.Creator<ObjFeedImages> CREATOR = new Parcelable.Creator<ObjFeedImages>() {
#Override
public ObjFeedImages createFromParcel(Parcel source) {
try {
return new ObjFeedImages(source);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
#Override
public ObjFeedImages[] newArray(int size) {
try {
return new ObjFeedImages[size];
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
};
}
After creating some list of such object say
ObjFeedImages object = new ObjFeedImages();
object.image_id = 1;
object.like_status = true;
object.image_url="http://some image url";
Intent intent = new Intent(/*Your Intent Info*/);
intent.putExtras("key_name",object);
startActivity(intent);
Here is the complete description.
To retrive object in other activity you have to write below code.
ObjFeedImages objectOnOtherActivity = (ObjFeedImages)getIntent().getParcelableExtra("key_name");
So ready to enjoy code.
Happy coding....

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