2015-08-10 8 views
2

Я пытаюсь сохранить данные в RealmList после вызова диалогового окна. Диалог должен взять имя нового объекта, FixtureInfo, добавить его в RealmList, а затем перейти к следующему действию. Однако после перехода к следующему действию и нажатия кнопки «Назад» ListView, заполненный этим RealmList, не показывает только что созданный объект. Нет ошибки, она просто не появляется. Есть идеи?Данные Realm не сохраняются java

EDIT добавлено в RealmBaseAdapter как beeeneder, предлагаю, что у меня есть и проблема сохраняется.

первый активность

public class RoomDescription extends ActionBarActivity { 

    public AlertDialog.Builder dialogBuilder; 
    public RealmList<FixtureInfo> myFixtures = new RealmList<>(); 
    public String RoomName; 
    public String FixtureName; 
    public RealmList<Rooms> myRooms = new RealmList<>(); 
    private Realm realm; 
    public Rooms rooms; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_room_description); 

     //get room name 
     TextView textFixture = (TextView) findViewById(R.id.RoomName); 
     Bundle extras = getIntent().getExtras(); 
     if (extras != null) { 
      RoomName = extras.getString("txtString"); 
      textFixture.setText(RoomName); 
     } 


     //initiate realm instant to get CompanyInfo object, Room object, and populate myRoom and myFixtures 
     realm = Realm.getInstance(this); 
     rooms = realm.where(Rooms.class).equalTo("Name", RoomName).findFirst(); 
     realm.beginTransaction(); 
     CompanyInfo companyinfo = realm.where(CompanyInfo.class).findFirst(); 
     myRooms = companyinfo.getRooms(); 
     myFixtures = rooms.getFixtureInfos(); 
     realm.commitTransaction(); 
     populateListView(); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     LoadInfo(); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     SaveInfo(); 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     realm.close(); 
    } 

    private void setFixtureName() 
    { 
     //dialog to add fixture to room and set its name 
     dialogBuilder = new AlertDialog.Builder(this); 
     final EditText txtInput = new EditText(this); 


     dialogBuilder.setTitle("New Fixture"); 
     dialogBuilder.setMessage("What is the fixture name?"); 
     dialogBuilder.setView(txtInput); 
     dialogBuilder.setPositiveButton("Add", new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       //initiate realm instant 
       Realm realm = Realm.getInstance(getApplicationContext()); 
       realm.beginTransaction(); 
       //get fixture name and create FixtureInfo object 
       FixtureName = txtInput.getText().toString(); 
       FixtureInfo fixtureInfo = realm.createObject(FixtureInfo.class); 
       fixtureInfo.setName(FixtureName); 
       fixtureInfo.setRoomName(RoomName); 
       myFixtures.add(fixtureInfo); 
       realm.commitTransaction(); 
       //save changes 
       SaveInfo(); 
       //start new activity 
       Intent i = new Intent(RoomDescription.this, FixtureDescription.class); 
       i.putExtra("textString", FixtureName); 
       i.putExtra("txtString", RoomName); 
       populateListView(); 
       Toast.makeText(getApplicationContext(), "Fixture has been added.", Toast.LENGTH_SHORT).show(); 
       startActivity(i); 

      } 
     }); 
     dialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       SaveInfo(); 
      } 
     }); 

     AlertDialog dialogFixtureName = dialogBuilder.create(); 
     dialogFixtureName.show(); 
    } 

    private void setRoomName() 
    { 
     //same as setRoomName in RoomList.java 
     dialogBuilder = new AlertDialog.Builder(this); 
     final EditText txtInput = new EditText(this); 


     dialogBuilder.setTitle("New Room"); 
     dialogBuilder.setMessage("What is the room name?"); 
     dialogBuilder.setView(txtInput); 
     dialogBuilder.setPositiveButton("Add", new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       Realm realm = Realm.getInstance(getApplicationContext()); 
       realm.beginTransaction(); 
       String txtString = txtInput.getText().toString(); 
       Rooms rooms = realm.createObject(Rooms.class); 
       rooms.setName(txtString); 
       myRooms.add(rooms); 
       realm.commitTransaction(); 
       SaveInfo(); 
       realm.close(); 
       Intent i = new Intent(RoomDescription.this, RoomDescription.class); 
       i.putExtra("txtString", txtString); 
       Toast.makeText(getApplicationContext(), "Room has been added.", Toast.LENGTH_SHORT).show(); 
       populateListView(); 
       startActivity(i); 
      } 
     }); 
     dialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       SaveInfo(); 
      } 
     }); 

     AlertDialog dialogFixtureName = dialogBuilder.create(); 
     dialogFixtureName.show(); 
    } 

    private void removeFixture() 
    { 
     //remove fixture from room 
     dialogBuilder = new AlertDialog.Builder(this); 

     dialogBuilder.setTitle("Select Fixture to Remove"); 
     dialogBuilder.setSingleChoiceItems(myFixtures.toArray(new String[myFixtures.size()]), -1, new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       //initiate realm instant 
       Realm realm = Realm.getInstance(getApplicationContext()); 
       //remove fixture info from room 
       realm.beginTransaction(); 
       myFixtures = rooms.getFixtureInfos(); 
       myFixtures.remove(which); 
       //save change 
       SaveInfo(); 
       populateListView(); 
       Toast.makeText(getApplicationContext(), "Fixture has been removed.", Toast.LENGTH_SHORT).show(); 
       dialog.dismiss(); 
      } 
     }); 

     AlertDialog dialogFixtureName = dialogBuilder.create(); 
     dialogFixtureName.show(); 
    } 
    private void populateListView() 
    { 
     //on click for the list of FixtureInfo connected to the room 
     ListView list = (ListView) findViewById(R.id.FixtureList); 
     RealmResults<FixtureInfo> results = realm.where(FixtureInfo.class).equalTo("RoomName", RoomName).findAll(); 
     FixtureListAdapter adapter = new FixtureListAdapter(this, results, true); 
     list.setAdapter(adapter); 
     list.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       switch (position) { 
        default: 
         Intent i = new Intent(RoomDescription.this, FixtureDescription.class); 
         TextView textItem = (TextView) view; 
         String FixtureName = textItem.getText().toString(); 
         i.putExtra("textString", FixtureName); 
         i.putExtra("txtString", RoomName); 
         startActivity(i); 
         break; 
       } 

      } 

     }); 

    } 

    public void SaveInfo() 
    { 
     //save info or update info 
     realm.beginTransaction(); 
     rooms.setName(RoomName); 
     rooms.setFixtureInfos(myFixtures); 
     realm.copyToRealmOrUpdate(rooms); 
     realm.commitTransaction(); 
    } 

    public void LoadInfo() 
    { 
     //load info from specific room 
     realm.beginTransaction(); 
     myFixtures = rooms.getFixtureInfos(); 
     realm.commitTransaction(); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_room_description, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     switch (item.getItemId()) 
     { 
      case R.id.newFixture: 
       setFixtureName(); 
       break; 
      case R.id.removeFixture: 
       removeFixture(); 
       break; 
      case R.id.add: 
       setRoomName(); 
       break; 
      case R.id.home: 
       startActivity(new Intent(getApplicationContext(), MainPage.class)); 
       break; 
      case R.id.summary: 
       startActivity(new Intent(getApplicationContext(), Summary.class)); 
       break; 
     } 


     return super.onOptionsItemSelected(item); 
    } 
} 

