Sorting with Comparator not working - android

I have to store and manage a volume list in the format:
"100 ml", "200 ml", "300 ml"...
I'm using the SharedPreferences with JSON to store this everytime the list is changed.
I want the list to be ordered, so 100 < 1000, but it is showing like 1000 and 2000 before 300.
Here is my comparator:
mVolumeComparator = new Comparator<String>() {
#Override
public int compare(String s1, String s2) {
int volume1 = Integer.parseInt(s1.replace(" ml", ""));
int volume2 = Integer.parseInt(s2.replace(" ml", ""));
if (volume1 > volume2) {
return 1;
} else if (volume2 > volume1) {
return -1;
} else {
return 0;
}
}
};
And here is my get method:
public static ArrayList<String> getVolumesFromPreference(Context ctx) {
if (!ctx.getSharedPreferences(KEY_SHARED_PREFERENCES, MODE_PRIVATE).contains(KEY_VOLUMES_BUNDLE)) {
startDefaultVolumes(ctx, KEY_VOLUMES_BUNDLE);
}
try {
JSONArray jsonArray = new JSONArray(ctx.getSharedPreferences(KEY_SHARED_PREFERENCES, MODE_PRIVATE).getString(KEY_VOLUMES_BUNDLE, null));
ArrayList<String> lista = new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
lista.add(jsonArray.getString(i));
}
Collections.sort(lista, mVolumeComparator);
return lista;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
private static void startDefaultVolumes(Context ctx, String key_bundle) {
JSONArray jsonArray = new JSONArray();
jsonArray.put("269 ml");
jsonArray.put("350 ml");
jsonArray.put("473 ml");
jsonArray.put("550 ml");
jsonArray.put("600 ml");
SharedPreferences.Editor editor = ctx.getSharedPreferences(KEY_SHARED_PREFERENCES, MODE_PRIVATE).edit();
editor.putString(key_bundle, jsonArray.toString());
editor.commit();
}

use Integer.valueOf() method instead Integer.parceInt()

I will recommend you to store only the value "100", "1000", "300" and UNIT if you have more than unit available.
SO, you can order it just with a normal Integer comparator, and then apply the "ml" suffix at runtime

Try this code for sorting arraylist in ascending order.
ArrayList<int> lista = new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
lista.add(Integer.parseInt(jsonArray.getString(i)));
}
Collections.sort(lista , new Comparator<Integer >() {
#Override
public int compare(Integer lhs, Integer rhs) {
return Integer.valueOf(lhs).compareTo(Integer.valueOf(rhs));
}
});

Related

JSONarray separation to lists in android

I have the following JSONarray and I need to have the output like below. Help please.
{
"data": [
{
"Mandal": "Rambilli",
"Village": "Chatametta"
},
{
"Mandal": "Anakapalle",
"Village": "Valluru"
},
{
"Mandal": "Anakapalle",
"Village": "Venkupalem"
},
{
"Mandal": "Rambilli",
"Village": "Chebrolu Konda"
},
{
"Mandal": "Anakapalle",
"Village": "Vetajangalapalem"
},
{
"Mandal": "Anakapalle",
"Village": "Vooderu"
}
]
}
The out put needs to be two lists with names of Mandal
List<String> Rambilli to contain [Chatametta, Chebrolu Konda]
List Anakapalle to contain [Valluru, Venkupalem, Vetajangalapalem, Vooderu]
The major roadblock I'm facing is how to put the name of the mandal to the output list.
I hard coded every thing but Try:
List<String> listOfRambilli = new ArrayList<>();
List<String> listOfAnakapalle = new ArrayList<>();
try {
JSONArray dataArray = jsonData.getJSONArray("data");
for (int i = 0; i < dataArray.length(); i++) {
JSONObject objectInsideDataArray = dataArray.getJSONObject(i);
String village = objectInsideDataArray.getString("Village");
String mandal = objectInsideDataArray.getString("Mandal");
if (mandal.equals("Rambilli"))
listOfRambilli.add(village);
else if (mandal.equals("Anakapalle"))
listOfAnakapalle.add(village);
else
throw new NoSuchElementException();
}
Log.d("TAG", "" + listOfAnakapalle);
Log.d("TAG", "" + listOfRambilli);
} catch (JSONException e) {
e.printStackTrace();
}
Try this way:
JSONArray jsonArray = jsonObject.getJSONArray("data");
ArrayList<String> rambilliList = new ArrayList<>();
ArrayList<String> anakapalleList = new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject listJsonObject = jsonArray.getJSONObject(i);
if(listJsonObject.getString("Mandal").equals("Rambilli")){
rambilliList.add(listJsonObject.getString("Village"));
} else if(listJsonObject.getString("Mandal").equals("Anakapalle")) {
anakapalleList.add(listJsonObject.getString("Village"));
}
}
System.out.println("Rambilli contains" + rambilliList)
System.out.println("Anakapalle contains" + anakapalleList)

