parse.com - 嵌套查询和加入 Table

parse.com - Nested query and Join Table

我对嵌套查询有疑问。在 query5.whereEqualTo("piwo", followList2.get(0)) 中,我想获取该对象,但它吐出错误,指出 followList2 需要声明为最终的,但是当它执行时,所有匿名 class 都变成红色并出现 Cannot resolve constructor(...) 错误。有人以前收到过这个吗?

ParseQuery<ParseObject> query3 = ParseQuery.getQuery("Piwo");
                    query3.whereEqualTo("marka", beer); // TODO if(beer == "all") then don't use it
                    query3.findInBackground(new FindCallback<ParseObject>() {
                        public void done(List<ParseObject> followList2, ParseException e) {

                            if (followList2 != null) {
                                Log.d("ASD", "Szukane piwo: " + followList2.get(0).getString("marka"));
                            } else {
                                Log.d("ASD", "Zero wyników1");
                            }

                            ParseQueryAdapter<ParseObject> adapter =
                                    new ParseQueryAdapter<ParseObject>(this, new ParseQueryAdapter.QueryFactory<ParseObject>() {
                                        public ParseQuery<ParseObject> create() {
                                            // Here we can configure a ParseQuery to our heart's desire.
                                            ParseQuery query5 = new ParseQuery("Cena");
                                            query5.whereContainedIn("lokal", list);
                                            query5.whereEqualTo("piwo", followList2.get(0);
                                            query5.include("piwo");
                                            query5.include("lokal");
                                            query5.orderByAscending("cena");
                                            return query5;
                                        }
                                    });
                            adapter.setTextKey("lokal.place");
                            adapter.setImageKey("photo");

                            ListView listView = (ListView) findViewById(R.id.listview);
                            listView.setAdapter(adapter);

如果我没理解错的话,你已经尝试过了:

...
public void done(final List<ParseObject> followList2, ParseException e) {
...

由于某种原因,这让编译器不高兴。

我认为可能有两种可能的解决方案

  1. 如果您打算在 Activity/Fragment 的其他地方使用 followList2 对象。然后简单地声明一个字段变量来保存结果并从中读取。这样匿名内部 class 应该可以访问它。
  2. 将 followList2 写入另一个声明为 final 的局部变量。这样我们就不会改变 done() 回调的签名。

解决方案 1:

List<ParseObject> mFollowList2; // field variable outside method
...
public void done(List<ParseObject> followList2, ParseException e) {
    mFollowList2 = followList2; 
    // use mFollowList2 in rest of code
...    

解决方案 2:

public void done(List<ParseObject> followList2, ParseException e) {
    final List<ParseObject> finalFollowList2 = followList2; 
    // use finalFollowList2 in rest of code
...    

正如评论中所说,我不记得有过同样的问题,但我希望这能解决问题。

第三个建议是试用 Bolts https://github.com/BoltsFramework/Bolts-Android(附带解析 API)。如果您熟悉 javascript 中的 Promise,Bolts 与 Java 中的 Promise 基本相同。它消除了嵌套调用的需要,随着依赖查询数量的增长,形成金字塔形的代码块。然而,它确实需要一些时间来适应,在简单的情况下是没有必要的。

奖金:

由于您在使用适配器中包含的文本时遇到问题,我将向您展示我的一些代码作为示例。

首先,我有一个简单的项目布局: res/layout/view_adapter_item_simple.xml

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

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


</RelativeLayout>

接下来,这是我的自定义适配器:

public class SimpleParseAdapter<T extends ParseObject> extends
        ParseQueryAdapter<T> {

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

    private final String textCol;

    public SimpleParseAdapter(Context context, String textCol,
            QueryFactory<T> queryFactory) {
        super(context, queryFactory);
        this.textCol = textCol;
    }

    TextView text;

    @Override
    public View getItemView(T object, View v, ViewGroup parent) {

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

        super.getItemView(object, v, parent);

        text = (TextView) v.findViewById(R.id.text);

        text.setText(object.getString(textCol));

        return v;

    }


}

注意:我们还没有完成。这与标准的 ParseQueryAdapter 类似,因为它只使用 text.setText(object.getString(textCol)).

查看当前 class 的列

但是,可以很容易地编写一个专用适配器来处理嵌套包含,例如:

public class SimpleParseIncludeAdapter<T extends ParseObject> extends
        ParseQueryAdapter<T> {

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

    private final String includeCol;
    private final String textCol;

    public SimpleParseIncludeAdapter(Context context, String includeCol, String textCol,
            QueryFactory<T> queryFactory) {
        super(context, queryFactory);
        this.includeCol = includeCol;
        this.textCol = textCol;
    }

    TextView text;

    @Override
    public View getItemView(T object, View v, ViewGroup parent) {

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

        super.getItemView(object, v, parent);

        text = (TextView) v.findViewById(R.id.text);

        text.setText(object.getParseObject(includeCol).getString(textCol));

        return v;

    }


}

现在像这样使用适配器:

new SimpleParseIncludeAdapter(**context**, "lokal", "place",**queryFactory**); 

其中 queryFactory 有义务做 query.include("lokal")(包括整个 'lokal' 指针),或`query.include("lokal.place")(仅包括 'place' 列 'lokal');

额外奖励 - subclassing

最后一点,您似乎没有使用 subclassing,但如果您使用了,您也可以为 Cena subclasses 提供专门的自定义适配器。

public class CenaParseAdapter extends
        ParseQueryAdapter<Cena> {

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



    public CenaParseAdapter(Context context, 
            QueryFactory<Cena> queryFactory) {
        super(context, queryFactory);

    }

    TextView text;

    @Override
    public View getItemView(Cena cena, View v, ViewGroup parent) {

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

        super.getItemView(object, v, parent);

        text = (TextView) v.findViewById(R.id.text);

        text.setText(cena.getPlace());

        return v;

    }


}

在这种情况下 cena.getPlace() 可以查找包含的本地:

// inside Cena sublass

public Lokal getLokal() { // assuming Lokal also is subclassed
    return (Lokal)getParseObject("lokal");
}

public String getPlace() {
    return (getLokal() != null) ? getLokal().getPlace() : "";
}

// inside Lokal subclass

public String getPlace() {
    return getString("place");
}