从onListItemClick获取解析对象ID

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从onListItemClick获取解析对象ID相关的知识,希望对你有一定的参考价值。

我目前正在开发一个应用程序,其中包含登录时的朋友列表和用户配置文件。当用户点击朋友列表中的朋友时,我希望他们被定向到该朋友的个人资料页面。为此,我一直在尝试从列表视图中单击的用户中提取特定对象ID,然后将其传递到下一个活动,我使用它来为所有用户运行查询其他属性(名称,电子邮件,家乡等)。我已经想出了如何通过意图传递数据,但是我在点击列表项中获取用户ID时遇到了各种各样的麻烦。我的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);

```

我也试过这种东西无济于事。

```

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

    }

```

在这两种情况下,当我在列表视图中单击用户时,应用程序崩溃。如何从单击的用户成功拉出对象ID并将其传递?

编辑:这是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)

编辑:以下是活动的完整代码,包括查询和列表适配器。包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());
                }
            }
        });

}

}

答案

看看ParseQueryAdapter

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

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

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

另外我建议EventBus将ParseObject传递给下一个Activity https://github.com/greenrobot/EventBus

然后你可以这样做:

适配器:

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

FriendsProfileActivity中的任何位置:

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

如果您继续在parse.com中使用子类,则可以通过EventBus以这种方式发送任何子类。

示例代码 - 未经测试但应该接近您想要的

ParseQueryAdapter:

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>

适配器:

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;

    }

}

我在其布局中使用包含ListView的常规片段:

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>

片段中代码的重要部分:

@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;
}

片段代码的可选添加:

/* 
 *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();
}
另一答案

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

然后在onItemClickListener中,调用此textview的getText()。

通过这种方式,您可以在方法中获取objectId并将其与intent一起传递。

以上是关于从onListItemClick获取解析对象ID的主要内容,如果未能解决你的问题,请参考以下文章

设置模型类和自定义适配器以从 onListItemClick 获取 SQLite DB rowID

无法从 onListItemClick 开始片段

我无法从 ListFragment 内的 onListItemClick 开始新活动

getInitialProps() 应该解析为一个对象。但发现“未定义”

onListItemClick 不会(总是)被 ListActivity 调用

使用自定义适配器绕过 ListView 的 onListItemClick()