implement favorite button in listview android studio

I am implementing favorite button in ListView trying from the last five days. I have created a ListView which gets the current textview text and saves it in the ArrayList (names) and if the data is already present then deletes it, works perfectly but when I close the app the ArrayList gets empty i wants to save the array list in preferences.
array declaration:
ArrayList<String> names = new ArrayList<>();
Below is the code
favoritebutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick( View v) {
if (!names.contains(textView_name.getText())){
names.add((String) textView_name.getText());
for (int i=0; i<names.size(); i++) {
System.out.println(names.get(i));
favoritebutton.setBackgroundResource(R.drawable.fav_checked);
}
}
else {
System.out.println(textView_name.getText() + " is already present in the Array at index " + names.indexOf(textView_name.getText()));
int currentIndex = names.indexOf(textView_name.getText());
names.remove(currentIndex);
for (int i=0; i<names.size(); i++) {
System.out.println(names.get(i));
favoritebutton.setBackgroundResource(R.drawable.star_off);
}
}
}
});
You can use SharedPreferences to retrieve and store data like below:
private ArrayList<String> names;
private SharedPreferences sharedPreferences;
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
String favoriteItems = sharedPreferences.getString("FAVORITE_ITEMS", "");
if(favoriteItems.isEmpty())
names = new ArrayList<>();
else
names = new ArrayList<>(Arrays.asList(favoriteItems.split(",")); //Update like this
favoritebutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick( View v) {
if (!names.contains(textView_name.getText())){
names.add((String) textView_name.getText());
for (int i=0; i<names.size(); i++) {
System.out.println(names.get(i));
favoritebutton.setBackgroundResource(R.drawable.fav_checked);
}
}
else {
System.out.println(textView_name.getText() + " is already present in the Array at index " + names.indexOf(textView_name.getText()));
int currentIndex = names.indexOf(textView_name.getText());
names.remove(currentIndex);
for (int i=0; i<names.size(); i++) {
System.out.println(names.get(i));
favoritebutton.setBackgroundResource(R.drawable.star_off);
}
}
sharedPreferences.edit().putString("FAVORITE_ITEMS", TextUtils.join(",", names)).apply();
}
});
You will have to save that list in preferences after each update you can use Gson lib for that which convert array list to JsonArray and JsonArray to Arraylist which will help to you...
String str = fetchFromPref();
ArrayList<String> names = covertToArrayListFromJSOnString(str);
favoritebutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick( View v) {
if (!names.contains(textView_name.getText())){
names.add((String) textView_name.getText());
for (int i=0; i<names.size(); i++) {
System.out.println(names.get(i));
favoritebutton.setBackgroundResource(R.drawable.fav_checked);
}
}
else {
System.out.println(textView_name.getText() + " is already present in the Array at index " + names.indexOf(textView_name.getText()));
int currentIndex = names.indexOf(textView_name.getText());
names.remove(currentIndex);
for (int i=0; i<names.size(); i++) {
System.out.println(names.get(i));
favoritebutton.setBackgroundResource(R.drawable.star_off);
}
}
String str = convertArrayListToJson(names).toString();
saveToPrefrences(str);
}
});

