I am trying to learn retrofit and I have made successful attempts at posting data and now I am trying to retrieve JSON array which looks as follows:
{
"result": "success",
"message": "All Questions Have Been Selected",
"question": {
"all_question_ids": ["1","2","3"]
}
}
I am using the following getter
public ArrayList getAll_question_ids(){
return all_question_ids;
}
I am retrieving using Retrofit as follows
if (resp.getResult().equals(Constants.SUCCESS)) {
SharedPreferences.Editor editor = pref.edit();
Log.d("Question_IDs", "getAllQuestionID() = " + response.body().getQuestion().getAll_question_ids() );
editor.putString(Constants.All_QUESTION_IDS,((resp.getQuestion().getAll_question_ids().toString())));
editor.apply();
}
progress.setVisibility(View.INVISIBLE);
It is here that I am stuck, as I am retrieving the array ok but I am unsure how to loop out the Array which is now stored in Shared Preferences.
When I place a toast to show me how the IDs are coming across, my toast confirms the data as [1,2,3]
The goal is to add a dynamic button and the individual ID, i.e button 1, button 2 etc every-time the loop is iterated.
I have tried the following:
String questionNumber = pref.getString(Constants.All_QUESTION_IDS, "");
for (int i =0; i < questionNumber.length(); i++) {
try {
/*Dynamically create new Button which includes the question name
*/
AppCompatButton btn_question = new AppCompatButton(getActivity());
/*LayoutParams (int width, int height,float weight)
As LayoutParams is defaulted in px, I have called a method called dpToPX to make sure
the dynamically added EditText is the same size on all devices.
*/
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(dpToPx(280), dpToPx(45), 1);
btn_question.setBackgroundColor(Color.parseColor("#3B5998"));
btn_question.setTextColor(Color.WHITE);
// btn_question.setText(String.valueOf(x));
btn_question.setText("Question "+ pref.getString(Constants.All_QUESTION_IDS,""));
btn_question.setGravity(Gravity.CENTER);
//generate unique ID for each new EditText dynamically created
View.generateViewId();
//Log.d("TEST VALUE", "Question1 generated ID = " + btn_question.generateViewId());
params.setMargins(0, dpToPx(10), 0, dpToPx(10));
btn_question.setPadding(0, 0, 0, 0);
btn_question.setLayoutParams(params);
allEds.add(btn_question);
mLayout.addView(btn_question);
} catch (Exception e) {
Log.d(TAG, "Failed to create new edit text");
}
}
However the above is adding the value as it appears in the array e.g [1,2,3] which is obviously not what I want.
I have added a photo in case my explanation isn't clear. I want a button with 1 number added to it each time the loop iterates but I am unable to figure this out.
I have looked through lots of resource but cannot find an answer that is relevant to my problem, although, if there is, I am not familiar enough to recognise a similar issue.
If someone can offer some assistance, I would appreciate it!
When you call editor.putString(Constants.All_QUESTION_IDS,((SOMETHING.toString())));, what is actually stored depends on the implementation of the toString method in the type of SOMETHING (in this case String[]). So avoid doing that. Instead, since you're already using Gson or Jackson (or others), store the question_idsas JSON:
final String jsonIds = gson.toJson (resp.getQuestion().getAll_question_ids());
editor.putString(Constants.All_QUESTION_IDS, jsonIds);
Your actual stored value no longer depends on the implementation of something that you don't control (String[].toString). It is a valid JSON array and regardless of what tool/library you use to read it back, it's valid.
Now, to read back the stored data:
final String storedJson = pref.getString(Constants.All_QUESTION_IDS, null);
if (null == storedJson) {
// TODO: No question ids found
}
final String[] ids = gson.fromJson (storedJson, String[].class);
for (int i = 0; i < ids.length; i++) {
// make your buttons
}
This is a problem of saving and then reading out a List of items (in this case, String instances).
You've chosen to save the list by calling editor.putString() with a value of getAll_question_ids().toString(). That toString() call is going to return a string representation of your list, or, in other words, a String instance with the value [1, 2, 3]. At this point, you no longer have a List proper, but a String that looks like a list.
This is all technically fine, but it means you have to take this into account when you're trying to read out that list.
You've written this to read the list back out:
String questionNumber = pref.getString(Constants.All_QUESTION_IDS, "");
Once this line executes, questionNumber will be a String instance with the value [1, 2, 3]. Again, this is fine, but now we come to the key point: we have to convert this String back into a List.
If you know for sure that the values in this list won't have commas in them, you can do it easily:
Trim the braces off the string using substring()
Create a String[] using split()
Convert your array to a list using Arrays.asList() (you could even skip this step since iterating over an array is just as easy as iterating over a list)
Put that together and you get:
String questionNumber = pref.getString(Constants.All_QUESTION_IDS, "");
questionNumber = questionNumber.substring(1, questionNumber.length() - 1);
String[] array = questionNumber.split(", ");
List list = Arrays.asList(array);
At this point, you can iterate over your array or list:
for (String value : list) {
...
btn_question.setText("Question " + value);
...
}
I have a screen where the user selects items he/she wants deleted, then I store his/her choices into an integer arrayList (based on which positions they clicked on the listView).
I then pass the items that they want deleted to a function where I actually delete them from my hashtable that holds all the information. For some reason though, it's just NOT deleting from the hashtable. I've tested and looked at all the variables I'm using to access the data and they are correct. I'm not sure why it's not removing what I tell it to..
Here is the function:
for (Entry<Integer, ArrayList<Deck>> i : listOfDecks.entrySet()) {
for (int p = 0; p < i.getValue().size(); p++) {
if (i.getValue().get(p).getTitle().equals(deckTitle)) {
for (int z = 0; z < deletedItems.size(); z++) {
listOfDecks.get(i.getKey()).get(p).getDeck().remove(deletedItems.get(z));
}
}
}
}
deletedItems is the arrayList that holds what the user has selected as their items they want deleted.
What I see is that you are calling Deck.remove(int) so you're not removing from a hashtable, but from a deck.
What does this method remove(int) of the class Deck do?.
I receive data from a server using JSON and I want to order them alphabetically with alphabet indexed section and store them in a ListView.
Maybe something that will happen in :
for(int i=0;i<jArray.length();i++){
// here
}
I read that you can order elements like that only using a cursor. In my case would be very inefficient to store the elements from the server in the database and read them again. Waste of time and memory.
So, I am asking you if there could be any solution for my problem : order alphabetically with alphabet indexed section string received from JSON .
EDIT: I want my listview to look like this http://eshyu.wordpress.com/2010/08/15/cursoradapter-with-alphabet-indexed-section-headers/ . I mean with those sections . All tutorials I found said that you need to fetch information with a cursor. My question was if I could't do this wihout a cursor, because it would be a waste of memory to store them in the local database too.
You may need to parse the JSON Array :
List<Project> list = new ArrayList<Project>();
for (int i = 0; i < jArray.length(); i++) {
JSONObject obj = (JSONObject) jArray.get(i);
project = new Project();
project.setId( Long.parseLong(obj.get("id").toString()));
project.setKey(obj.get("key").toString());
project.setName(obj.get("name").toString());
list.add(project);
}
You can use the comparator class like this to sort them :
Collections.sort(list), new Comparator<Project>() {
public int compare(Project p1, Project p2) {
return p1.getKey().compareToIgnoreCase(p2.getKey());
}
});
You can also have Project class and implements Comparable:
public class Project implements Comparable<Project> {
private long id;
private String key;
private String name;
public int compareTo(Project p) {
if (this.key > p.key)
return -1;
else if (this.key < p.key)
return 1;
return 0;
}
}
And then sort the list by Collections.sort(list);
My suggestion is try to sort the data in the Server-side, because the memory of the phone is limited and it may make you application time consuming to show the data, but you do not have memory limitation problem in the Server-side.
use a comparator to sort the arraylist as described here . And then use an ArrayAdapter to show the items in Listview
I have to create an app in android with a database.In that database I have a predefined list of products.
Now,the thing is that my ap has to offer to the user the posibility to introduce in that list some other products which are not in the list.
To this end, I've created an autocomplete text view in which I introduce a new product and I take the text fro autocomplete and I have to write it in the database
Now,my problem is that when I display the products that I've introduced in the database,the toast text that I use to display what I have in the database it shows me nothing next to "product......".
Now,that may be because when I try to get the text from the autocomplete I get nothing in return?
This is how I read from autocomplete:
mItem = (AutoCompleteTextView) findViewById(R.id.todo_edit_item);
String nou=mItem.getText().toString();
And then I compare nou(which is what I wrote in the autocomplete) with what I have predefnied in the list,so if it is a new product(which was not in the list already) the I add it in the database:
for(int i = 0; i < l; i++)
{
if (nou!=fruits[i])
t=true;
else t=false;
}
if (t==true)
{
db.insertTitle(nou);
fruits=db.getAllfromDB("Fruits","fruit");
l=l+1;
}
Anyone any ideas of what I'm doing wrong in here cause I can't figure out.I'lll be here for further details.Thank u in advance:)
You compare strings using != instead of using !nou.equals(fruits[i]). also you compare to all elements in array each time, since you so t is always the value of the comparison to the last element in the array whether a match was found or not.
It should be written like that:
t = true;
for(int i = 0; i < l; i++)
{
if (nou.equals(fruits[i]))
{
t=false;
break;
}
}
if (t==true)
{
db.insertTitle(nou);
fruits=db.getAllfromDB("Fruits","fruit");
l=l+1;
}
So I've got the following:
NodeList nodeList = element.getElementsByTagName("rowset");
if (nodeList.getLength() > 0) {
for (int i = 0; i < nodeList.getLength(); i++) {
Element entry = (Element) nodeList.item(i);
Element _titleE = (Element) entry.getElementsByTagName("row").item(0);
Node _title = _titleE.getAttributes().getNamedItem("name");
t1.setText(_title.getNodeValue());
}
}
I've got the following XML layout:
<row name="" characterID="" corporationName="" corporationID="" />
(couple of lines of these)
the ideal way would be to create an array right? and then call the data from the array?
EDIT:
What I'm trying to do is read an XML File and store the values so that they can be accessed later so I'm assuming the ideal way would be to use an array?
(as my girlfriends name is jenny, too, I will be guessing what you want)
If you just want to store one value, an array or a ArrayList is good for that. If you need to store all 4 given attributes of your row, you should think about creating a class (lets call it MyRow) that contains those values. Than you can put all your rows into one ArrayList with the type of your class.
Pseudocode:
ArrayList<MyRow> myRowList = new ArrayList<MyRow>();
while reading each row
MyRow row = new MyRow();
row.mName = getAttributes().getNamesItem("name");
row.mCharacterId = getAttributes().getNamesItem("characterID");
// more setting...
}
A last tip for the next time: take some time to explain and specify your next question. That will improve the answers you get as well.