Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting Parse Object ID from onListItemClick

I am currently working on an app which contains a friends list when logged in and user profiles. When the user clicks on a friend in the friends list, I would like them to be directed to a profile page for this friend. To do this, I have been trying to extract the specific object id from the user that is clicked on in the list view and then pass that onto the next activity where I use it to run a query for all the users other attributes (name, email, hometown, etc.). I have figured out how to pass along data through intents but I am having all sorts of trouble obtaining the user id from the list item clicked. My onItemCLick code is below.

```

public void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);

    ParseObject item = (ParseObject) l.getAdapter().getItem(position);
    String objectID = item.getObjectId().toString();

    Intent intent = new Intent(getActivity(), FriendsProfileActivity.class);
    intent.putExtra("ID", objectID);
    startActivity(intent);

```

I have also tried something of this sort to not avail.

```

public void onListItemClick(ListView l, View v, int position, long id) {
     super.onListItemClick(l, v, position, id);

     ParseObject item = (ParseObject) l.getAdapter().getItem(position);
     item.saveInBackground(new SaveCallback() {
         @Override
         public void done(ParseException e) {
             if(e == null) {
                 String objectID = item.getObjectId();
                 Log.e(TAG, objectID);

                 Intent intent = new Intent(getActivity(), FriendsProfileActivity.class);
                 intent.putExtra("ID", objectID);
                 startActivity(intent);
                }
                else {
                    Log.e(TAG, e.getMessage());
                }
            }
        });

    }

```

In both cases, the app crashes when I click on the user in the list view. How can I succesfully pull the object ID from the user clicked on and pass it along?

Edit: Here is the logcat error.

Process: com.richluick.ribbit, PID: 2194 java.lang.ClassCastException: java.lang.String cannot be cast to com.parse.ParseObject at com.richluick.ribbit.FriendsFragment.onListItemClick(FriendsFragment.java:83) at android.support.v4.app.ListFragment$2.onItemClick(ListFragment.java:58) at android.widget.AdapterView.performItemClick(AdapterView.java:299) at android.widget.AbsListView.performItemClick(AbsListView.java:1113) at android.widget.AbsListView$PerformClick.run(AbsListView.java:2904) at android.widget.AbsListView$3.run(AbsListView.java:3638) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5017) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) at dalvik.system.NativeStart.main(Native Method)

Edit: Here is the full code for the activity including the query and list adapter. package com.richluick.ribbit;

import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.parse.FindCallback;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import com.parse.ParseRelation;
import com.parse.ParseUser;
import com.parse.SaveCallback;

import java.util.List;

public class FriendsFragment extends android.support.v4.app.ListFragment {

    public static final String TAG = FriendsFragment.class.getSimpleName();

    protected List<ParseUser> mFriends;
    protected ParseRelation<ParseUser> mFriendsRelation;
    protected ParseUser mCurrentUser;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_friends, container, false);
        return rootView;
    }

    @Override
    public void onResume() {
        super.onResume();

        mCurrentUser = ParseUser.getCurrentUser();
        mFriendsRelation = mCurrentUser.getRelation(ParseConstants.KEY_FRIENDS_RELATION);

        getActivity().setProgressBarIndeterminateVisibility(true);

        ParseQuery<ParseUser> query =  mFriendsRelation.getQuery();
        query.addAscendingOrder(ParseConstants.KEY_USERNAME);
        query.findInBackground(new FindCallback<ParseUser>() {
            @Override
            public void done(List<ParseUser> friends, ParseException e) {
                getActivity().setProgressBarIndeterminateVisibility(false);

                if (e == null) {
                    mFriends = friends;

                    String[] usernames = new String[mFriends.size()];
                    int i = 0;
                    for (ParseUser user : mFriends) {
                        usernames[i] = user.getUsername();
                        i++;
                    }
                    ArrayAdapter<String> adapter = new ArrayAdapter<String>(getListView().getContext(),
                    android.R.layout.simple_list_item_1, usernames);
                    setListAdapter(adapter);
                }
                else {
                    Log.e(TAG, e.getMessage());
                    AlertDialog.Builder builder = new AlertDialog.Builder(getListView().getContext());
                    builder.setTitle(R.string.error_title)
                            .setMessage(e.getMessage())
                            .setPositiveButton(android.R.string.ok, null);
                    AlertDialog dialog = builder.create();
                    dialog.show();
                }
            }
        });
    }

    @Override
  public void onListItemClick(ListView l, View v, int position, long id) {
     super.onListItemClick(l, v, position, id);

        final ParseObject item = (ParseObject) l.getAdapter().getItem(position);
        item.saveInBackground(new SaveCallback() {
            @Override
            public void done(ParseException e) {
                if(e == null) {
                    String objectID = item.getObjectId();
                    Log.e(TAG, objectID);

                    Intent intent = new Intent(getActivity(), FriendsProfileActivity.class);
                    intent.putExtra("ID", objectID);
                    startActivity(intent);
                }
                else {
                    Log.e(TAG, e.getMessage());
                }
            }
        });

}

}