MultiSelectListPreference onPreferenceChange() method getting wrong parameters

I have an Android app with a MultiSelectListPreference, and I'm using the onPreferenceChange() method to update the Preference's summary. I've managed to write the code that updates the summary based on the newValues parameter, but the contents of the Object do not match the actual options selected by the user.
Here is my code:
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference instanceof MultiSelectListPreference) {
List<String> newValues = new ArrayList<>((HashSet<String>) newValue);
MultiSelectListPreference pref = (MultiSelectListPreference) preference;
ArrayList<String> newSummary = new ArrayList<>();
ArrayList<CharSequence> values = new ArrayList<>(Arrays.asList(pref.getEntryValues()));
for (int i = 0; i < newValues.size(); i++) {
int currentIndex = findIndexOfString(values, newValues.get(i).replaceAll(" ", ""));
String title = (currentIndex >= 0) ? pref.getEntries()[currentIndex].toString().replaceAll(" ", "") : "";
newSummary.add(title);
}
pref.setSummary(TextUtils.join(", ", newSummary));
}
return true;
}
private static int findIndexOfString(List<CharSequence> list, String s) {
for (int i = 0; i < list.size(); i++) {
if (s.equals(list.get(i).toString().replaceAll(" ", ""))) {
return i;
}
}
return -1;
}
This is the code I'm using to set summary based on the newValue Object received from onPreferenceChange(), which contains the values stored as a preference. (Not good for the summary)
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference instanceof MultiSelectListPreference) {
List<String> newValues = new ArrayList<>((HashSet<String>) newValue);
pref.setSummary(TextUtils.join(", ", getSummaryListFromValueList(newValues)));
}
return true;
}
private List<String> getSummaryListFromValueList(List<String> valueList) {
String[] allSummaries = getResources().getStringArray(R.array.pref_notif);
String[] allValues = getResources().getStringArray(R.array.pref_notif_values);
List<String> summaryList = new ArrayList<>();
for (int i = 0; i < allValues.length; i++) {
for (String value : valueList) {
if (allValues[i].equals(value)) {
summaryList.add(allSummaries[i]);
}
}
}
return summaryList;
}

Retrieving String[] from JSONObject from sharedPreferences

