Элементы Android FirebaseListAdapter всегда возвращают 0 для одного целого - PullRequest
0 голосов
/ 03 ноября 2019

У меня есть объекты в базе данных Firebase, которые представляют персонажей в видеоигре и содержат всю их статистику (атака, защита, здоровье и т. Д.). Я использую firebaseListAdapter, чтобы заполнить вид сетки пользовательскими представлениями, показывающими символы и некоторые их характеристики.

При использовании Android API 25 или ниже это работает, как и ожидалось, но с API 26 и выше все данные, КРОМЕ, кромезначение здоровья приходит через штраф, а значение здоровья всегда устанавливается равным 0.

Переменная здоровья - это просто целое число, которое никогда не обрабатывается иначе, чем другие целочисленные значения (сила, защита и т. д.) в любом местеcode.

Я отмечу, что добавление слушателя к значению здоровья одного из любых символов прекрасно возвращает значение.

У кого-нибудь есть идеи, что может быть причиной этого?

enter image description here

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

}

1 Ответ

0 голосов
/ 05 ноября 2019

В итоге я нашел исправление, но я все еще не уверен, почему это проблема только на определенных уровнях API Android.

public void setHealth(int health) {
    if (health > max_health) this.health = max_health;
    else if (health <= 0) this.health = 0;
    else this.health = health;
}

Функция setHealth () вызывается для каждого объекта, когдаfirebaseListAdapter получает эти объекты, и при использовании API 26+ эти функции должны вызываться по частям или как-то еще, потому что при вызове значение max_health устанавливается в 0, поэтому условие

if (health > max_health)

выполняется ипоэтому здоровье было ошибочно установлено равным 0. В более старых версиях Android значение max_health уже было правильно задано таймом, когда вызывается функция setHealth ().

Я добавил проверку, чтобы убедиться, что max_health нет'0 в верхней части функции setHealth (), поскольку у персонажа не может быть 0 для max_health

Я все еще был бы заинтересован ради любопытства и, возможно, чтобы помочь кому-то в дальнейшемузнавая, почему поведение отличается в разных версиях Android, но пока я рассмотрю мой первоначальный вопрос с ответом.

...