parse.com - 嵌套查询和连接表

时间:2015-06-13 19:07:19

标签: android parse-platform nested-queries nested-query

我遇到嵌套查询问题。在query5.whereEqualTo("piwo", followList2.get(0))中我想获取对象,但是它会发出错误,即followList2需要被声明为final,但是当它执行时,所有匿名类都会以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);

1 个答案:

答案 0 :(得分:2)

如果我理解正确,你已经尝试过:

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

由于某种原因导致编译器不满意。

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

  1. 如果您打算在Activity / Fragment中的其他位置使用followList2对象。然后简单地声明一个字段变量来保存结果并从中读取。这样匿名内部类就可以访问它了。
  2. 将followList2写入另一个声明为final的局部变量。这样我们就不会改变done()回调的签名。
  3. 解决方案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中的promises,那么对于Java来说,Bolts基本相同。它消除了嵌套调用的需要,随着依赖查询数量的增长,形成金字塔形状的代码块。但是,它需要一些时间来习惯,在简单的情况下,它是没有必要的。

    <强>加成:

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

    首先,我有一个项目的简单布局: 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))查看当前类的列。

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

    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")(包括整个&#39; lokal&#39;指针),或`query.include(&#34; lokal.place&#34;)(仅包括&#39; lokal&#39;)的

    列;

    额外奖励 - 继承

    最后一点,它看起来并不像你在使用子类化,但是如果你这样做了,你也可以为Cena子类设置专门的自定义适配器。

    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()可以查找包含的lokal:

    // 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");
    }