我需要Realm的一些帮助。
我有一个Realm对象:PokemonExperience
RealmList<RealmString>
public class PokemonExperience extends RealmObject {
public RealmList<RealmString> mainSkills;
public RealmList<RealmString> getMainSkills() {
return mainSkills;
}
public void setMainSkills(RealmList<RealmString> mainSkills) {
this.mainSkills = mainSkills;
}
我也有RealmString
个对象,只有值字段。
有了这个,我有一个带有复选框的多选列表,这些复选框有onClickListeners。当我选中复选框时,我想将所有值保存到RealmString
模型中,然后将RealmStrings保存到RealmList<RealmString>
模型中的PokemonExperience
。
这是我的代码:
public View getView(final int position, View convertView, final ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null) {
//inflate Layout
convertView = layoutInflater.inflate(R.layout.fragment_multiple_choice_adapter, parent, false);
convertView.findViewById(R.id.fragment_multiple_choice_checkbox);
viewHolder.checkBox.setOnClickListener(view -> {
setCheckListener(viewHolder);
});
convertView.setTag(viewHolder);
if (selectedPositions.size() == 0) {
Method getter = getGetter(field);
try {
List<Object> values = Arrays.asList(data.values().toArray());
Object result = getter.invoke(object);
List<Object> resultAsList = (List<Object>) result;
for (int i = 0; i < values.size(); i++) {
if (resultAsList.contains(values.get(i))) {
selectedPositions.add(i);
}
viewHolder.checkBox.setChecked(position == selectedPositions.get(i));
viewHolder.position = position;
}
} catch (Exception e) {}
}
List<Object> keys = Arrays.asList(data.keySet().toArray());
viewHolder.textView.setText(keys.get(position).toString());
viewHolder.position = position;
return convertView;
}
private Method getSetter(Field field) {
return settersMap.get(field);
}
private Method getGetter(Field field) {
return gettersMap.get(field);
}
private boolean isGetter(Method method) {
return method.getName().startsWith("get") &&
method.getParameterTypes().length == 0 &&
!void.class.equals(method.getReturnType());
}
private boolean isSetter(Method method) {
return method.getName().startsWith("set") &&
method.getParameterTypes().length == 1;
}
private String croppedMethodName(boolean isGetter, boolean isSetter, Method method) {
if (!isGetter && !isSetter) {
return null;
}
if (isSetter &&
method.getParameterTypes()[0].getName().equals(boolean.class.getCanonicalName())) {
char[] c = new StringBuilder(method.getName()).substring(2).toCharArray();
c[0] = Character.toLowerCase(c[0]);
return new String(c);
}
char[] c = new StringBuilder(method.getName()).substring(3).toCharArray();
c[0] = Character.toLowerCase(c[0]);
return new String(c);
}
private void setCheckListener(ViewHolder viewHolder) {
selectedPosition = viewHolder.position;
Log.d(TAG, "getView: 111: " + selectedPosition);
// We save our values here to Realm
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
Method setter = getSetter(field);
try {
List<Object> values = Arrays.asList(data.values().toArray());
// taking a piece of string based on viewHolder.position to determine
// what is the "object" we should be saving
Object selectedObject = values.get(viewHolder.position);
Log.d(TAG, "selectedObject: " + selectedObject);
RealmString selectedRealmString = (RealmString) selectedObject;
Log.d(TAG, "realmString: " + selectedRealmString);
String selectedRealmStringValue = selectedRealmString.getValue();
Log.d(TAG, "realmStringValue: " + selectedRealmStringValue);
RealmResults<RealmString> realmStrings = realm.where(RealmString.class).findAll();
if (!realmStrings.contains(selectedRealmStringValue)) {
selectedRealmString = new RealmString();
selectedRealmString.setValue(selectedRealmStringValue);
realm.copyToRealm(selectedRealmString);
}
Log.d(TAG, "saved realmString: " + selectedRealmString);
Log.d(TAG, "saved realmStringValue: " + selectedRealmStringValue);
Log.d(TAG, "RealmResult size: " + realmStrings.size());
Log.d(TAG, "RealmResult: " + realmStrings.toArray().toString());
Method getter = getGetter(field);
Log.d(TAG, "getter name: " + getter.getName());
Object existingObjects = getter.invoke(object);
Log.d(TAG, "existingObjects: " + existingObjects);
RealmList<RealmString> existingValues;
existingValues = (RealmList<RealmString>) existingObjects;
Log.d(TAG, "existingValues1: " + existingValues);
if (!existingValues.contains(selectedRealmString)) {
Log.d(TAG, "existingValues2: " + existingValues);
existingValues.add(selectedRealmString);
}
Log.d(TAG, "existingValues3: " + existingValues);
setter.invoke(object, existingValues);
Log.d(TAG, "setCheckListener: setter is: " + setter.getName());
} catch (Exception e) {
e.printStackTrace();
}
realm.commitTransaction();
realm.close();
viewHolder.checkBox.setChecked(true);
notifyDataSetChanged();
}
我的问题:
为什么我的值会保存到My RealmString模型两次?每当我点击任何复选框时,该复选框的字符串值都会保存两次。
为什么将值保存到RealmString模型,即使有检查。
if(!realmStrings.contains(selectedRealmStringValue)){ // ... }
这应该确保只保存新值。
RealmList<RealmString>
未保存到我的PokemonExperience的mainSkills字段中。感谢任何帮助。非常感谢!
答案 0 :(得分:0)
我认为你应该这样检查
if (!realmStrings.contains(selectedRealmString)) {
...
}
因为selectedRealmString
是RealmString
类的实例,selectedRealmStringValue
是String
类的实例而您的RealmResults
包含RealmString
答案 1 :(得分:0)
selectedRealmString
是一个非托管对象,您将两次插入您的领域(realm.copyToRealm(selectedRealmString)
和existingValues.add(selectedRealmString)
)。您可以执行selectedRealmStringManaged = realm.copyToRealm(selectedRealmString)
,然后执行existingValues.add(selectedRealmStringManaged)
。
答案 2 :(得分:0)
if (!realmStrings.contains(selectedRealmString)) {
...
}
上述方法不起作用,因为我们真正需要做的是比较对象的价值。 这有效:
ArrayList<String> existingValuesArrayList = new ArrayList<>();
for (int i = 0; i < existingValues.size(); i++) {
existingValuesArrayList.add(existingValues.get(i).getValue());
}
if (!existingValuesArrayList.contains(selectedRealmString.getValue())) {
//...
}