简体   繁体   English

从onListItemClick获取解析对象ID

[英]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.). 为此,我一直在尝试从列表视图中单击的用户中提取特定对象ID,然后将其传递到下一个活动,我使用它来为所有用户运行查询其他属性(名称,电子邮件,家乡等)。 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. 我已经想出了如何通过意图传递数据,但是我在点击列表项中获取用户ID时遇到了各种各样的麻烦。 My onItemCLick code is below. 我的onItemCLick代码如下。

``` ```

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? 如何从单击的用户成功拉出对象ID并将其传递?

Edit: Here is the logcat error. 编辑:这是logcat错误。

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; 包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());
                }
            }
        });

}

} }

Have a look at ParseQueryAdapter 看看ParseQueryAdapter

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

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

API: https://parse.com/docs/android/api/com/parse/ParseQueryAdapter.html . 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 . 我还建议EventBus将ParseObject传递给下一个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: 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. 如果您继续在parse.com中使用子类,则可以通过EventBus以这种方式发送任何子类。

Example code - untested but should be close to what you want 示例代码 - 未经测试但应该接近您想要的

The ParseQueryAdapter: ParseQueryAdapter:

The layout for R.layout.adapter_item_friend - can be customized but nothing fancy here R.layout.adapter_item_friend的布局 - 可以自定义,但没有什么花哨的

<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: 我在其布局中使用包含ListView的常规片段:

R.layout.yourfriendslistlayout: 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();
}

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 在列表项中简单使用textview,并在适配器的getItemView()中使用ObjectID对象填充它,并将其可见性设置为View.GONE

Then in onItemClickListener, call getText() of this textview. 然后在onItemClickListener中,调用此textview的getText()。

In this way you can get objectId in your method and pass it along with intent. 通过这种方式,您可以在方法中获取objectId并将其与intent一起传递。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM