1

我有一個存儲在Firebase中的標籤列表。在我的一個片段中,一個MultiAutoCompleteTextView(MACTV)讓用戶選擇相關的標籤。MultiAutoCompleteTextView和Firebase

目的,

  • 是填充使用從火力地堡的 標籤的陣列(在ArrayAdapter用於MACTV)。
  • 一旦用戶使用 OnItemClickListener從MACTV選擇相關標籤,所選標籤需要保存到 Firebase。

以下是我嘗試實施的方法。

定義一個ArrayAdapter爲MACTV

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

保存選中的標籤,火力

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

爲2。不幸的是,當我在MACTV開始打字沒有相關的標籤顯示爲彈出的閾值規定。

我哪裏錯了?

+0

在將項添加到適配器後,只需在onDataChange()方法內添加此行即可。 adapterMultiAutoComplete.notifyDataSetChanged(); –

+0

相關(不重複)與回答問題http://stackoverflow.com/a/39715702/5593959 –

回答

1

順便說一句,很好的問題!這個月我見過的最有趣。

首先,使用此代碼,您可以將整個tags節點加載到設備。想象一下,你有2M的標籤(SO有嗎?),這個代碼還能工作嗎? ;)

第二件事,onDataChange(以及所有Firebase回調中的代碼)中的代碼在工作線程上調用,但是適配器方法應該在UI線程中調用。

而最後,這裏是我看到的解決辦法:

  1. 您需要使用查詢(你可以閱讀更多的docs
  2. 首先,我們需要排序的名稱標籤。因此,這是基本查詢:

    DatabaseReference baseRef = FirebaseDatabase.getInstance().getReference().child("tags").orderByChild("tagName"); 
    
  3. 下一頁 - 你必須重視TextWatcherMultiAutoCompleteTextView與下面的代碼

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

P.S:代碼從來沒有測試,可能無法正常工作。但你有這個主意;)

+0

感謝您介紹瞭解決方案的替代視角。我之前沒有考慮過使用查詢。但是哪個更好? _Case 01:_使用For循環來獲取所有可用的tagNames。在這種情況下,搜索速度更快,但涉及太多標籤時沒有意義。在_Case 02:_中(使用查詢),涉及的搜索時間過長(例如,當我希望搜索並添加10個標記時)例如, – user3314337

+0

@ user3314337將限制設置爲100。如果您的值小於100,請將它們保存在適配器中,並且不要進行更多查詢=) –

相關問題