我在firebase数据库中有一些对象,这些对象代表视频游戏中的角色,并包含其所有状态(攻击,防御,健康等)。我使用firebaseListAdapter用自定义视图填充gridview,该自定义视图显示了字符及其某些状态。
使用Android API 25或更低版本时,此操作可以按预期工作,但是使用API 26及更高版本时,除健康值之外的所有数据都可以正常使用,并且健康值始终设置为0。
健康变量只是一个int值,在代码中的任何地方都不会与其他整数值(强度,防御力等)区别对待。
我会注意到,仅向任何字符的运行状况值添加一个侦听器就可以很好地获取该值。
有人有什么主意吗?
FirebaseListOptions<PlayerMonster> options = new FirebaseListOptions.Builder<PlayerMonster>()
.setQuery(mDatabase.child("playerMonsters").child(firebaseId).orderByChild("size"), PlayerMonster.class)
.setLayout(R.layout.monster_grid_single)
.build();
monsterFirebaseAdapter = new FirebaseListAdapter<PlayerMonster>(options) {
@Override
protected void populateView(View view, PlayerMonster monsterInstance, int position) {
// Not getting value for health ONLY, max health and everything else works. Querying health by itself also works.
Timber.d("monster health is " + monsterInstance.getHealth() + ", max hp: " + monsterInstance.getMax_health());
// Code here populates the view
}
};
grid.setAdapter(monsterFirebaseAdapter);
package odyssey.game.balfur.odyssey.firebase_objects;
import android.os.Parcel;
import android.os.Parcelable;
import com.google.firebase.database.Exclude;
import java.util.HashMap;
import java.util.Map;
public class PlayerMonster extends Monster implements Parcelable {
private String user_given_nick_name;
private int experience;
private int drawableRes;
private int itemHeldId;
protected PlayerMonster(Parcel in) {
user_given_nick_name = in.readString();
monster_name = in.readString();
itemHeldId = in.readInt();
type = in.readInt();
level = in.readInt();
health = in.readInt();
max_health = in.readInt();
experience = in.readInt();
size = in.readInt();
skill1 = in.readInt();
skill2 = in.readInt();
skill3 = in.readInt();
skill4 = in.readInt();
strength = in.readInt();
defense = in.readInt();
magicStrength = in.readInt();
magicDefense = in.readInt();
speed = in.readInt();
skinId = in.readInt();
}
public static final Creator<PlayerMonster> CREATOR = new Creator<PlayerMonster>() {
@Override
public PlayerMonster createFromParcel(Parcel in) {
return new PlayerMonster(in);
}
@Override
public PlayerMonster[] newArray(int size) {
return new PlayerMonster[size];
}
};
public int getDrawableRes() {return drawableRes;}
public void setDrawableRes(int drawableRes) {this.drawableRes = drawableRes;}
public int getExperience() {return experience;}
public void setExperience(int experience) {this.experience = experience; }
// public void addExperience(int experience) {this.experience += experience; }
public String getUser_given_nick_name() {
return user_given_nick_name;
}
public void setUser_given_nick_name(String user_given_nick_name) {this.user_given_nick_name = user_given_nick_name;}
public int getItemHeldId() {return itemHeldId;}
public void setItemHeldId(int itemHeldId) {this.itemHeldId = itemHeldId;}
public String getMonsterStringName(){ return user_given_nick_name; }
public PlayerMonster(){}
public PlayerMonster(String userGivenNickName, String monsterName, int itemHeldId, int type, int level, int health,
int max_health, int experience, int size, int skill1, int skill2, int skill3, int skill4,
int strength, int defense, int magicStrength, int magicDefense, int speed, int skinId){
this.user_given_nick_name = userGivenNickName;
this.monster_name = monsterName;
this.itemHeldId = itemHeldId;
this.type = type;
this.level = level;
this.health = health;
this.max_health = max_health;
this.experience = experience;
this.size = size;
this.skill1 = skill1;
this.skill2 = skill2;
this.skill3 = skill3;
this.skill4 = skill4;
this.strength = strength;
this.defense = defense;
this.magicStrength = magicStrength;
this.magicDefense = magicDefense;
this.speed = speed;
this.skinId = skinId;
}
// constructor for monsters w/ image resource. for use in the monsterBattleGridAdapter
public PlayerMonster(String userGivenNickName, String monsterName, int itemHeldId, int type, int level, int health,
int max_health, int experience, int size, int drawableRes, int skill1, int skill2, int skill3, int skill4,
int strength, int defense, int magicStrength, int magicDefense, int speed, int skinId){
this.user_given_nick_name = userGivenNickName;
this.monster_name = monsterName;
this.itemHeldId = itemHeldId;
this.type = type;
this.level = level;
this.health = health;
this.max_health = max_health;
this.experience = experience;
this.size = size;
this.drawableRes = drawableRes;
this.skill1 = skill1;
this.skill2 = skill2;
this.skill3 = skill3;
this.skill4 = skill4;
this.strength = strength;
this.defense = defense;
this.magicStrength = magicStrength;
this.magicDefense = magicDefense;
this.speed = speed;
this.skinId = skinId;
}
@Exclude
public Map<String, Object> toMap() {
HashMap<String, Object> result = new HashMap<>();
result.put("user_given_nick_name", user_given_nick_name);
result.put("monster_name", monster_name);
result.put("itemHeldId", itemHeldId);
result.put("type", type);
result.put("level", level);
result.put("health", health);
result.put("max_health", max_health);
result.put("experience", experience);
result.put("size", size);
result.put("skill1", skill1);
result.put("skill2", skill2);
result.put("skill3", skill3);
result.put("skill4", skill4);
result.put("strength", strength);
result.put("defense", defense);
result.put("magicStrength", magicStrength);
result.put("magicDefense", magicDefense);
result.put("speed", speed);
result.put("skinId", skinId);
return result;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(user_given_nick_name);
parcel.writeString(monster_name);
parcel.writeInt(itemHeldId);
parcel.writeInt(type);
parcel.writeInt(level);
parcel.writeInt(health);
parcel.writeInt(max_health);
parcel.writeInt(experience);
parcel.writeInt(size);
parcel.writeInt(skill1);
parcel.writeInt(skill2);
parcel.writeInt(skill3);
parcel.writeInt(skill4);
parcel.writeInt(strength);
parcel.writeInt(defense);
parcel.writeInt(magicStrength);
parcel.writeInt(magicDefense);
parcel.writeInt(speed);
parcel.writeInt(skinId);
}
}
package odyssey.game.balfur.odyssey.firebase_objects;
import android.os.Parcel;
import android.os.Parcelable;
import odyssey.game.balfur.odyssey.helpers.Condition;
import odyssey.game.balfur.odyssey.helpers.Helpers;
import odyssey.game.balfur.odyssey.helpers.TalentShorthand;
import java.util.HashMap;
import timber.log.Timber;
public class Monster implements Parcelable {
String monster_name;
int type;
int skill1;
int skill2;
int skill3;
int skill4;
int max_health;
int health;
int shield = 0;
int strength;
int speed;
int defense;
int magicStrength;
int magicDefense;
private boolean canSwap = true;
int skinId; // Each separate skin for each monster will have an ID associated with it
String firebaseId;
// At start of battle, record monsters stats to make sure buffs stay below certain %
public int[] baseStats = new int[6];
// Used to record how many stacks of a buff a monster has. can have between -5 and 5, each
// Representing 8% change from base stats. All values initialize to 0 by default
public int[] buffStacks = new int[6];
private HashMap<Integer, Condition> currentConditions = new HashMap<>();
private HashMap<Object, TalentShorthand> talentShorthand= new HashMap<>();
int level;
int size;
protected Monster(Parcel in) {
monster_name = in.readString();
type = in.readInt();
skill1 = in.readInt();
skill2 = in.readInt();
skill3 = in.readInt();
skill4 = in.readInt();
max_health = in.readInt();
health = in.readInt();
shield = in.readInt();
strength = in.readInt();
speed = in.readInt();
defense = in.readInt();
magicStrength = in.readInt();
magicDefense = in.readInt();
canSwap = in.readByte() != 0;
skinId = in.readInt();
firebaseId = in.readString();
baseStats = in.createIntArray();
buffStacks = in.createIntArray();
level = in.readInt();
size = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(monster_name);
dest.writeInt(type);
dest.writeInt(skill1);
dest.writeInt(skill2);
dest.writeInt(skill3);
dest.writeInt(skill4);
dest.writeInt(max_health);
dest.writeInt(health);
dest.writeInt(shield);
dest.writeInt(strength);
dest.writeInt(speed);
dest.writeInt(defense);
dest.writeInt(magicStrength);
dest.writeInt(magicDefense);
dest.writeByte((byte) (canSwap ? 1 : 0));
dest.writeInt(skinId);
dest.writeString(firebaseId);
dest.writeIntArray(baseStats);
dest.writeIntArray(buffStacks);
dest.writeInt(level);
dest.writeInt(size);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<Monster> CREATOR = new Creator<Monster>() {
@Override
public Monster createFromParcel(Parcel in) {
return new Monster(in);
}
@Override
public Monster[] newArray(int size) {
return new Monster[size];
}
};
// At start of battle, need to copy an array of each monsters stats and store it in each monster object
// These values will be checked when buff skills are used to ensure monsters stats do not go over the max buff amount (currently 40% over base)
public void backupStats(){
Timber.d("Backing up stats for %s", monster_name);
baseStats[0] = strength;
baseStats[1] = defense;
baseStats[2] = magicStrength;
baseStats[3] = magicDefense;
baseStats[4] = speed;
baseStats[5] = max_health;
}
public Monster(){}
public Monster(int level, String monster_name, int skinId){
this.level = level;
this.monster_name = monster_name;
this.skinId = skinId;
}
public int[] getBaseStats() { return baseStats; }
public void setBaseStats(int[] baseStats) { this.baseStats = baseStats; }
public String getFirebaseId() {return firebaseId;}
public void setFirebaseId(String firebaseId) {this.firebaseId = firebaseId;}
public int getSpeed() {return speed;}
public void setSpeed(int speed) {this.speed = speed;}
public int getStrength() {return strength;}
public void setStrength(int strength) {this.strength = strength;}
public int getDefense() {return defense;}
public void setDefense(int defense) {this.defense = defense;}
public int getMagicStrength() {return magicStrength;}
public void setMagicStrength(int magicStrength) {this.magicStrength = magicStrength;}
public int getMagicDefense() {return magicDefense;}
public void setMagicDefense(int magicDefense) {this.magicDefense = magicDefense;}
public int getSkill2() {return skill2;}
public void setSkill2(int skill2) {this.skill2 = skill2;}
public int getSkill3() {return skill3;}
public void setSkill3(int skill3) {this.skill3 = skill3;}
public int getSkill1() {return skill1;}
public void setSkill1(int skill1) {this.skill1 = skill1;}
public int getSkill4() {return skill4;}
public void setSkill4(int skill4) {this.skill4 = skill4;}
public int getSize() {return size;}
public void setSize(int size) {this.size = size;}
public int getMax_health() {
return max_health;
}
public void setMax_health(int max_health) {
this.max_health = max_health;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
if (health > max_health) this.health = max_health;
else if (health <= 0) this.health = 0;
else this.health = health;
}
public int getShield() {return shield;}
public void setShield(int shield) {
if (shield > max_health) this.shield = max_health;
else if (shield <= 0) this.shield = 0;
else this.shield = shield;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getMonster_name() {
return monster_name;
}
public void setMonster_name(String monster_name) {
this.monster_name = monster_name;
}
public String getMonsterStringName(){ return monster_name; }
public int getSkinId() { return skinId; }
public void setSkinId(int skinId) { this.skinId = skinId; }
public boolean isCanSwap() { return canSwap; }
public void setCanSwap(boolean canSwap) { this.canSwap = canSwap; }
public HashMap<Object, TalentShorthand> getTalentShorthand(){
return talentShorthand;
}
public void setTalentShorthand(HashMap<Object, TalentShorthand> talentShorthand){this.talentShorthand = talentShorthand;}
public HashMap<Integer, Condition> getCurrentConditions(){
return currentConditions;
}
public void setCurrentConditions(HashMap<Integer, Condition> currentConditions){this.currentConditions = currentConditions;}
public void addCondition(int conditionId, int roundsRemaining, double conditionDamagePercent, int addedStacks){
Condition condition;
if (currentConditions.containsKey(conditionId)){
int conditionStacks = currentConditions.get(conditionId).getConditionStacks();
// If adding one to the current stacks would still be less than the max stacks for that condition, add 1, otherwise do nothing
if (conditionStacks + addedStacks > Helpers.getConditionMaxStacks(conditionId)){
conditionStacks = Helpers.getConditionMaxStacks(conditionId);
addedStacks = Helpers.getConditionMaxStacks(conditionId) - conditionStacks; // The difference between the max and the preexisting conditions will be the true number of stacks added
} else {
conditionStacks += addedStacks;
}
condition = new Condition(roundsRemaining, conditionDamagePercent, conditionStacks);
condition.setStacksAppliedThisRound(addedStacks);
currentConditions.put(conditionId, condition);
} else {
condition = new Condition(roundsRemaining, conditionDamagePercent, addedStacks);
condition.setStacksAppliedThisRound(addedStacks);
currentConditions.put(conditionId, condition);
}
}
public void removeCondition(int conditionId){ // Used for calling condition remove skills doi
if (currentConditions.containsKey(conditionId)){
currentConditions.remove(conditionId);
}
}
}
答案 0 :(得分:0)
我最终找到了修复程序,但是我仍然不确定为什么这仅在某些android API级别才是问题。
public void setHealth(int health) {
if (health > max_health) this.health = max_health;
else if (health <= 0) this.health = 0;
else this.health = health;
}
当firebaseListAdapter获取这些对象时,将为每个对象调用setHealth()函数,并且在使用API 26+时,必须逐个调用这些函数,因为调用时max_health
的值设置为0,这样的情况
if (health > max_health)
是正确的,因此将健康状况错误地设置为0。在较旧的Android版本中,调用setHealth()函数的tim已经正确设置了max_health值。
我添加了一项检查,以确保setHealth()函数顶部的max_health
不为0,因为max_health
的字符不能为0
出于好奇的缘故,我仍然会感兴趣,并可能会帮助某人了解为什么行为在不同版本的Android中会有所不同,但是暂时,我会考虑回答我原来的问题。