带有 FirebaseRecyclerAdapter 的 RecyclerView 仍然是空的
RecyclerView with FirebaseRecyclerAdapter remains empty
我目前正在尝试使用 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 中显示它们。
这就是我在 activity
的 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} }
但他们似乎永远无法接通 UI。
这里是涉及的模型类,我正在使用Lombok 来生成getter、setter 和所需的构造函数(至少我希望我包含了所有需要的东西)。我已经将一些字段从枚举更改为字符串,以防万一这可能是个问题...注意:前面有很多代码...
计算输入项
@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
}
物种进化
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class SpeciesEvolution implements Parcelable {
private int candyNeeded;
private EvolutionPrecondition precondition;
private int evolvedSpecies;
//Parcelable stuff here
}
进化前提条件
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class EvolutionPrecondition implements Parcelable {
private String preconditionType;
private int buddyKm;
private String evoItem;
//Parcelable stuff
}
我的模型有什么问题还是我太盲目看不到真正的问题?任何提示将不胜感激...
By setting the lifecycle owner, manually calling startListening and stopListening on the adapter should not be necessary, right?
不,两者都是必需的。为了能够显示来自 Firebase 数据库的数据,您需要开始监听更改,为此您应该在 onStart()
方法中添加以下代码行:
@Override
protected void onStart() {
super.onStart();
mAdapter.startListening();
}
要停止侦听更改,您需要在 onStop()
方法中添加以下代码行:
@Override
protected void onStop() {
super.onStop();
if(mAdapter != null) {
mAdapter.stopListening();
}
}
请参阅我在 中的回答,我已经解释了为什么您应该删除侦听器。
我解决了。不需要 start/stopListening,我的 getters/setters 或 DatabaseReference 也不是错误的...
就是这条线
mRecyclerView.setHasFixedSize(true);
在我删除它之后,我可以将所有内容恢复到问题中显示的状态。
我从这个 GitHub 问题 https://github.com/firebase/FirebaseUI-Android/issues/204 中得到了灵感
无论如何都要感谢 Alex Mamo :)
我目前正在尝试使用 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 中显示它们。 这就是我在 activity
的 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} }
但他们似乎永远无法接通 UI。
这里是涉及的模型类,我正在使用Lombok 来生成getter、setter 和所需的构造函数(至少我希望我包含了所有需要的东西)。我已经将一些字段从枚举更改为字符串,以防万一这可能是个问题...注意:前面有很多代码...
计算输入项
@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
}
物种进化
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class SpeciesEvolution implements Parcelable {
private int candyNeeded;
private EvolutionPrecondition precondition;
private int evolvedSpecies;
//Parcelable stuff here
}
进化前提条件
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class EvolutionPrecondition implements Parcelable {
private String preconditionType;
private int buddyKm;
private String evoItem;
//Parcelable stuff
}
我的模型有什么问题还是我太盲目看不到真正的问题?任何提示将不胜感激...
By setting the lifecycle owner, manually calling startListening and stopListening on the adapter should not be necessary, right?
不,两者都是必需的。为了能够显示来自 Firebase 数据库的数据,您需要开始监听更改,为此您应该在 onStart()
方法中添加以下代码行:
@Override
protected void onStart() {
super.onStart();
mAdapter.startListening();
}
要停止侦听更改,您需要在 onStop()
方法中添加以下代码行:
@Override
protected void onStop() {
super.onStop();
if(mAdapter != null) {
mAdapter.stopListening();
}
}
请参阅我在
我解决了。不需要 start/stopListening,我的 getters/setters 或 DatabaseReference 也不是错误的...
就是这条线
mRecyclerView.setHasFixedSize(true);
在我删除它之后,我可以将所有内容恢复到问题中显示的状态。 我从这个 GitHub 问题 https://github.com/firebase/FirebaseUI-Android/issues/204 中得到了灵感 无论如何都要感谢 Alex Mamo :)