like image 948
Rich Luick Avatar asked May 17 '26 00:05

Rich Luick


2 Answers

Have a look at ParseQueryAdapter

Docs: https://parse.com/docs/android_guide#ui-queryadapter

Tutorial: https://parse.com/tutorials/parse-query-adapter

API: https://parse.com/docs/android/api/com/parse/ParseQueryAdapter.html.

Also I would recommend EventBus to pass the ParseObject to the next Activity https://github.com/greenrobot/EventBus.

Then you can do:

Adapter:

Intent intent = new Intent(getActivity(), FriendsProfileActivity.class);
EventBus.getDefault().postSticky(YourParseObject);
startActivity(intent);

Anywhere in FriendsProfileActivity:

ParseObject yourParseObject = EventBus.getDefault().getStickyEvent(ParseObject.class);

If you move on to using subclasses in parse.com, then any subclass can be sent via the EventBus this way.

Example code - untested but should be close to what you want

The ParseQueryAdapter:

The layout for R.layout.adapter_item_friend - can be customized but nothing fancy here

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:paddingTop="5dp">


    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:text="item" />

</RelativeLayout>

The Adapter:

public class ParseUserFriendsAdapter extends ParseQueryAdapter<ParseUser> {

    private static final String TAG = ParseUserFriendsAdapter.class.getSimpleName();

    public ParseUserFriendsAdapter(Context context) {
        super(context, new ParseQueryAdapter.QueryFactory<ParseUser>() {

            @Override
            public ParseQuery<ParseUser> create() {
                ParseUser currentUser = ParseUser.getCurrentUser();
                ParseRelation<ParseUser> friendsRelation = currentUser.getRelation(ParseConstants.KEY_FRIENDS_RELATION);
                ParseQuery<ParseUser> query =  friendsRelation.getQuery();
                query.addAscendingOrder(ParseConstants.KEY_USERNAME);
                return query;
            }
        });
    }

    @InjectView(R.id.text) TextView text;

    @Override
    public View getItemView(final ParseUser user, View v, ViewGroup parent) {

        if (v == null) {
            v = View.inflate(getContext(), R.layout.adapter_item_friend,
                    null);
        }

        super.getItemView(user, v, parent);

        ButterKnife.inject(this, v);

        text.setText(user.getUsername());


        return v;

    }

}

I am using a regular fragment containing a ListView in it's layout:

R.layout.yourfriendslistlayout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:choiceMode="singleChoice"
        android:dividerHeight="1dp" />

</LinearLayout>

The important parts of the code in the fragment:

@Override
public void onCreate(Bundle savedInstanceState) {
    Log.d(TAG, "onCreate");

    mAdapter = new ParseUserFriendsAdapter(getActivity());

    super.onCreate(savedInstanceState);
}

@InjectView(R.id.listview) ListView mListView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View rootView = inflater.inflate(
            R.layout.yourfriendslistlayout, container, false);

    ButterKnife.inject(this, rootView);

    /** Setting the list adapter for the ListFragment */
    mListView.setAdapter(mAdapter);
    mListView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {

            // Now it is easy to get the ParseObject that is clicked
            ParseUser friend = mAdapter.getItem(position);

            Toast.makeText(getActivity(), "clicked " + friend.getObjectId(), Toast.LENGTH_SHORT).show();

            EventBus.getDefault().postSticky(friend);

            Intent intent = new Intent(getActivity(),
                    FriendsProfileActivity.class);
            startActivity(intent);

        }
    });
    return rootView;
}

Optional addition to the fragment code:

/* 
 *This last part automatically sets the load indicator whenever parse performs a query 
 */
private final OnQueryLoadListener<ParseUser> queryListener = new OnQueryLoadListener<ParseUser>() {

    @Override
    public void onLoaded(List<ParseUser> arg0, Exception arg1) {
        getActivity().setProgressBarIndeterminateVisibility(Boolean.FALSE);
    }

    @Override
    public void onLoading() {
        getActivity().setProgressBarIndeterminateVisibility(Boolean.TRUE);
    }
};

@Override
public void onResume() {
    mAdapter.addOnQueryLoadListener(queryListener);
    super.onResume();
}

@Override
public void onPause() {
    mAdapter.removeOnQueryLoadListener(queryListener);
    super.onPause();
}
like image 189
cYrixmorten Avatar answered May 19 '26 12:05

cYrixmorten


Simple use a textview in your list item, and populate it with ObjectID of object in getItemView() of your adapter and set its visibility to View.GONE

Then in onItemClickListener, call getText() of this textview.

In this way you can get objectId in your method and pass it along with intent.

like image 40
Abhishek Garg Avatar answered May 19 '26 13:05

Abhishek Garg