I was following Micers Answer store and retrieve a class object in shared preference
But how do I retrieve back STring[] from JSOnObject
my class is :
public class AppearExamState implements Serializable{
private static final long serialVersionUID = 1L;
Boolean flag = false;
int questionId;
int subjectId;
String[] storedAnswers;
public AppearExamState(int q, int subjId, String[] ans, boolean flg){
questionId = q;
subjectId = subjId;
storedAnswers = ans;
flag = flg;
} .......
.........getters and setters.....
.......
//-----------------------------------------------------------------
// Here I convert myObject to JsonObject
//-----------------------------------------------------------------
public JSONObject getJSONObject() {
JSONObject obj = new JSONObject();
try {
obj.put("Qid", this.questionId);
obj.put("Stored_Ans", this.storedAnswers);// is this RIGHT??
obj.put("subj_id", this.subjectId);
obj.put("Flag", this.flag);
} catch (JSONException e) {
e.printStackTrace();
}
return obj;
}
Now when I store in sharepref I followed micers answer and did this:
//--------------------------------------------------------------------------------------
public void sendSharedPreference(ArrayList<AppearExamState> arrayl){
SharedPreferences mPrefs = this.getSharedPreferences("aimmds_state", 0);
SharedPreferences.Editor prefsEditor = mPrefs.edit();
Set<String> set= new HashSet<String>();
for (int i = 0; i < arrayl.size(); i++) {
set.add(arrayl.get(i).getJSONObject().toString());
}
prefsEditor.putStringSet("aimmds_state", set);
prefsEditor.commit();
}
//--------------------------------------------------------------------------------------
and I am stuck here with no clue how to do this
public ArrayList<AppearExamState> loadFromStorage(Context c) {
SharedPreferences mPrefs = c.getSharedPreferences("aimmds_state", 0);
ArrayList<AppearExamState> items = new ArrayList<AppearExamState>();
Set<String> set = mPrefs.getStringSet("aimmds_state", null);
for (String s : set) {
try {
JSONObject jsonObject = new JSONObject(s);
int Quesid = jsonObject.getInt("Qid");
int SubjId = jsonObject.getInt("subj_id");
Boolean flag = jsonObject.getBoolean("Flag");
String[] StoAnswer = ????? ;
AppearExamState myclass = new AppearExamState(Quesid, SubjId, StoAnswer, flag );
items.add(myclass);
} catch (JSONException e) {
e.printStackTrace();
}
}
return items;
}
You cannot put an array to JSON, but you can put a Collection, which is represented by a JSONArray (http://www.json.org/javadoc/org/json/JSONObject.html#put%28java.lang.String,%20java.util.Collection%29). So the correct way to put your array to JSONObject is:
obj.put("Stored_Ans", new JSONArray(this.storedAnswers));
and to get:
JSONArray jsonArray = jsonObject.getJSONArray("Stored_Ans");
String[] StoAnswer = new String[jsonArray.length()];
for(i = 0; i < jsonArray.length(); i++){
StoAnswer[i] = jsonArray.getString(i);
}

How can I store an integer array in SharedPreferences?

I want to save/recall an integer array using SharedPreferences. Is this possible?
You can try to do it this way:
Put your integers into a string, delimiting every int by a character, for example a comma, and then save them as a string:
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
int[] list = new int[10];
StringBuilder str = new StringBuilder();
for (int i = 0; i < list.length; i++) {
str.append(list[i]).append(",");
}
prefs.edit().putString("string", str.toString());
Get the string and parse it using StringTokenizer:
String savedString = prefs.getString("string", "");
StringTokenizer st = new StringTokenizer(savedString, ",");
int[] savedList = new int[10];
for (int i = 0; i < 10; i++) {
savedList[i] = Integer.parseInt(st.nextToken());
}
You can't put Arrays in SharedPreferences, but you can workaround:
private static final String LEN_PREFIX = "Count_";
private static final String VAL_PREFIX = "IntValue_";
public void storeIntArray(String name, int[] array){
SharedPreferences.Editor edit= mContext.getSharedPreferences("NAME", Context.MODE_PRIVATE).edit();
edit.putInt(LEN_PREFIX + name, array.length);
int count = 0;
for (int i: array){
edit.putInt(VAL_PREFIX + name + count++, i);
}
edit.commit();
}
public int[] getFromPrefs(String name){
int[] ret;
SharedPreferences prefs = mContext.getSharedPreferences("NAME", Context.MODE_PRIVATE);
int count = prefs.getInt(LEN_PREFIX + name, 0);
ret = new int[count];
for (int i = 0; i < count; i++){
ret[i] = prefs.getInt(VAL_PREFIX+ name + i, i);
}
return ret;
}
Here's my version, based on Egor's answer. I prefer not to use StringBuilder unless I'm building an enourmous string, but thanks to Egor for using StringTokenizer -- haven't made much use of this in the past, but it's very handy! FYI, this went in my Utility class:
public static void saveIntListPrefs(
String name, Activity activity, List<Integer> list)
{
String s = "";
for (Integer i : list) {
s += i + ",";
}
Editor editor = activity.getPreferences(Context.MODE_PRIVATE).edit();
editor.putString(name, s);
editor.commit();
}
public static ArrayList<Integer> readIntArrayPrefs(String name, Activity activity)
{
SharedPreferences prefs = activity.getPreferences(Context.MODE_PRIVATE);
String s = prefs.getString(name, "");
StringTokenizer st = new StringTokenizer(s, ",");
ArrayList<Integer> result = new ArrayList<Integer>();
while (st.hasMoreTokens()) {
result.add(Integer.parseInt(st.nextToken()));
}
return result;
}
I like to use JSON, which can be stored and retrieved as a string, to represent any complex data in SharedPreferences.
So, in the case of an int array:
public void setPrefIntArray(String tag, int[] value)
{
SharedPreferences.Editor prefEditor = PreferenceManager.getDefaultSharedPreferences(context)
.edit();
String s;
try
{
JSONArray jsonArr = new JSONArray();
for (int i : value)
jsonArr.put(i);
JSONObject json = new JSONObject();
json.put(tag, jsonArr);
s = json.toString();
}
catch(JSONException excp)
{
s = "";
}
prefEditor.putString(tag, s);
prefEditor.commit();
}
public int[] getPrefIntArray(String tag, int[] defaultValue)
{
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
String s = pref.getString(tag, "");
try
{
JSONObject json = new JSONObject(new JSONTokener(s));
JSONArray jsonArr = json.getJSONArray(tag);
int[] result = new int[jsonArr.length()];
for (int i = 0; i < jsonArr.length(); i++)
result[i] = jsonArr.getInt(i);
return result;
}
catch(JSONException excp)
{
return defaultValue;
}
}
The beauty is that the same idea can be applied to any other complex data representable as a JSON.
Two solutions:
(1) Use http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html
It has split/join functions that let you join and split the integers in one liners:
StringUtils.join([1, 2, 3], ';') = "1;2;3"
StringUtils.split("1;2;3", ';') = ["1", "2", "3"]
You'd still have to convert the strings back to integers, though.
Actually, for splitting java.lang.String.split() will work just as fine:
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String)
(2) Use the SharedPreferences.putStringSet() (API 11):
SharedPreferences.Editor editor = preferences.edit();
int count = this.intSet.size();
if (count > 0) {
Set<String> theSet = new HashSet<String>();
for (Long l : this.intSet) {
theSet.add(String.valueOf(l));
}
editor.putStringSet(PREFS_KEY, theSet);
} else {
editor.remove(PREFS_KEY);
}
editor.commit();
And to get it back:
Set<String> theSet = this.preferences.getStringSet(PREFS_KEY, null);
if (theSet != null && !theSet.isEmpty()) {
this.intSet.clear();
for (String s : theSet) {
this.intSet.add(Integer.valueOf(s));
}
}
This code does not catch the NPEs or NumberFormatExceptions because the intSet is otherwise assured to not contain any nulls. But of course, if you cannot assure that in your code you should surround this with a try/catch.
Here is how the "convert to comma-separated String" solution could look in Kotlin, implemented as extension functions:
fun SharedPreferences.Editor.putIntArray(key: String, value: IntArray): SharedPreferences.Editor {
return putString(key, value.joinToString(
separator = ",",
transform = { it.toString() }))
}
fun SharedPreferences.getIntArray(key: String): IntArray {
with(getString(key, "")) {
with(if(isNotEmpty()) split(',') else return intArrayOf()) {
return IntArray(count(), { this[it].toInt() })
}
}
}
That way you can use putIntArray(String, IntArray) and getIntArray(String) just like the other put and set methods:
val prefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
prefs.edit().putIntArray(INT_ARRAY_TEST_KEY, intArrayOf(1, 2, 3)).apply()
val intArray = prefs.getIntArray(INT_ARRAY_TEST_KEY)
I went for the below solution, it's the least verbose of what I could see in this thread (in my case I wanted to have a set as a collection). "value" is the of type Set<Int>.
Save:
sharedPreferences.edit {
if (value.isNotEmpty()) {
putStringSet(key, hashSetOf(*value.map { it.toString() }.toTypedArray()))
} else {
remove(key)
}
}
Retrieve:
val stringSet = sharedPreferences.getStringSet(key, null)
if (stringSet.isNullOrEmpty()) return emptySet()
return setOf<Int>(*stringSet.map { Integer.valueOf(it) }.toTypedArray())
You can only save primitive values in sharedPreference. Use Sqlite instead.

Categories

Resources