RealmBaseAdapter класс

public class FixtureListAdapter extends RealmBaseAdapter<FixtureInfo> implements ListAdapter { 
    private static class ViewHolder{ 
     TextView FixtureName; 
    } 
    public FixtureListAdapter(Context context, RealmResults<FixtureInfo> realmResults, boolean automaticUpdate) { 
     super(context, realmResults, automaticUpdate); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     ViewHolder viewHolder; 
     if (convertView == null) { 
      convertView = inflater.inflate(android.R.layout.simple_list_item_1, 
        parent, false); 
      viewHolder = new ViewHolder(); 
      viewHolder.FixtureName = (TextView) convertView.findViewById(android.R.id.text1); 
      convertView.setTag(viewHolder); 
     } else { 
      viewHolder = (ViewHolder) convertView.getTag(); 
     } 

     FixtureInfo fixtureInfo = realmResults.get(position); 
     viewHolder.FixtureName.setText(fixtureInfo.getName()); 
     return convertView; 
    } 
} 

FixtureInfo класс

public class FixtureInfo extends RealmObject{ 
    @PrimaryKey 
    private String RoomName; 
    @Ignore 
    private String Name; 
    private String Description; 
    private String Wattage; 
    private String Run_Time; 
    private String Bulbs_Out; 
    private String Notes; 
    private int Count; 

