In my code, with the help of context menu I'm able to delete a particular item from Listview but as I'm using sharedpreferences to save arraylist called "places" then it restores the sharedpreference when the app is launched back again. Now how should I implement my sharedpreferences such that when a particular item is deleted from listview, the same item also gets deleted from arraylist "places" of shared preferences.
Below is my code snippet
static ArrayList<String> places = new ArrayList<String>();
static ArrayList<LatLng> locations = new ArrayList<>(); //to save lat and long
static ArrayAdapter arrayAdapter;
public ListView listView;
SharedPreferences sharedPreferences;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
sharedPreferences = this.getSharedPreferences("com.starprojects.memorableplaces", Context.MODE_PRIVATE);
registerForContextMenu(listView);
//tricker locations
ArrayList<String> latitudes = new ArrayList<>();
ArrayList<String> longitudes = new ArrayList<>();
//initially set
places.clear();
latitudes.clear();
longitudes.clear();
locations.clear();
//to restore
try {
places = (ArrayList<String>) ObjectSerializer.deserialize(sharedPreferences.getString("places", ObjectSerializer.serialize(new ArrayList<>())));
latitudes = (ArrayList<String>) ObjectSerializer.deserialize(sharedPreferences.getString("latitudes", ObjectSerializer.serialize(new ArrayList<>())));
longitudes = (ArrayList<String>) ObjectSerializer.deserialize(sharedPreferences.getString("longitudes", ObjectSerializer.serialize(new ArrayList<>())));
Log.i("palces",places.toString());
} catch (IOException e) {
e.printStackTrace();
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
// sharedPreferences = getSharedPreferences("places",0);
SharedPreferences.Editor editor = sharedPreferences.edit();
if((item.getTitle()).equals("Delete"))
{
places.remove(info.position);
editor.remove("places"); //problem is here, how to get particular index to be removed from arraylist places and save it.
editor.commit();
arrayAdapter.notifyDataSetChanged();
return true;
}
return super.onContextItemSelected(item);
}
}
you can get index by
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
int index = info.position;
it means you must a list in you shared preference or you have a different key for your shared preference.
Case 1: if you have a list in your shared preference than update the shared preference with the remove of data of data from the listview.
Case 2: if you assigned different key_names for each of the list item then you can simply remove or clear that key_name when the data is removed from the shared preference.
If I'm getting the point of your question you are trying to keep the shared preferences copy up to date with the one you display and vice-versa.
To accomplish this I think that you just need to put the updated places array list into shared preferences, like this:
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
SharedPreferences.Editor editor = sharedPreferences.edit();
if ((item.getTitle()).equals("Delete")) {
// Update local list
places.remove(info.position);
// Set list into shared preferences
// Or if you use a JSON string you could serialize and use putString()
editor.putStringSet("places", places);
// Use apply it's async
editor.apply();
arrayAdapter.notifyDataSetChanged();
return true;
}
return super.onContextItemSelected(item);
}
Please use apply() in place of commit(). It's faster and asynchronous
Related
I have a shopping cart where I add products, but I have a problem with it. When I push the button to delete an item, recycler view is not updated after calling also notifydatachanged(). When I navigate again to my shopping cart, the item is not there because is deleted. But I wan't to see direclty when I'm in my shopping cart activity. Here is my adapter:
holder.removeProduct.setOnClickListener(v -> {
SharedPreferences preferences = mContext.getSharedPreferences(ITEMS_PREF, Context.MODE_PRIVATE);
SharedPreferences.Editor mEditor = preferences.edit();
Gson gson = new Gson();
String json = preferences.getString("artikujtShporta", "");
ArrayList<Artikujt> artikullObject = gson
.fromJson(json, new TypeToken<ArrayList<Artikujt>>(){}.getType());
if (artikullObject != null) {
int indexToRemove;
for(int i = 0 ; i < artikullObject.size(); i++){
if(artikullObject.get(i).getId().equals(artikulli.getId())) {
indexToRemove = i;
artikullObject.remove(indexToRemove);
notifyItemRemoved(indexToRemove);
String jsonString = gson.toJson(artikullObject);
mEditor.putString("artikujtShporta", jsonString);
mEditor.apply();
}
}
}
});
and in my fragment:
SharedPreferences preferences = Objects.requireNonNull(getContext())
.getSharedPreferences(ITEMS_PREF, Context.MODE_PRIVATE);
Gson gson = new Gson();
String json = preferences.getString("artikujtShporta", "");
cartItems = gson.fromJson(json, new TypeToken<ArrayList<Artikujt>>(){}.getType());
basketAdapter = new BasketAdapter(cartItems, getContext());
mRecyclerView = mView.findViewById(R.id.basket_recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this.getActivity()));
mRecyclerView.setAdapter(basketAdapter);
//basketAdapter.clear();
//basketAdapter.addAll(cartItems);
basketAdapter.notifyDataSetChanged();
notifyDataSetChanged here in the for loop:
for(int i = 0 ; i < artikullObject.size(); i++){
if(artikullObject.get(i).getId().equals(artikulli.getId())) {
indexToRemove = i;
artikullObject.remove(indexToRemove);
//here
notifyDataSetChanged();
String jsonString = gson.toJson(artikullObject);
mEditor.putString("artikujtShporta", jsonString);
mEditor.apply();
}
}
UPDATE
keep what I told you and make sure that the list that you call on the method .remove(indexToRemove) is the actual list that you passed to your adapter to populate data, meaning the list that you used in getItemCount()
in other words:
I am not sure if artikullObject is the list that you must remove the object from, you must use the main list you used to populate the adapter.
Create an IShoppingCart Interface which will be implemented by your Fragment. We want to keep the logic in the Fragment. (I personally would move this logic to the ViewModel but that will be going on a tangent.)
IShoppingCart
interface IShoppingCart {
fun addItemToCart(item: CartItem): Boolean
fun removeItemToCart(itemId: String): Boolean
/**
* Feel free to add more functionality
*/
}
Now, pass your fragment through composition to your RecyclerViewAdapter.
RecyclerViewAdapter
ShoppingCartAdapter(val contract: IShoppingCart) : RecyclerView.Adapter<ViewHolder>() {
.
.
.
}
Now you can use this reference in your ViewHolder class as they probably are defined as Inner Classes.
ViewHolder
holder.removeProduct.setOnClickListener(v -> {
// This will kick in the code that lies in the Fragment
contract.removeItemToCart(viewHolder.itemView.id)
});
Now in your Fragment, inside the removeItemToCart(val itemId), just remove the item with the given itemId and call notifyDataSetChanged().
Fragment
fun DeleteItemToCart(itemId: String) {
dataset.removeItemWithItemId(itemId)
notifyDataSetChanged()
}
Following this approach, you do not need to notify the adapter that the whole data set changed, as it did not. You can simply tell the adapter that only a single element's position changed (as it was removed) by using notifyItemRemoved(position: Int).
You can delete an item within the adapter on within a ViewHolder view onClick() listener of a certain row in the RecyclerView by using getAdapterPosition() which returns the position of the clicked row; so you'd add:
artikullObject.remove(getAdapterPosition());
notifyItemRemoved(getAdapterPosition());
So changes in your code:
holder.removeProduct.setOnClickListener(v -> {
SharedPreferences preferences = mContext.getSharedPreferences(ITEMS_PREF, Context.MODE_PRIVATE);
SharedPreferences.Editor mEditor = preferences.edit();
Gson gson = new Gson();
String json = preferences.getString("artikujtShporta", "");
ArrayList<Artikujt> artikullObject = gson
.fromJson(json, new TypeToken<ArrayList<Artikujt>>(){}.getType());
// remove current row of the clicked item
artikullObject.remove(getAdapterPosition());
notifyItemRemoved(getAdapterPosition());
});
Update:
getAdapterPosition() is not found as a method
The getAdapterPosition() is a ViewHolder method that can not be accessed from the adapter class, so you can just transfer the View.OnLongClickListener to be within the custom ViewHolder instead of the custom RecyclerView.Adapter adapter.
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
View removeProduct;
MyViewHolder(#NonNull View listItem) {
super(listItem);
// caching views
removeProduct = listItem.findViewById(...);
// Listen to removing a product
removeProduct.setOnClickListener(v -> {
SharedPreferences preferences = mContext.getSharedPreferences(ITEMS_PREF, Context.MODE_PRIVATE);
SharedPreferences.Editor mEditor = preferences.edit();
Gson gson = new Gson();
String json = preferences.getString("artikujtShporta", "");
ArrayList<Artikujt> artikullObject = gson
.fromJson(json, new TypeToken<ArrayList<Artikujt>>(){}.getType());
// remove current row of the clicked item
artikullObject.remove(getAdapterPosition());
notifyItemRemoved(getAdapterPosition());
});
}
}
Note: your approach of removing a single item by iterating the entire list of items is not that good on performance, so you just need to target a certain index to be deleted.
I'm trying to make favorites module in my app. If user click favorite button for a radio, this radio must displayed in Favorites screen. But just last clicked radio shown in Favorites screen. I want to save more than one radios in Favorites. Where I'm doing wrong? thanks in advance.
This is favorite button in RadioFragment
add_favorites_button= (Button) view.findViewById(R.id.add_favorites_button);
add_favorites_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
SharedPreferences settings = getActivity().getSharedPreferences("PREFS", 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("radio_link", radio_play_link);
editor.putString("radio_namee", radio_name);
editor.commit();
}
});
And I'm trying to get these values and put in ArrayList in FavoritesFragment. To display received values, I sent them in textview to try.
public class FavoritesFragment extends Fragment {
public FavoritesFragment() {
// Required empty public constructor
}
TextView radio_name_txt, radio_link_txt;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_favorites, container, false);
List<String> radio_name_list = new ArrayList<>();
List<String> radio_link_list = new ArrayList<>();
SharedPreferences settings = getActivity().getSharedPreferences("PREFS",0);
radio_name_list.add(settings.getString("radio_namee", ""));
radio_link_list.add(settings.getString("radio_link", ""));
radio_name_txt = (TextView) view.findViewById(R.id.radio_name_txt);
radio_link_txt = (TextView) view.findViewById(R.id.radio_link_txt);
String a= "";
String b= "";
for (int i =0; i<radio_name_list.size(); i++) {
a = a +radio_name_list.get(i);
b = b +radio_link_list.get(i);
}
radio_name_txt.setText(a);
radio_link_txt.setText(b);
return view;
}
}
You have a lot of data and Shared Preferences is not the write option to store your data for 7000 items. Shared preference is good for easy and less frequent data storage, For your case you need to make a SQLite Database. If its totally new to your then pay a visit in Androids only Documentation Training in this link.
since you are using same key for every radio button insert it will overwrite the previous values.
You need to store values in an array and then store array in the preferneces.
Or the better way is to use sqllite database in the android to store the likes in a table.
Try displaying the values from the Lists radio_name_list and radio_link_list in a ListView:
Save the values in an Array List.
Create a ListView instead of a TextView.
Create an ArrayAdapter and set it as the adapter for your ListView.
As far as I can see you only have one TextView. Try creating a ListView instead of a TextView. It will be more organized.
editor.putString("radio_link", radio_play_link);
editor.putString("radio_namee", radio_name);
You are overwriting the favorite every time you try to add a new one, so instead of doing the above, do this:
editor.putString(radio_play_link, radio_play_link);
editor.putString(radio_name, radio_name);
So now you have a key-value pair, and you can iterate over your favorites like this:
String radioLink = "", radioKey = "";
for (Map.Entry<String, ?> entry : getSharedPreferences("PREFS",0).getAll().entrySet()) {
radioKey = entry.getKey();
radioLink = (String) entry.getValue();
}
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
preferences = getSharedPreferences(FAVORI, 0);
ListView favlist = (ListView) findViewById(R.id.favoriliste);
ArrayList<String> foo = new ArrayList<String>();
String [] bar = foo.toArray(new String[0]);
public void favekle(String string) {
foo.add(string);
bar = foo.toArray(new String[0]);
favadapter = new MyFavAdapter(Diziler.this,
android.R.layout.simple_list_item_1, R.id.txtTitle, bar);
// favlist= new ArrayList<>();
favlist.setAdapter(favadapter);
favadapter.notifyDataSetChanged();
}
favadapter = new MyFavAdapter(Diziler.this,
android.R.layout.simple_list_item_1, R.id.txtTitle, bar);
// favlist= new ArrayList<>();
favlist.setAdapter(favadapter);
favadapter.notifyDataSetChanged();
Hello.I need help.I want save dynamically added items in Listview with SharedPreferences.
I'm adding listview items with public void favekle function.I'm adding items to ArrayList<> than i convert ArrayList<> to string array finally i set items to adapter.
If i restart application my listview items disappear.
How can i save added items with sharedpreferences?I used StringBuilder but it didn't work.Thank you.
You can save to shared preference in this way
SharedPreferences sp = context.getSharedPreferences(
"file name", 0);
SharedPreferences.Editor spEdit = sp.edit();
spEdit.putLong(key, value);
spEdit.commit();
You are supposed to store single key-value paired data with SharedPreferences. Trying to store big grouped data is not efficient at all. You should use an SQLite database.
SQLite and ContentProvider Tutorial
You can store string sets in Shared Preferences, then convert them back to a List when you retrieve them.
ArrayList<String> list = new ArrayList<String>();
list.add("test1");
list.add("test2");
PreferenceManager.getDefaultSharedPreferences(context)
.edit()
.putStringSet("stringset", new HashSet<String>(list))
.commit();
How can I save the ListView and restore it by resume? Because when i close the app all contents are delete.
Thanks for answers
public class ToDoList extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView myListView = (ListView)findViewById(R.id.todolist);
final EditText myEditText = (EditText)findViewById(R.id.addtodo);
final ArrayList todoItems = new ArrayList();
final ArrayAdapter aa;
aa = new ArrayAdapter(this,
android.R.layout.simple_list_item_1,
todoItems);
myListView.setAdapter(aa);
String edittext="";
SharedPreferences settings = getSharedPreferences("PreferencesName", 0);
edittext = settings.getString("Content", edittext);
todoItems.add(0, edittext);
myEditText.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN)
if (keyCode == KeyEvent.KEYCODE_ENTER){
todoItems.add(0, myEditText.getText().toString());
aa.notifyDataSetChanged();
String edittext= myEditText.getText().toString();
SharedPreferences settings = getSharedPreferences("PreferencesName", 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("Content", edittext);
myEditText.setText("");
return true;
}
return false;
}
});
}}
According to the comment you gave - about losing data after closing application - there are few options which you have to solve your problem.
What you have to do is to store your data for further use - you can either use SharedPreferences or SQLite database.
SharedPreferences
It is good choice for small amounts of data. If
you're trying to store ListView's content, SharedPreferences is
most likely not a good option for you.
This code you can use for storing data in your SharedPreferences:
SharedPreferences settings = getSharedPreferences("PreferencesName", 0);
SharedPreferences.Editor editor = settings.edit();
editor.putInteger("FirstInteger", a);
editor.putInteger("SecondInteger", b);
(...)
And this is how you retrieve it:
SharedPreferences settings = getSharedPreferences("PreferencesName", 0);
int a = settings.getInteger("FirstInteger", false);
int b = settings.getInteger("SecondInteger", false);
Anyway, here you can read more
about it:
http://developer.android.com/guide/topics/data/data-storage.html
Database
Better for larger amounts of data. It is more difficult,
but if you know basics of MySQL, you will have no problem with using
it. There is a good tutorial about using SQLite database in android
application:
http://www.vogella.com/articles/AndroidSQLite/article.html
After you have stored your data, you can then access the local storage to retrieve them, refill adapter and recreate ListView.
I have a spinner like this:
// Spinner 1
final Spinner plan = (Spinner) dialog.findViewById(R.id.spinner1);
strings = getResources().getStringArray(R.array.paymentplan);
sAdapter = new SpinnerAdapter(this,
android.R.layout.simple_spinner_item, strings);
sAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
plan.setAdapter(sAdapter);
// plan.setAdapter(spinner1Adapter);
plan.setSelection(prefsDisplay.getInt("spinnerSelection1", 0));
plan.setOnItemSelectedListener(new MyOnItemSelectedListenerPlan());
When user clicks, I want it to save state:
public void onClick(View v) {
Editor editor2 = prefsPlan.edit();
int selectedPosition1 = plan.getSelectedItemPosition();
editor2.putInt("spinnerSelection1", selectedPosition1);
editor2.commit();
}
It saves the position in SharedPref, but the spinner goes back to default. Anyone see something here?
you are storing spinnerSelection
editor1.putInt("spinnerSelection", selectedPosition);
an accessing spinnerSelection1
prefsDisplay.getInt("spinnerSelection1", 0)
make them consistent.
Update
when you are accessing plan.getSelectedItemPosition(). then spinner is visible? I guess NO.
try to put a public variable for selected position. And update selected position in your MyOnItemSelectedListenerPlan. And then store that position in shared preferences. I guess it solve your problem.
to Save:
int selectedPosition = yourSpinner.getSelectedItemPosition()
editor.putInt("spinnerSelection", selectedPosition);
editor.commit();
to Load:
yourSpinner.setSelection(prefs.getInt("spinnerSelection",0));
if you are array used it should changed like this
String selectedString = yourArray[yourSpinner.getSelectedItemPosition()];
editor.putString("spinnerSelection", selectedString);
editor.commit();
checking array[i] against the value stored in prefs.if you use an
ArrayList instead this part could be done without the loop by calling
ArrayList.indexOf(prefs.getString("spinnerSelection", "");
when you commit show all above array item gone. show no one into
array.
Try below code and first save position of current selected item into one integer variable on onItemSelectedListener() using below code and after that store this variable value into shared preferences.
For Store value into one Variable.
int index;
public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
// Here Position is Item Index
index = position;
}
For Store Value into shared preferences.
SharedPreferences myPrefs = this.getSharedPreferences("myPrefs", MODE_WORLD_READABLE);
SharedPreferences.Editor prefsEditor = myPrefs.edit();
prefsEditor.putInt("SelectedIndex", index);
prefsEditor.commit();
And see below link for more information
Android Spinners
Android Shared Preferences
after saving to the preferences, you have to set the selected item to the spinner for further uses
as
int pos = prefsDisplay.getInt("spinnerSelection", "0");
display.setSelection(pos);
but you are using spinnerSelection1. so By default if there is no matching in the preferences. the default value will return. so Here 0 is returned and spinner is set to first position