3

I am trying to save data into a RealmListafter calling a dialog box. The dialog is supposed to take the name of the new object, a FixtureInfo, add it to the RealmList, and then move to the next activity. However after moving to the next activity and pressing the back button the ListView populated with that RealmList doesn't show the object just created. There is no error it just doesn't show up. Any ideas?

EDIT added in RealmBaseAdapter as beeeneder suggest I do and problem persists.

first activity

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 class

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 class

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

}
JJ Stamp
  • 121
  • 2
  • 13
  • You are not saving anything to realm in `populateListView` inside the realm transaction, I don't quite get the point of `populateListView` . And to use Realm with ListView, `RealmBaseAdapter` would be a quite handy choice. See doc https://realm.io/docs/java/latest/api/io/realm/RealmBaseAdapter.html . And example: https://github.com/realm/realm-java/tree/master/examples/adapterExample – beeender Aug 11 '15 at 02:02
  • I'm using the realm transaction to add to the `RealmList` after the transaction I save using `SaveInfo()` – JJ Stamp Aug 11 '15 at 13:48
  • You didn't call `notifyDataSetChanged()` on `FixtureList`, the listview can never know you want to update it. And for the current code, i think even if you called that, the listview won't update as well since you didn't feed your adapter with new data. If you want to use the auto update feature from Realm, try to read those two links I put in the previous comment. – beeender Aug 11 '15 at 13:57
  • Created a `RealmBaseAdapter` but problem persists. I edited in my adapter and the implemented java file. Am I implementing incorrectly? – JJ Stamp Aug 11 '15 at 17:33
  • Hi, it is not quite easy to read the code on SO. I suggest you set a break pointer in `onClick` to check `fixtureInfo` you tried to add there. since the `RoomName` is the primary key, so if you are trying to change a `FixtrueInfo` with a different `RoomName` there, i don't expect you will see any changes in the listview since the `RealmResults` is based on the original name. And couple of other problems: 1. transaction is only needed for writing, no need for reading. 2. If the object is created by `Realm.createObject`, no need to call `copyToRealmOrUpdate` anymore. – beeender Aug 12 '15 at 04:05
  • I suggest you to spend a couple of more minutes on our examples https://github.com/realm/realm-java/tree/master/examples . And also, the mechanism behind the realm-java is that we using Proxy object to overload getters/setters. It is not difficult. You can find `FixtureInfoRealmProxy.java` in your build directory. It would be interesting and helpful to understand the whole thing, maybe you can have a quick look at that as well :) – beeender Aug 12 '15 at 04:10
  • That helped a bunch showing those links and walking through with me these things. Thank you, if you would like to you can post those links into an answer and I'll check it. Thanks so much for the help. – JJ Stamp Aug 12 '15 at 14:59

1 Answers1

0

I suggest you set a break pointer in onClick to check fixtureInfo you tried to add there. since the RoomName is the primary key, so if you are trying to change a FixtrueInfo with a different RoomName there, i don't expect you will see any changes in the ListView since the RealmResults is based on the original name.

And couple of other problems:

  1. transaction is only needed for writing, no need for reading.
  2. If the object is created by Realm.createObject, no need to call copyToRealmOrUpdate anymore

I suggest you to spend a couple of more minutes on our examples http://github.com/realm/realm-java/tree/master/examples . And also, the mechanism behind the realm-java is that we using Proxy object to overload getters/setters. It is not difficult. You can find FixtureInfoRealmProxy.java in your build directory. It would be interesting and helpful to understand the whole thing, maybe you can have a quick look at that as well :)

beeender
  • 3,555
  • 19
  • 32