I used AndroidBegin guide to populate my ListView with data from Parse.com table (http://www.androidbegin.com/tutorial/android-parse-com-simple-listview-tutorial/) and it shows an empty ListView.
// RemoteDataTask AsyncTask
private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Create a progressdialog
mProgressDialog = new ProgressDialog(QuestionsList.this);
// Set progressdialog title
mProgressDialog.setTitle("Parse.com Simple ListView Tutorial");
// Set progressdialog message
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
// Show progressdialog
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// Locate the class table named "Country" in Parse.com
if (AnswerActivity.friend.isEmpty()) {
if (AnswerActivity.wantedTop == AnswerActivity.all) {
// Locate the class table named "Info" in Parse.com
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("Info");
// Locate the column named "Views" in Parse.com and order list by ascending
query.orderByDescending("Views");
try {
ob = query.find();
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
} else {
// Locate the class table named "Info" in Parse.com
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("Info");
// Search for the wanted topic
query.whereContains("User_Topic", AnswerActivity.wantedTop);
// Locate the column named "Views" in Parse.com and order list by ascending
query.orderByDescending("Views");
try {
ob = query.find();
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
} else {
if (AnswerActivity.wantedTop == AnswerActivity.all) {
// Locate the class table named "Info" in Parse.com
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("Info");
// Search for the wanted topic
query.whereContains("User_Name", AnswerActivity.friend);
// Locate the column named "Views" in Parse.com and order list by ascending
query.orderByDescending("Views");
try {
ob = query.find();
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
} else {
// Locate the class table named "Info" in Parse.com
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("Info");
// Search for the wanted topic
query.whereContains("User_Topic", AnswerActivity.wantedTop);
query.whereContains("User_Name", AnswerActivity.friend);
// Locate the column named "Views" in Parse.com and order list by ascending
query.orderByDescending("Views");
try {
ob = query.find();
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
}
}
#Override
protected void onPostExecute(Void result) {
// Locate the listview in listview_main.xml
listview = (ListView) findViewById(R.id.listview);
// Pass the results into an ArrayAdapter
adapter = new ArrayAdapter<String>(QuestionsList.this,
R.layout.listview_item);
// Retrieve object "name" from Parse.com database
for (ParseObject country : ob) {
adapter.add((String) country.get("name"));
}
// Binds the Adapter to the ListView
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
// Capture button clicks on ListView items
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// Send single item click data to SingleItemView Class
Intent i = new Intent(QuestionsList.this,
SingleItemView.class);
// Pass data "name" followed by the position
i.putExtra("name", ob.get(position).getString("name")
.toString());
// Open SingleItemView.java Activity
startActivity(i);
}
});
}
}
Later, I used ParseQueryAdapter tutorial, but still, it doesn't work.
Someone knows how to do it?
make a parse query factory
ParseQueryAdapter.QueryFactory<Post> factory;
factory = new ParseQueryAdapter.QueryFactory<Post>() {
#Override
public ParseQuery<Post> create() {
ParseQuery query = new ParseQuery("YourParseObject");
return query;
}
};
make a parse query adapter
private ParseQueryAdapter<Post> adapter;
adapter = new ParseQueryAdapter<Post>(this, factory) {
#Override
public View getItemView(final Post object, View v, ViewGroup parent) {
if (v == null) {
v = View.inflate(getContext(), R.layout.post_item, null);
}
return v;
}
};
adapter.setPaginationEnabled(true);
adapter.setTextKey("title");
adapter.setImageKey("Image");
adapter.loadObjects();
ListView your_list_view = (ListView) findViewById(R.id.list);
your_list_view.setAdapter(adapter);
done, now objects are in a list
make sure that you have a sperate xml file for each parseobject, here i have it labaled as (R.id.post_item)
You really don't need an AsyncTask for that...
Just create your query, invoke findInBackGround() which will create a Async for you, and on the callback, populate your listview.
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> results, ParseException e) {
if (results != null && results.size() > 0) {
YourAdapter adapter = new YourAdapter(context, results);
list.setAdapter(adapter);
Alternatively, if you want to use a ParseQueryAdapter, it's even simpler:
// create your query before, but do no call findInBackground.
YourParseQueryAdapter adapter = new YourParseQueryAdapter(context, new ParseQueryAdapter.QueryFactory<ParseObject>() {
public ParseQuery<ParseObject> create() {
return query;
}
});
list.setAdapter(adapter);
Have a good read at the documentation again in case of any issues
Hope this helps!
Related
I'm new to android and I need help in retrieving the array that I created in parse server named as "busStops" but I can't figure out where the problem exists in my code
ParseQuery<ParseObject> parseQuery = new ParseQuery<ParseObject>
("RouteDetails");
parseQuery.whereEqualTo("routeNumber",searchView.getText().toString());
parseQuery.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> busStops, ParseException e) {
if(e == null){
final List<String> arrayList = new ArrayList<>();
for (ParseObject parseObject : busStops){
if (parseObject.getList("busStops") != null) {
arrayList.add(parseObject.getList("busStops").toString());
}
}
arrayAdapter = new ArrayAdapter(SearchForRoutes.this,android.R.layout.simple_list_item_1,arrayList);
listView.setAdapter(arrayAdapter);
}
}
});
It is possible to show an Array in a ListView. You should use getJSONArray instead of getList in your JAVA code. See my code below.
My structure class is:
Then, I added the code below into my Activity (MainActivity.java):
final ListView listView = (ListView) findViewById(R.id.listviewA);
ParseQuery<ParseObject> query = ParseQuery.getQuery("RouteDetails");
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> results, ParseException e) {
if (e == null) {
for(int i = 0; i < results.size(); i++) {
JSONArray array = results.get(i).getJSONArray("busStop");
for(int j = 0; j < array.length(); j++) {
try {
dataList.add(array.getString(j));
} catch (JSONException e1) {
e1.printStackTrace();
}
}
myArray = dataList.toArray(new String[dataList.size()]);
ArrayAdapter<String> adapterList
= new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_single_choice, myArray);
listView.setAdapter(adapterList);
}
} else {
final Toast toast = Toast.makeText(
MainActivity.this,
String.valueOf("Error =>" + e.getMessage()),
Toast.LENGTH_LONG
);
toast.show();
}
}
});
And the result will be something like as this:
First of all, you may don't need to create another ArrayList than the list that is returned by parseObject.getList("busStops"). You can directly pass it to the adapter constructor. But since you may want to do a process on the list, iterate the list like :
for(Object s : parseObject.getList("busStops") { String current = s.toString(); }
Also you can save the list to another ArrayList by passing it to ArrayList constructor.
ArrayList<String> al = new ArrayList<>(parseObject.getList("busStops"))
And finally, you can fix your code (that is worst-practice :) ) by simply deleting the .toString() from the line in your none-null if statement and changing add to addAll.
like this : arrayList.addAll(parseObject.getList("busStops"));
I am trying to populate an Array from a parse.com query and I am stock in the part of getting the element from query. basically i dont know where to get the current location for exercise_object.get(location) thanks.
ParseQuery<ParseObject> query = ParseQuery.getQuery("Programs");
query.whereEqualTo("name", objname);
query.orderByAscending("name");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> list, ParseException e) {
if (e == null) {
//success
String [] exercice = new String[3];
exercise_object = list;
Toast.makeText(Wko_Display.this, "Workouts", Toast.LENGTH_LONG).show();
ParseObject program_object = exercise_object.get(location);
exercice [0] = exercise_object.getString("wk0");
exercice [1] = exercise_object.getString("wk1");
exercice [2] = exercise_object.getString("wk2");
}
If I understand what you're trying to do correctly, then this should work:
#Override
public void done(List<ParseObject> list, ParseException e){
if (e == null){
for (ParseObject pObj : list){
String[] exercise = new String[3];
// assuming each ParseObject has a pointer to a Program object in the database
ParseObject programObject = pObj.getParseObject("location");
// do whatever you want with this programObject
// then do any further stuff with the current pObj in the list
exercise[0] = pObj.getString("wk0");
// ...
}
} else{
Log.e(TAG, e.getMessage());
}
}
This would be wrong if you're expecting only one object to be returned from the query though. Let me know.
I have an AsyncTask that loads all my data on parse.com, then the user has a checkbox to select the categories he wants to display.
Once I get those choices (from a separate class via an interface), I reload the asyncTask, but It still lists everything (like if the array of choices gets erased/reloaded).
here is my code to get the selected categories :
#Override
public void onOkay(ArrayList<Integer> selected) {
StringBuilder stringBuilder = new StringBuilder();
if (selected.size() != 0) {
for (int i = 0; i < selected.size(); i++) {
String categories = selectedArray[selected.get(i)];
stringBuilder = stringBuilder.append(", " + categories);
}
//this is to display the content of the selectedArray :
Toast.makeText(this, "You have selected: "
+ stringBuilder.toString(), Toast.LENGTH_SHORT).show();
//reloading the AsyncTask class :
new RemoteDataTask().execute();
}
}
My AsyncTask :
private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
//timer and progressdialog...
}
#Override
protected Void doInBackground(Void... params) {
list_of_articles = new ArrayList<Articles>();
try {
// Locate the class table named "Article" in Parse.com
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
"Article");
query.whereWithinKilometers("Localisation_Vendeur", device_location, rayon);
//this is the query I use :
query.whereContainedIn ("Category",Arrays.asList(selectedArray));
ob = query.find();
for (ParseObject article : ob) {
// Locate images in article_image column
ParseFile image = (ParseFile) article.get("label1");
Articles map = new Articles();
map.setArticle_label1((String) article.get("label2"));
map.setArticle_label2((String) article.get("label3"));
map.setArticle_category((String) article.get("Category"));
map.setArticle_label4((String) article.get("label4"));
map.setArticle_image(image.getUrl());
list_of_articles.add(map);
}
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
listview = (ListView) findViewById(R.id.listview);
// Pass the results into ListViewAdapter.java
adapter = new ListViewAdapter(MainActivity.this,
list_of_articles);
// Binds the Adapter to the ListView
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
}
}
How can I make that work ? Keep in mind that the query works, i've tested with an array that i filled manually and it works.
Thanks.
You should pass categories that user wants to display as arguments to AsyncTask through AsyncTask.execute(Params... params). They will be available in AsyncTask.doInBackground method as that method parameters. Use them inside doInBackgorund method to set your query appropriately.
private class RemoteDataTask extends AsyncTask<List<String>, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
//timer and progressdialog...
}
#Override
protected Void doInBackground(List<String>... params) {
list_of_articles = new ArrayList<Articles>();
try {
// Locate the class table named "Article" in Parse.com
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
"Article");
query.whereWithinKilometers("Localisation_Vendeur", device_location, rayon);
//this is the query I use :
query.whereContainedIn ("Category", params[0]);
ob = query.find();
for (ParseObject article : ob) {
// Locate images in article_image column
ParseFile image = (ParseFile) article.get("label1");
Articles map = new Articles();
map.setArticle_label1((String) article.get("label2"));
map.setArticle_label2((String) article.get("label3"));
map.setArticle_category((String) article.get("Category"));
map.setArticle_label4((String) article.get("label4"));
map.setArticle_image(image.getUrl());
list_of_articles.add(map);
}
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
listview = (ListView) findViewById(R.id.listview);
// Pass the results into ListViewAdapter.java
adapter = new ListViewAdapter(MainActivity.this,
list_of_articles);
// Binds the Adapter to the ListView
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
}
}
Then in code run AsyncTask by calling new RemoteDataTask().execute(Arrays.asList(selectedArray)). Make sure that selectedArray is updated properly before every call of AsyncTask.
I develop a message application using parse.com, there is a few class my data browser in parse com.
If class type custom, i can bind data's in column to my list view. Is class type User or Installation, i can't get my datas and bind to listview. I guess there is a security rule about this. well, how can i get values for "User" and "Installation" class type?
there is my codes, what can i add this?
#Override
protected Void doInBackground(Void... params) {
// Locate the class table named "User" in Parse.com
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
"User");
//query.orderByDescending("_created_at");
try {
ob = query.find();
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// Locate the listview in listview_main.xml
listview = (ListView) findViewById(R.id.listview);
// Pass the results into an ArrayAdapter
adapter = new ArrayAdapter<String>(MainActivity.this,
R.layout.listview_item);
// Retrieve object "name" from Parse.com database
for (ParseObject users : ob) {
adapter.add((String) users.get("username"));
}
// Binds the Adapter to the ListView
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
// Capture button clicks on ListView items
listview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// Send single item click data to SingleItemView Class
Intent i = new Intent(MainActivity.this,
SingleItemView.class);
// Pass data "username" followed by the position
i.putExtra("username", ob.get(position).getString("username")
.toString());
// Open SingleItemView.java Activity
startActivity(i);
}
});
}
The User objects are private, quick google search gave me this: https://parse.com/questions/how-can-i-find-parse-users-that-are-facebook-friends-with-the-current-user
Also you can only get your own installation object.
If you only need to list the users for the purpose of, say, Highscores, you could create a Highscore object containing:
username, score
When saving a score you can add a score column to you User or Parseinstallation depending on your needs. This way a user can easily get a reference to his own highscores. Make sure it has no ACL that makes it publically unreadable.
Now you are free to query the Highscores object.
Long answer short, factor out the things you wish to query in it's own object and add a reference to the user/installation.
Or perhaps even easier, the other way around, keeping a reference to the owner in the highscore:
username, score, owner
I am pretty confident that you are allowed to get the objectId of owner, whether it is user or installation. So a query like 'find Highscores where owner.objectId.equals(myUser.objectId)' should be valid.
Here is a snippet of my application. I have an option to save settings (sharedpreferences) in a parse.com object, thus sharing profiles between devices (parse is an object that I have implemented my self as a controller for all parse centric code, just not to be confused with anything from the parse library itself):
private void create() {
cat.removeAll();
switchPrefs = new ArrayList<SwitchPreference>();
currentProfile = parse.getParseProfile().getProfile();
parse.getParseProfile().getProfiles(new FindCallback<ParseObject>() {
#Override public void done(List<ParseObject> objects,
ParseException e) {
if (e == null) {
profiles = objects;
for (ParseObject profile : profiles) {
addProfile(profile);
}
}
}
});
}
private void addProfile(ParseObject profile) {
SwitchPreference switchPref = new SwitchPreference(getActivity());
switchPref.setTitle(profile.getString(ParseObjectHelper.Profile.name));
switchPref.setOrder(switchPrefs.size());
// switchPref.setKey(String.valueOf(profiles.size()));
if (currentProfile != null
&& profile.getObjectId().equals(currentProfile.getObjectId())) {
switchPref.setChecked(true);
} else {
switchPref.setChecked(false);
}
switchPref.setOnPreferenceChangeListener(new OnProfileChanged());
cat.addPreference(switchPref);
switchPrefs.add(switchPref);
if (!profiles.contains(profile)) {
profiles.add(profile);
}
}
So for each profile found attached to the current user adds a SwitchPreference.
Here is the code for getProfiles(..):
public void getProfiles(FindCallback<ParseObject> callback) {
ParseQuery<ParseObject> query = ParseQuery
.getQuery(ParseObjectHelper.Profile.objectname);
query.whereEqualTo(ParseObjectHelper.Profile.owner, parseUser);
query.findInBackground(callback);
}
To create a new Profile I do the following:
public void createProfile(final String profilename,
final GetCallback<ParseObject> callback) {
final ParseObject newProfile = new ParseObject(
ParseObjectHelper.Profile.objectname);
newProfile.put(ParseObjectHelper.Profile.name, profilename);
// the users ParseUser object
newProfile.put(ParseObjectHelper.Profile.owner, parseUser);
Map<String, ?> preferences = PreferenceManager
.getDefaultSharedPreferences(context).getAll();
for (String key : preferences.keySet()) {
if (key.startsWith("key")) {
newProfile.put(key, preferences.get(key));
}
}
newProfile.saveEventually(new SaveCallback() {
#Override public void done(ParseException e) {
callback.done(newProfile, e);
}
});
}
In the following code I search HighScore class for the best time results ordered by ascending.
So I'm getting list of best results.
What I having a difficulty is to add the name and the school name to of each time result to the list.(please see the attached images)
private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
// Override this method to do custom remote calls
protected Void doInBackground(Void... params) {
// Gets the current list of bestTime in sorted order
ParseQuery query = new ParseQuery("TestsTopRecords");
query.orderByAscending("bestTime");
try {
results = query.find();
} catch (ParseException e) {
}
return null;
}
#Override
protected void onPreExecute() {
HighScoreTable.this.progressDialog = ProgressDialog.show(HighScoreTable.this, "",
"Loading...", true);
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Void result) {
// Put the list of results into the list view
ArrayAdapter<Double> adapter = new ArrayAdapter<Double>(HighScoreTable.this,R.layout.todo_row);
for (ParseObject object : results) {
adapter.add((Double) object.get("bestTime"));
}
setListAdapter(adapter);
HighScoreTable.this.progressDialog.dismiss();
TextView empty = (TextView) findViewById(android.R.id.empty);
empty.setVisibility(View.VISIBLE);
}
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_high_score_table);
TextView empty = (TextView) findViewById(android.R.id.empty);
empty.setVisibility(View.INVISIBLE);
new RemoteDataTask().execute();
registerForContextMenu(getListView());
}
Here's probably the simplest hack to do this.
Use String instead of Double and do this
ArrayAdapter<String> adapter = new ArrayAdapter<String>(HighScoreTable.this,R.layout.todo_row);
for (ParseObject object : results) {
adapter.add((Double) object.get("bestTime") + " " + object.getString("Name") + " " + object.getString("SchoolAndCity"));
}