    public String getRoomName() { 
     return RoomName; 
    } 

    public void setRoomName(String roomName) { 
     RoomName = roomName; 
    } 
    public void setCount(int count) { 
     Count = count; 
    } 

    public int getCount() { 
     return Count; 
    } 

    public void setName(String name) { 
     Name = name; 
    } 

    public void setDescription(String description) { 
     Description = description; 
    } 

    public void setWattage(String wattage) { 
     Wattage = wattage; 
    } 

    public void setRun_Time(String run_Time) { 
     Run_Time = run_Time; 
    } 

    public void setBulbs_Out(String bulbs_Out) { 
     Bulbs_Out = bulbs_Out; 
    } 

    public void setNotes(String notes) { 
     Notes = notes; 
    } 

    public String getName() { 
     return Name; 
    } 

    public String getDescription() { 
     return Description; 
    } 

    public String getWattage() { 
     return Wattage; 
    } 

    public String getRun_Time() { 
     return Run_Time; 
    } 

    public String getBulbs_Out() { 
     return Bulbs_Out; 
    } 

    public String getNotes() { 
     return Notes; 
    } 

} 
+0

Вы ничего не спасаете в царстве в 'populateListView' внутри транзакции realm, я не совсем понимаю точка 'populateListView'. И использовать Realm с ListView, «RealmBaseAdapter» было бы весьма удобным выбором. См. Doc https://realm.io/docs/java/latest/api/io/realm/RealmBaseAdapter.html. Пример: https://github.com/realm/realm-java/tree/master/examples/adapterExample – beeender

+0

Я использую транзакцию realm для добавления в 'RealmList' после транзакции, которую я сохраняю, используя' SaveInfo() ' –

+0

Вы не вызывали 'notifyDataSetChanged()' на 'FixtureList', список не может знать, что вы хотите его обновить. И для текущего кода, я думаю, даже если вы его вызвали, список не будет обновляться, так как вы не кормите свой адаптер новыми данными. Если вы хотите использовать функцию автоматического обновления в Realm, попробуйте прочитать те две ссылки, которые я добавил в предыдущем комментарии. – beeender

ответ

0

Я предлагаю вам установить указатель перерыв в onClick проверить fixtureInfo вы пытались добавить туда. так как RoomName является первичным ключом, поэтому, если вы пытаетесь изменить FixtrueInfo с другим RoomName, я не ожидаю, что вы увидите изменения в ListView, так как RealmResults основан на исходном имени.

И несколько других проблем:

  1. сделки требуется только для записи, нет необходимости в чтении.
  2. Если объект создается Realm.createObject, нет необходимости вызывать copyToRealmOrUpdate больше

Я предлагаю вам провести еще пару минут на наших примерах http://github.com/realm/realm-java/tree/master/examples. А также механизм, лежащий в основе realm-java, заключается в том, что мы используем объект Proxy для перегрузки getters/seters. Это не сложно. Вы можете найти FixtureInfoRealmProxy.java в каталоге сборки. Было бы интересно и полезно понять все это, может быть, вы тоже можете быстро взглянуть на это :)

Смежные вопросы