我有一个存储在Firebase中的标签列表。在我的一个片段中,MultiAutoCompleteTextView(MACTV)允许用户选择相关标签。

目标,


使用以下命令填充Array(用于MACTV的ArrayAdapter)
Firebase中的标签。
一旦用户使用以下命令从MACTV中选择了相关标签
OnItemClickListener,需要将所选标签保存到
火力基地。


这是我尝试实施的方法。

定义用于MACTV的ArrayAdapter:

ArrayAdapter<String> adapterMultiAutoComplete = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1);


使用AddValueEventListener填充ArrayAdapter

if (fbUser != null) {
  dbTags.addValueEventListener(new ValueEventListener() {
      @Override
      public void onDataChange(DataSnapshot dataSnapshot) {
      //Basically, this says "For each DataSnapshot *Data* in dataSnapshot, do what's inside the method.
          for (DataSnapshot tagNameSnapshot : dataSnapshot.getChildren()) {
          //Get the suggestion by childing the key of the string you want to get.
              String ValueTagName = tagNameSnapshot.child("tagName")).getValue(String.class);
          //Add ValueTagName to ArrayAdapter
              adapterMultiAutoComplete.add(ValueTagName);
          }
       }

       @Override
       public void onCancelled(DatabaseError databaseError) {/*Do Nothing*/}
   });
}


MACTV代码

MultiAutoCompleteTextView articleTags = (MultiAutoCompleteTextView) findViewById(R.id.mactv_tags);
articleTags.requestFocus();
articleTags.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
articleTags.setAdapter(adapterMultiAutoComplete);


将所选标签保存到Firebase

List<String> ArticleTags = new ArrayList<>(Arrays.asList(articleTags.getText().toString().split(", ")));
DatabaseReference db = FirebaseDatabase.getInstance().getReference().child("tags").setValue(ArticleTags);


“阈值”值定义为2。不幸的是,当我开始在MACTV中键入内容时,没有相关的标签显示为弹出窗口。

我哪里做错了?

最佳答案

顺便说一句,很好的问题!我这个月见过的最有趣的。

首先,使用此代码将整个tags节点加载到设备。想象一下,您有2M的标签(SO有吗?),此代码仍然有效吗? ;)

第二件事,onDataChange中的代码(以及所有firebase回调中的代码)在辅助线程上调用,但是适配器方法应在UI线程中调用。

最后,这是我如何看待解决方案:


您需要使用查询(您可以在docs中阅读更多内容)
首先,我们需要按名称对标签进行排序。所以这是基本查询:

DatabaseReference baseRef = FirebaseDatabase.getInstance().getReference().child("tags").orderByChild("tagName");

下一步-您必须使用以下代码将TextWatcher附加到MultiAutoCompleteTextView

articleTags.addTextChangedListener(new TextWatcher() {

    @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        if (charSequence.length <3) return;

        String searchTarget = charSequence.toString().toLowerCase();
        //Here magic happens)
        baseRef.startAt(searchTarget).endAt(searchTarget + "\uf8ff").limitToFirst(20).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                //Handle executing this code in main thread yourself, answer will be too long with it
                adapterMultiAutoComplete.removeAll();
                for (DataSnapshot data: dataSnapshot.getChildren()) {
                     adapterMultiAutoComplete.add(data.getValue(String.class))
                }
                adapterMultiAutoComplete.notifyDatasetChanged();
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
               Log.wtf("What a terrible failure!", databaseError.toException());
            }
        });

    }

    @Override public void afterTextChanged(Editable editable) {}

});



附注:代码从未经过测试,可能无法正常工作。但是你有主意;)

09-04 06:34