带有FirebaseRecyclerAdapter的RecyclerView保持空白

时间:2018-08-15 19:38:32

标签: android firebase-realtime-database android-recyclerview recycler-adapter firebaseui

我目前正在尝试使用Firebase实时数据库构建应用程序, 我已经有一些数据,这些数据的结构如下(导出的JSON的摘录)

{
"userdata" : {
    "593QfAvxxxxxxxxxxxHqCMA3" : {
      "calcentries" : {
        "-LJy_hvvm3ySUqM6sQcf" : {
          "candyCount" : 0,
          "evolutionLine" : {
            "candyNeeded" : 25,
            "evolvedSpecies" : 2,
            "precondition" : {
              "buddyKm" : 0,
              "preconditionType" : "NONE"
            }
          },
          "evolvedSpeciesTransferCount" : 0,
          "newPokedexEntry" : false,
          "pokemonCount" : 0,
          "possibleEvoCountWithPreconditionsMet" : 0,
          "possibleEvolutionCount" : 0,
          "preconditionsMet" : false,
          "sourceSpecies" : 1,
          "sourceSpeciesCountAfterEvolutions" : 0,
          "sourceSpeciesTransferCount" : 0
        },
        "-LJy_hwMVTM20f0c5JOJ" : { ...

}

我尝试通过使用FirebaseRecyclerAdapter(Firebase UI 4.1.0)在RecyclerView中显示它们。 这就是我在活动的onCreate中初始化RecyclerView和适配器的方式

mRecyclerView = findViewById(R.id.rv_calculation_input);

RecyclerView.LayoutManager layoutManager = new GridLayoutManager(this,1, LinearLayoutManager.VERTICAL,false);

mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);

FirebaseRecyclerOptions<CalculationInputEntry> opt
     = new FirebaseRecyclerOptions.Builder<CalculationInputEntry>()
         .setLifecycleOwner(this)
         .setQuery(AppUtil.getCurrentUserRef().child("calcentries"), CalculationInputEntry.class)
         .build();

mAdapter = new FirebaseRecyclerAdapter<CalculationInputEntry, CalculationInputEntryViewHolder>(opt) {        
     @NonNull
     @Override
     public CalculationInputEntryViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
          View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_main, parent, false);
          return new CalculationInputEntryViewHolder(v);
     }

     @Override
     protected void onBindViewHolder(@NonNull CalculationInputEntryViewHolder holder, int position, @NonNull CalculationInputEntry model) {
           holder.bindEntry(model);
     }
 };

mRecyclerView.setAdapter(mAdapter);

视图仍然为空... 通过设置生命周期所有者,不需要在适配器上手动调用startListening和stopListening,对吗?

我将Firebase日志级别设置为要调试,并发现引发“ CHILD_ADDED”事件的相当多的条目,甚至显示了预期的数据...

D/EventRaiser: Raising /userdata/593QxxxxxxxxxCMA3/calcentries: CHILD_ADDED: { -LJy_tNakAl19tH5H_tb: {preconditionsMet=false, sourceSpeciesCountAfterEvolutions=0, newPokedexEntry=false, possibleEvoCountWithPreconditionsMet=0, possibleEvolutionCount=0, candyCount=0, sourceSpeciesTransferCount=0, evolutionLine={candyNeeded=25, precondition={buddyKm=0, preconditionType=NONE}, evolvedSpecies=375}, pokemonCount=0, sourceSpecies=374, evolvedSpeciesTransferCount=0} }

但它们似乎永远无法进入用户界面。

这里是涉及的模型类,我正在使用Lombok生成getter,setter和所需的构造函数(至少我希望我包括了所需的一切)。我已经将一些字段从Enums更改为Strings,以防万一这可能是一个问题...警告:前面有很多代码...

CalculationInputEntry

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class CalculationInputEntry implements Comparable, Parcelable {

    //Pokédex number for less data redundancy when serializing
    private int sourceSpecies;
    private SpeciesEvolution evolutionLine;

    //input variables
    private int candyCount;
    private int pokemonCount;
    private boolean newPokedexEntry;
    private boolean preconditionsMet;

    //calculation and result variables
    private int possibleEvolutionCount; // 0 when preconditionsMet false
    private int sourceSpeciesTransferCount;
    private int evolvedSpeciesTransferCount;
    private int sourceSpeciesCountAfterEvolutions;
    private int possibleEvoCountWithPreconditionsMet;

    public CalculationInputEntry(int species, SpeciesEvolution evolution, int candyCount, int pokemonCount) {
        this.sourceSpecies = species;
        this.evolutionLine = evolution;
        this.candyCount = candyCount;
        this.pokemonCount = pokemonCount;
        this.preconditionsMet = false;
        this.newPokedexEntry = false;
    }

   //some other methods, including compareTo and the Parcelable stuff
}

SpeciesEvolution

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class SpeciesEvolution implements Parcelable {
    private int candyNeeded;
    private EvolutionPrecondition precondition;
    private int evolvedSpecies;

    //Parcelable stuff here
}

EvolutionPrecondition

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class EvolutionPrecondition implements Parcelable {

    private String preconditionType;
    private int buddyKm;
    private String evoItem;

   //Parcelable stuff
}

我的模型有什么问题吗?还是我太盲目看不到真正的问题?任何提示将不胜感激...

2 个答案:

答案 0 :(得分:1)

  

通过设置生命周期所有者,不需要在适配器上手动调用startListening和stopListening,对吗?

否,两者都是必要的。为了能够显示Firebase数据库中的数据,您需要开始侦听更改,为此,您应该在onStart()方法中添加以下代码行:

@Override
protected void onStart() {
    super.onStart();
    mAdapter.startListening();
}

要停止收听foir更改,您需要像这样在onStop()方法中添加以下代码行:

@Override
protected void onStop() {
    super.onStop();
    if(mAdapter != null) {
        mAdapter.stopListening();
    }
}

请从此 post 中查看我的答案,在这里我解释了为什么您应该删除监听器。

答案 1 :(得分:0)

我解决了。既不需要start / stopListening,也不需要我的getter / setter或DatabaseReference ...

是这行

mRecyclerView.setHasFixedSize(true);

删除它后,我可以将所有内容恢复为问题中显示的状态。 我从这个GitHub问题https://github.com/firebase/FirebaseUI-Android/issues/204中得到了这个主意 无论如何都要感谢Alex Mamo:)