Android and parse - android

i made a listview with all the posts in the list.
what i want is when i click the child in the list i want another activity to be opened showing that specific post and the related comments
the question is how to know which item is clicked and how to show that particular post ParseObject in next activity
as they do in messaging app in which you click the message from the listview and subsequent messages are shown in the next activity
i might be very thankful to you if you solve this for me!!

Please Try this code:
Please implement your object class with Serializable
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position,
long arg3) {
try
{
Log.v("position",position); // hear is your list item position
MyClass obj = new MyClass(); // Class must be implements with Serializable
Intent showintent = new Intent(context,<activity class to open>);
showcontactintent.putExtra("obj",obj);
startActivity(showintent);
}
catch(Exception e)
{
e.printStackTrace();
}
}
});

Use: Relational Data
Objects can have relationships with other objects. To model this behavior, any ParseObject can be used as a value in other ParseObjects. Internally, the Parse framework will store the referred-to object in just one place, to maintain consistency.
For example, each Comment in a blogging app might correspond to one Post. To create a new Post with a single Comment, you could write:
// Create the post
ParseObject myPost = new ParseObject("Post");
myPost.put("title", "I'm Hungry");
myPost.put("content", "Where should we go for lunch?");
// Create the comment
ParseObject myComment = new ParseObject("Comment");
myComment.put("content", "Let's do Sushirrito.");
// Add a relation between the Post and Comment
myComment.put("parent", myPost);
// This will save both myPost and myComment
myComment.saveInBackground();
You can also link objects using just their objectIds like so:
// Add a relation between the Post with objectId "1zEcyElZ80" and the comment
myComment.put("parent", ParseObject.createWithoutData("Post", "1zEcyElZ80"));
By default, when fetching an object, related ParseObjects are not fetched. These objects' values cannot be retrieved until they have been fetched like so:
fetchedComment.getParseObject("post")
.fetchIfNeededInBackground(new GetCallback<ParseObject>() {
public void done(ParseObject post, ParseException e) {
String title = post.getString("title");
// Do something with your new title variable
}
});
You can also model a many-to-many relation using the ParseRelation object. This works similar to List, except that you don't need to download all the ParseObjects in a relation at once. This allows ParseRelation to scale to many more objects than the List approach. For example, a User may have many Posts that they might like. In this case, you can store the set of Posts that a User likes using getRelation. In order to add a post to the list, the code would look something like:
ParseUser user = ParseUser.getCurrentUser();
ParseRelation<ParseObject> relation = user.getRelation("likes");
relation.add(post);
user.saveInBackground();
You can remove a post from the ParseRelation with something like:
relation.remove(post);
For more read: https://parse.com/docs/android/guide#objects-relational-data
^why did I copy all the words here instead of just providing the link? Because parse links are broken sometimes and doesn't direct you to the section you need (instead it just sends you to https://parse.com/docs/android/guide and because the doc is so large, you won't be able to find it.

Related

How to update an element in Adapter list once changes have been made to the element in a different Activity?

