领域连续调用onChange addChangeListener

时间:2018-01-11 20:45:50

标签: java android realm android-arrayadapter

道歉,如果解释得不好,我自己很难理解。如果你指出任何你不理解的东西,我会尽力纠正任何问题。好的,我们走了。

几节课。 (D& D表,表有武器用户可以装备,这是关于配备存储在列表中的所述武器)

到目前为止,我收集到的是当我创建一个新的attackListViewContentAdapter时,它会以快速且持续的速度循环。这么多,以至于屏幕没有响应我触摸任何小部件。我已经完成了每次通过时记录一个数字的事情,所以它会一次又一次地显示它。如果您需要有关于此的信息,我可以向您显示我放置日志的位置以及当我添加其他视图(行)时在Logcat中显示的内容。

我相信这与onChangedListener有关,它继续被触发,即使我找到了为什么我会进入一个可以创建新视图并拥有监听器以便它可以记录更改的阶段的原因。

请注意,为了空间利益,我将使用缩写代码。我忽略了不相关的对话框和小部件之类的东西。因此,如果它看起来像是缺少某些东西或者您需要查看这些类,那么它可能位于我在每个类上面链接的文件中。

CombatFragment

public class CombatFragment extends Fragment {
@BindView(R.id.lv_attack_spellcasting_content)
ListView lv_attack_spellcasting_title;


@Nullable
@Override
public View onCreateView(final LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.content_combat, container, false);
    RealmList<Weapon> weaponList = sheet.getWeaponList();
    final AttackListViewContentAdapter attackListViewContentAdapter = new AttackListViewContentAdapter(getActivity(), sheet, realm, weaponList);
    weaponList.addChangeListener(new RealmChangeListener<RealmList<Weapon>>() {
        @Override
        public void onChange(RealmList<Weapon> weapons) {
            /* Gives the adaptor a kick to know that the weapon realm list has changed */
            attackListViewContentAdapter.notifyDataSetChanged();
            loopOnChanged++;
        }
    });
    lv_attack_spellcasting_title.setAdapter(attackListViewContentAdapter);
    playerInit();
    return rootView;
}

   // This is a fake method, this is just to show that the .add is in it's own method which is triggered by a button press and not in onCreate
   public void buttonPress() {
       sheet.getWeaponList().add(realm.createObject(Weapon.class));
   }
} `

AttackListViewContentAdapter

public class AttackListViewContentAdapter extends ArrayAdapter<Weapon> {
        public AttackListViewContentAdapter(Context context, Sheet sheet, Realm realm, List<Weapon> weaponList) {
        super(context, 0, weaponList);
        this.sheet = sheet;
        this.realm = realm;
    }
    @Override
    @NonNull
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null)
        //Because you're returning the view (AttachToRoot is false) the ArrayAdaptor (This class) will handle adding the view to the list.
        convertView = 
        LayoutInflater.from(getContext()).inflate(R.layout.attack_list_item, parent, false);
        return convertView;
    }
}

Weapon

public class Weapon extends RealmObject {
    @PrimaryKey
    int weaponID;
    //properties, set get methods etc.
}

Sheet

public class Sheet extends RealmObject {
    @PrimaryKey
    private int sheetID;
    private RealmList<Weapon> weaponList;

    public RealmList<Weapon> getWeaponList() {
        return weaponList;
    }

    public void setWeaponList(RealmList<Weapon> weaponList) {
        this.weaponList = weaponList;
    }
}

content_combat

            <ListView
            android:id="@+id/lv_attack_spellcasting_content"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"

            android:columnCount="7"
            android:rowCount="1" />

attack_list_item

没有什么可以包含

1 个答案:

答案 0 :(得分:1)

由于AttackListViewContentAdapter类中的微调控件小部件初始化错误,您的问题正在发生。

  1. 您必须在设置setOnItemSelectedListener之前设置您的微调器选择。
  2. 您必须检查您的微调器选择是否不等于当前选择,以避免onChangeonItemSelected方法之间的无限循环。我的意思是,您的微调器onItemSelected回调,执行领域转换,然后,这些转换会触发您的onChange回调,最后,您的onChange回调会调用notifyDataSetChanged(),这会使周期重新开始进入一个无限循环。
  3. 要解决您的问题,您应该按照 AttackListViewContentAdapter.java 中的后续步骤进行操作:

    A)addWeaponToUI()方法中删除以下行:

    private void addWeaponToUI() {
        et_name_value.setText(weapon.getWeaponName());
        np_damage_number_of_die_value.setValue(weapon.getWeaponDamageNumberOfDie());
        SheetEnum.Ability ability = SheetEnum.Ability.getEnumValue(weapon.getWeaponAbilityBonusInt());
        tv_attack_bonus_value.setText(String.valueOf(sheet.getAbilityBonus(ability)));
    
        // REMOVE below lines!
        //s_damage_die_type_value.setSelection(weapon.getWeaponDamageDieTypeInt());
        //s_damage_type_value.setSelection(weapon.getWeaponDamageTypeInt());
        //s_ability_bonus_value.setSelection(weapon.getWeaponAbilityBonusInt());
    }
    

    B)setSelection()之前调用微调器setOnItemSelectedListener(),然后选中所选项不等于所选位置以避免无限循环:

    ArrayAdapter<CharSequence> damageDieTypeAdapter = ArrayAdapter.createFromResource(getContext(), R.array.die_type, android.R.layout.simple_spinner_dropdown_item);
        s_damage_die_type_value.setAdapter(damageDieTypeAdapter);
        //Set selection before listener
        s_damage_die_type_value.setSelection(weapon.getWeaponDamageDieTypeInt());
        s_damage_die_type_value.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View v, final int position, long id) {
                //Check selected position is not equal to current position to avoid an infinite loop
                if (position != weapon.getWeaponDamageDieTypeInt()) {
                    String[] value = getContext().getResources().getStringArray(R.array.die_type);
                    realm.executeTransaction(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        weapon.setWeaponDamageDieType(position);
                    }
                });
            }
        }
    
        @Override
        public void onNothingSelected(AdapterView<?> parent) {
        }
    });
    

    C)s_damage_type_values_ability_bonus_value微调器重复步骤B