I'm looking for the best implementation pattern in Android to update a list when one of the elements change in a different activity.
Imagine this user journey:
An async process fetches ten (10) contact profiles from a web server. These are placed in an array and an adapter is notified. The ten (10) contact profiles are now displayed in a list.
The user clicks on contact profile five (5). It opens up an activity with details of this contact profile. The user decides they like it and clicks 'add to favourite'. This triggers an async request to the web server that the user has favourited contact profile five (5).
The user clicks back. They are now presented again with the list. The problem is the list is outdated now and doesn't show that profile five (5) is favourited.
Do you:
Async call the web server for the updated data and notify the adapter to refresh the entire list. This seems inefficient as the call for the list can take a couple of seconds.
On favouriting the profile store the object somewhere (perhaps in a singleton service) marked for 'refresh'. OnResume in the List activity do you sniff the variable and update just that element in the list.
Ensure the list array is static available. Update the array from the detail activity. OnResume in the activity always notify the adapter for a refresh.
Ensure the list array and adapter is static available. Update the array and notify the adapter from the detail activity.
Any other options? What is the best design principle for this?
Async call the web server for the updated data and notify the adapter
to refresh the entire list. This seems inefficient as the call for the
list can take a couple of seconds.
As you say, it's very inefficient. Creating an Object is expensive in Android. Creating a List of many object is much more expensive.
On favouriting the profile store the object somewhere (perhaps in a
singleton service) marked for 'refresh'. OnResume in the List activity
do you sniff the variable and update just that element in the list.
This is not a good solution because there is a probability that the app crashes before we refresh the object or the app get killed by the device.
Ensure the list array is static available. Update the array from the
detail activity. OnResume in the activity always notify the adapter
for a refresh.
Updating the array via a static method or variable is not a good solution because it makes your detail Activity get coupled with the list. Also, you can't make sure that only the detail activity that change the list if your project get bigger.
Ensure the list array and adapter is static available. Update the
array and notify the adapter from the detail activity.
Same as the above, static variable or object is a no go.
You better use an Event Bus system like EventBus.
Whenever you clicks 'add to favourite' in detail activity, send the async request to update favourite to the web server and also send Event to the list activity to update the specific profile object. For example, if your profile has id "777" and the profile is favourited in detail activity then you need to send the Event something like this in your :
btnFavourite.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Send event when click favourite.
EventBus.getDefault.post(new RefreshProfileEvent(id, true);
}
});
RefreshProfileEvent is a simple pojo:
public class RefreshProfileEvent {
private String id;
private boolean isFavourited;
public RefreshProfileEvent(String id, boolean isFavourited) {
this.id = id;
this.isFavourited = isFavourited;
}
//getter and setter
}
Then you can receive the Event in your list activity to update the selected profile:
public class YourListActivity {
...
#Override
protected onCreate() {
...
EventBus.getDefault().register(this);
}
#Override
protected onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(RefreshProfileEvent event) {
// Refresh specific profile
// For example, your profile is saved in List<Profile> mProfiles
// Search for profile by its id.
for(int i = 0; i < mProfiles.size(); i++) {
if(mProfiles.getId().equals(event.getId()) {
// Refresh the profile in the adapter.
// I assume the adapter is RecyclerView adapter named mAdapter
mProfiles.get(i).isFavourited(true);
mAdapter.notifyItemChanged(i);
// Stop searching.
break;
}
}
}
You don't need to wait for AsyncTask request result returned by the server. Just make the profile favourited first and silently waiting for the result. If your request success, don't do anything. But if the request error, make the profile unfavourited and send unobstructive message like SnackBar to inform the user.
Third option is the best when a user changes the data in detail activity the array should be changed and then when the use returns to main activity call Adapter.notifyDataSetChanged(); will do the trick
For an ArrayAdapter , notifyDataSetChanged only works if you use the add() , insert() , remove() , and clear() on the Adapter.
You can do something like this:
#Override
protected void onResume() {
super.onResume();
Refresh();
}
public void Refresh(){
items = //response....
CustomAdapter adapter = new CustomAdapter(MainActivity.this,items);
list.setAdapter(adapter);
}
On every onResume activity it will refresh the list. Hope it helps you.

ParseQuery for profile picture while displaying post

I am working on a sample app like Instagram in parse.com.Each post displays the profile picture(resized)of the uploader and the post photo.The user info is stored in a different class "_user" containing the profile picture in "profileimage" and the posts are stored in a different class "Posts".How to make a query to fetch them both (in a single query to reduce payload).The thing I have tried so far.I want to know what to add in my query.
ParseQuery<ParseObject> query=ParseQuery.getQuery("testing");
query.orderByAscending("createdAt");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> arg0, ParseException arg1) {
for(ParseObject obj:arg0){
ParseFile pfile=obj.getParseFile("Image");
coaching coach=new coaching();
coach.setId(obj.getObjectId());
coach.setName(obj.getString("Name"));
coach.setPlace(obj.getString("Place"));
coach.setImageurl(pfile.getUrl());
array.add(coach);
}
listView.setAdapter(new parseadapter());
}
});
What you're looking for is a relation, specifically a ParseRelation. You'll have to add a Pointer from your "Posts" class to your "Users" class. Do note that you add the user as a Pointer using their objectId. Something like:
Next you have to add the following code your query to include the Pointer object because by default the SDK does not.
query.include("postAuthor"); //your column name for pointer
Lastly you have to fetch the ParseObject containing the User data separately (in your loop)
ParseObject author = obj.getParseObject("postAuthor"); // column name for pointer
ParseFile authorPicture = author.getParseFile("profileimage"); // column user profile picture
authorPicture.getUrl(); // profile picture URL
author.getString("name"); // name of the user
Consider fetching the name of the user who posted* as I have above, this is a better database design and will correspond to changes made to the name of a user.
I hope this helps you and others stuck in similar situations. You can read more about ParseRelation here.

Generalized Android Activity

I am new to Android programming. My question is that i have a list (ListView) of 8 restaurant headings. Upon clicking of any of these, a new page (activity) would start containing the menu and details of the restaurant. I understand that implementing 8 activities would be wasteful so probably i will have a general restaurant detail activity.
Now i am figuring out how to display this information out in an efficient way. I have so far implemented this which helps me to send a message across to the other activity according to the restaurant selected. But how can i send big chunks of information:
----MainActivity.java------
String [] restaurants = {"abc","def"....};
int POSITION_ACT;
list.setOnItemClickListener(new AdapterView.OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
POSITION_ACT=position;
customActivity(view);
}
});
public void customActivity(View view) {
Intent intent = new Intent(this, RestaurantDetails.class);
intent.putExtra(MESSAGE, "You clicked this restaurant: " + restaurants[POSITION_ACT]);
startActivity(intent);
}
--generalrestaurant.java----
Intent intent = getIntent();
String msg = intent.getStringExtra(foodActivity.MESSAGE);
TextView tt1 = (TextView) findViewById(R.id.tt1);
tt1.setText(msg);
You shouldn't be passing lots of information. Your model information should be in instances of a Restaurant class. Then you can keep all those instances in an ArrayList in a singleton. Write a getter for the singleton that returns a Restaurant instance and then call it from the RestaurantDetails activity using the extra you sent (maybe you want to make this a UUID). Finally, when the activity dies, you should save the Restaurant data from the singleton to a raw XML file or something and read it back in when the app starts up again.
You can create a POJO for your restaurant information and write data like Name, Location, Per head cost, rating etc to it. Then your POJO must implement Serializable or Parcelable. In your intent you can pass your POJO using intent.putExtra(String, Serializable) or intent.putExtra(String, Parcelable). In your second activity you can get the object and display your data in your Activity. Have a look at the below links :
http://developer.android.com/reference/java/io/Serializable.html
http://developer.android.com/reference/android/os/Parcelable.html

How do I create groups of ParseUsers using Parse.com?

Currently I'm using Parse.com in order to create multiple ParseUsers. This works perfectly and each user can login individually. However from here I want to expand my app to allow Users to create groups of users and therefore have data that is only relevant and shared between these Users. This will mean that when the User logs in, they can see a List of the groups they are members of and from there can share data simply just to those users of that individual group. What would be the best way to tackle this and does anybody have any examples or tutorials that I could follow in order to understand this concept?
I've considered creating a Group class and then making this store User's IDs in an array and then allow each User to store an array of the Group IDs that they're currently members of. I'm just not really sure how to broach this issue.
Thanks in advance!
I ended up doing as shown below:
ParseQuery<ParseRole> query = ParseRole.getQuery();
Intent intent = getActivity().getIntent();
String groupId = intent.getStringExtra("groupId");
query.whereEqualTo("objectId", groupId);
groupUsers = new ArrayList<String>();
query.findInBackground(new FindCallback<ParseRole>() {
#Override
public void done(List<ParseRole> objects, ParseException e) {
if(e == null) {
for(ParseRole role : objects) {
ParseRelation<ParseUser> usersRelation = role.getRelation("users");
ParseQuery<ParseUser> usersQuery = usersRelation.getQuery();
usersQuery.findInBackground(new FindCallback<ParseUser>() {
#Override
public void done(List<ParseUser> objects, ParseException e) {
for(ParseUser user : objects) {
groupUsers.add(user.getUsername());
}
}
});
}
} else {
Toast.makeText(getActivity(), "ERROR", Toast.LENGTH_SHORT).show();
}
}
});
I passed in the group ID from the Intent that sent me to that Fragment that I was checking and then populated my ListView with the list that I've returned from the query on the Parse database with the specific group ID. I hope this helps anyone else who had the same issue as me. Good luck!
Since you probably want to use it for security as well as making it easier for code/users, look at the Roles security feature.
You can add/remove Users from Roles, and assign ACL permissions to Roles instead of Users. This way when people are added-to/removed-from the Role the permissions don't require any changes.
Initially there was a limit to the number of Roles you were allowed to create based on account type, but this restriction was removed last year I believe.

Adding items to Array List with specified objects

I am working in a translator kind of app and i need some help.
I have a class with getters and setters for my Array List objects. Each object has a phrase, a meaning, and usage.
so i have this to create my list:
ArrayList<PhraseCollection> IdiomsList = new ArrayList<PhraseCollection>();
now how do i add these objects to the list, each object containing the phrase, its meaning, and a use in a sentence?
For Example: The Layout would be something like this
Phrase
Kick the bucket
Meaning
When someone dies
Usage
My grandfather kicked the bucket
Thanks a lot
this is what i came up with that worked for me
private void loadIdioms() {
//creating new items in the list
Idiom i1 = new Idiom();
i1.setPhrase("Kick the bucket");
i1.setMeaning("When someone dies");
i1.setUsage("My old dog kicked the bucket");
idiomsList.add(i1);
}
ArrayList has a method call add() or add(ELEMENT,INDEX);
In order to add your objects you must first create them
PhraseCollection collection=new PhraseCollection();
then create the ArrayList by
ArrayList<PhraseCollection> list=new ArrayList<PhraseCollection>();
add them by :
list.add(collection);
Last if you want to render that in your ListView item, you must override the toString() in your PhraseCollection.
I suppose you would use the add(E) method (http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html#add(E)).
Here is an example using your example provided.
public class Phrase {
public final String phrase, meaning, usage;
//TODO: implement getters?
public Phrase(String phrase, meaning, usage) {
this.phrase = phrase;
this.meaning = meaning;
this.usage = usage;
}
}
and use it like this:
// create the list
ArrayList<Phrase> idiomsList = new ArrayList<Phrase>();
// create the phrase to add
Phrase kick = new Phrase("kick the bucket", "When someone dies", "My grandfather kicked the bucket");
// add the phrase to the list
idiomsList.add(kick);

Categories

Resources