0

I am developing a notes application, in which users creates a note, upon saving the note, the note is saved and displayed in the recyclerview. I am looking for something which displays which shows the date on the day the note is created. I have instantiated the calender in adapter class and did set the date. The problem is all the cards are having today's date irrespective of the date created. Like in the following picture Screenshot of emulator

Below is my adapter class

 package com.cksapp.mvvmarchitecture;
    
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.PopupMenu;
    import android.widget.TextView;
    
    import androidx.annotation.NonNull;
    import androidx.recyclerview.widget.RecyclerView;
    
    import java.text.DateFormat;
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.List;
    
    public class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.NoteHolder> {
    
        private static List<Note> notes = new ArrayList<>();
        private onItemClicklistener listener;
        private onItemClicklistener1 listener1;
        private onItemClicklistener2 listener2;
        private onItemClicklistener3 listener3;
    
        private NoteViewModel noteViewModel;
    
        @NonNull
        @Override
        public NoteHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.note_item,parent,false);
            return new NoteHolder(itemView);
    
        }
    
        @Override
        public void onBindViewHolder(@NonNull NoteHolder holder, final int position) {
            final Note currentNote = notes.get(position);
            holder.textViewTitle.setText(currentNote.getTitle());
            holder.textViewDescription.setText(currentNote.getDescription());
            Calendar c = Calendar.getInstance();**//calender instantiation**
            String currentDate = DateFormat.getDateInstance().format(c.getTime());
            holder.textViewdate.setText(currentDate);
    
    
        }
        private void deleteItem(int position) {
           noteViewModel.delete(notes.get(position));
        }
    
        @Override
        public int getItemCount() {
            return notes.size();
        }
    
        public void setNotes(List<Note> notes){
            this.notes = notes;
            notifyDataSetChanged();
        }
        public Note getNoteAt(int position){
            return notes.get(position);
        }
    
        class NoteHolder extends RecyclerView.ViewHolder{
            private TextView textViewTitle, textViewdate;
            private TextView textViewDescription;
            private ImageView menupopup;
    
    
            public NoteHolder(@NonNull View itemView) {
                super(itemView);
                textViewTitle = itemView.findViewById(R.id.text_view_title);
                textViewDescription = itemView.findViewById(R.id.text_view_description);
                textViewdate = itemView.findViewById(R.id.datetext);
                menupopup = itemView.findViewById(R.id.options);
                menupopup.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
    
                        PopupMenu popupMenu = new PopupMenu(v.getContext(), v);
                        popupMenu.getMenuInflater().inflate(R.menu.popup_menu, popupMenu.getMenu());
                        popupMenu.show();
                        popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                            @Override
                            public boolean onMenuItemClick(MenuItem item) {
                                final int position1 = getAdapterPosition();
    
                                switch (item.getItemId()){
                                    case R.id.opennotemenu:
                                        if(position1 != RecyclerView.NO_POSITION && listener1 != null) {
                                            listener2.onItemclick2(notes.get(position1));
                                        }
                                        break;
                                    case R.id.editmenu:
                                        if(position1 != RecyclerView.NO_POSITION && listener1 != null) {
                                            listener1.onItemclick1(notes.get(position1));
                                        }
                                        break;
                                    case R.id.deletemenu:
                                        if(position1 != RecyclerView.NO_POSITION && listener != null) {
                                            listener.onItemclick(notes.get(position1));
                                        }
                                        break;
                                    case R.id.sharenote:
                                        if(position1 != RecyclerView.NO_POSITION && listener3 != null) {
                                            listener3.onItemclick3(notes.get(position1));
                                        }
                                }
                                return true;
                            }
                        });
                    }
                });
    
            }
        }
        public interface onItemClicklistener{
            void onItemclick(Note note);
        }
        public void setonItemClicklistener(onItemClicklistener listener){
            this.listener = listener;
    
        }
        public interface onItemClicklistener1{
            void onItemclick1(Note note);
        }
        public void setonItemClicklistener1(onItemClicklistener1 listener1){
            this.listener1 = listener1;
    
        }
        public interface onItemClicklistener2{
            void onItemclick2(Note note);
        }
        public void setonItemClicklistener2(onItemClicklistener2 listener2){
            this.listener2 =  listener2;
        }
        public interface onItemClicklistener3{
            void onItemclick3(Note note);
        }
        public void setonItemClicklistener3(onItemClicklistener3 listener3){
            this.listener3 = listener3;
        }
    }




**My add note activity**

package com.cksapp.mvvmarchitecture;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.NumberPicker;
import android.widget.Toast;

import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;

public class NewActivityNote extends AppCompatActivity {
    EditText title, description;

    public static final String EXTRA_TITLE = "com.cksapp.mvvmarchitecture.EXTRA_TITLE";
    public static final String EXTRA_ID = "com.cksapp.mvvmarchitecture.EXTRA_ID";
    public static final String EXTRA_DESCRIPTION = "com.cksapp.mvvmarchitecture.EXTRA_DESCRIPTION";
    String currentDate;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_note);
        title = findViewById(R.id.title1);
        description = findViewById(R.id.description1);
        getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close);

        Intent intent = getIntent();
        if(intent.hasExtra(EXTRA_ID)){
            setTitle("Edit Note");
            title.setText(intent.getStringExtra(EXTRA_TITLE));
            description.setText(intent.getStringExtra(EXTRA_DESCRIPTION));
        }

        setTitle("Add Note");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.new_note, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()){
            case R.id.save:
                savenote();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
       
    }

    private void savenote() {
        String title1 = title.getText().toString();
        String description1 = description.getText().toString();


        if(title1.trim().isEmpty() || description1.trim().isEmpty()){
            Toast.makeText(NewActivityNote.this, "Enter title and description",Toast.LENGTH_SHORT).show();
            return;
        }

        Intent data = new Intent();
        data.putExtra(EXTRA_TITLE, title1);
        data.putExtra(EXTRA_DESCRIPTION, description1);


        int id = getIntent().getIntExtra(EXTRA_ID, -1);
        if(id != -1){
            data.putExtra(EXTRA_ID, id);
        }


        setResult(RESULT_OK, data);
        finish();
    }

    public void doSave(View view) {
        savenote();
    }
}

Like you suggested, my changes in the project are, Here is the converter class I added

    import androidx.room.TypeConverter;

import java.sql.Date;


public class Converters {
    @TypeConverter
    public static Date fromTimestamp(Long value) {
        return value == null ? null : new Date(value);
    }

    @TypeConverter
    public static Long dateToTimestamp(Date date) {
        return date == null ? null : date.getTime();
    }
}

I have added date object in entity class

import androidx.room.Entity;
import androidx.room.PrimaryKey;

import java.sql.Date;


@Entity(tableName = "note_table")
public class Note {
    @PrimaryKey(autoGenerate = true)
    private int id;
    private String title;
    private String description;
    private Date date;



    public Note(String title, String description) {
        this.title = title;
        this.description = description;

    }
   public void setDate(Date date){
        this.date = date;
   }

   public Date getDate(){
        return date;
   }

    public void setId(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }


    public String getDescription() {
        return description;
    }

}

The below is my NewNoteActivity savenote method in which I want to record the date

private void savenote() {
        String title1 = title.getText().toString();
        String description1 = description.getText().toString();
        Date date = Calendar.getInstance().getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
        currentDate = sdf.format(date);

And next I tried to access the currentDate string into my adapter class to set the date

 @Override
    public void onBindViewHolder(@NonNull NoteHolder holder, final int position) {
        final Note currentNote = notes.get(position);
        holder.textViewTitle.setText(currentNote.getTitle());
        holder.textViewDescription.setText(currentNote.getDescription());
        NewActivityNote n = new NewActivityNote();
        String date = n.currentDate;
        holder.textViewdate.setText(date);

And finally it is giving me null in place of date textview. The textview is finally set to nothing(empty)

The screenshot of my emulator after performing above tasks result

Below is my complete NewNoteActivity

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.NumberPicker;
import android.widget.TextView;
import android.widget.Toast;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class NewActivityNote extends AppCompatActivity {
    EditText title, description;

    public static final String EXTRA_TITLE = "com.cksapp.mvvmarchitecture.EXTRA_TITLE";
    public static final String EXTRA_ID = "com.cksapp.mvvmarchitecture.EXTRA_ID";
    public static final String EXTRA_DESCRIPTION = "com.cksapp.mvvmarchitecture.EXTRA_DESCRIPTION";
    String currentDate;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_note);
        title = findViewById(R.id.title1);
        description = findViewById(R.id.description1);
        getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close);

        Intent intent = getIntent();
        if(intent.hasExtra(EXTRA_ID)){
            setTitle("Edit Note");
            title.setText(intent.getStringExtra(EXTRA_TITLE));
            description.setText(intent.getStringExtra(EXTRA_DESCRIPTION));
        }

        setTitle("Add Note");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.new_note, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()){
            case R.id.save:
                savenote();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
       
    }

    private void savenote() {
        String title1 = title.getText().toString();
        String description1 = description.getText().toString();
        Date date = Calendar.getInstance().getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
        currentDate = sdf.format(date);



        if(title1.trim().isEmpty() || description1.trim().isEmpty()){
            LayoutInflater inflater = getLayoutInflater();
            View layout = inflater.inflate(R.layout.toast_custom, (ViewGroup) findViewById(R.id.toastlayout));
            TextView t1 = layout.findViewById(R.id.toasttext);
            ImageView i1 = layout.findViewById(R.id.toastimage);
            t1.setText("Enter title and description");
            i1.setImageResource(R.drawable.ic_error);
            Toast toast = new Toast(getApplicationContext());
            toast.setGravity(Gravity.CENTER, 0, 0);
            toast.setDuration(Toast.LENGTH_LONG);
            toast.setView(layout);
            toast.show();
            return;
        }

        Intent data = new Intent();
        data.putExtra(EXTRA_TITLE, title1);
        data.putExtra(EXTRA_DESCRIPTION, description1);


        int id = getIntent().getIntExtra(EXTRA_ID, -1);
        if(id != -1){
            data.putExtra(EXTRA_ID, id);
        }
        LayoutInflater inflater = getLayoutInflater();
        View layout = inflater.inflate(R.layout.toast_custom, (ViewGroup) findViewById(R.id.toastlayout));
        TextView t1 = layout.findViewById(R.id.toasttext);
        ImageView i1 = layout.findViewById(R.id.toastimage);
        t1.setText("Enjoy, Note saved to your collections!");
        i1.setImageResource(R.drawable.ic_check);
        Toast toast = new Toast(getApplicationContext());
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.setDuration(Toast.LENGTH_LONG);
        toast.setView(layout);
        toast.show();


        setResult(RESULT_OK, data);
        finish();
    }

    public void doSave(View view) {
        savenote();
    }
}

My Dao class

package com.cksapp.mvvmarchitecture;

import androidx.lifecycle.LiveData;

import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;

import androidx.room.Update;

import java.util.List;

@Dao
public interface NoteDao {

    @Insert
    void insert(Note note);

    @Update
    void update(Note note);

    @Delete
    void delete(Note note);

    @Query("DELETE FROM note_table")
    void deleteAllNotes();



    @Query("Select * from note_table order by id desc")
    LiveData<List<Note>> getAllNotes();
}
  • with your current implementation they all will have the same time displayed, because you're making an instance of the calendar as they're bound, you're not getting the time from the actual individual `Note` object – a_local_nobody Sep 02 '20 at 09:22
  • I have tried to extract the time from NewActivityNote by instantiating calender class but I am getting null, not the desired date. Thanks – Chandrakishore Reddy Sep 02 '20 at 10:03

1 Answers1

0

As has been pointed out, you need to save the date in your note entity.

If you are interested in recommended ways to get the time, read this answer.

You should then be converting your time to a Long and save it (in your note class) to the database. Then when displaying the date you have to convert the number back to a formatted date.

It is also possible to let Room handle your complex objects that carry information about the time, such as the Date class (which is returned by your c.getTime() call). As an example for saving a Date object to your database you can define a simple converter class as in this example from the documentation.

cewaphi
  • 410
  • 2
  • 7
  • Thanks for that @cewaphi Do I also have to save date object in the constructor of note entity?. Thanks! – Chandrakishore Reddy Sep 04 '20 at 01:50
  • By "saving the date object in the constructor" you mean that the constructor of your class takes a `Date` type variable as input parameter and thus your entity has a member variable of type `Date`? If you want to save this to your Room database you will need to create a converter class as mentioned above. Otherwise, Room can only handle primitive types, such as `String` and `Boolean` – cewaphi Sep 04 '20 at 09:48
  • Kindly go through my changes @cewaphi Thanks for your time! – Chandrakishore Reddy Sep 04 '20 at 15:08
  • May I ask why you are trying to create an instance of an activity for the date instead of accessing the date from your `currentNote`? Is your `savenote` method complete there? I do not see any saving operation take place – cewaphi Sep 04 '20 at 21:46
  • Am doing it because I wanted to save the date on which the user has clicked the save button. It is a method in new note activity. I think it becomes clear if I add full new note activity class. @cewaphi – Chandrakishore Reddy Sep 05 '20 at 04:24
  • I only see you are getting a date to a string. But after that nothing happens with that string? Then you are returning the data in an intent for an activity that is waiting for a result? Firstly, you are not returning the date there. Secondly, where is this data actually saved to the database? – cewaphi Sep 05 '20 at 07:06
  • So I must also give u my Dao class, that answers ua question. Am not quite sure abt how to save to database and accessing it here. I will share my dao too. – Chandrakishore Reddy Sep 05 '20 at 14:45
  • I didn't specifically mean your `Dao` class. What I meant is the following. You have your date formatted as a `String` here `currentDate = sdf.format(date);` But I do not see where you are saving it. I assumed your `Dao` implementation to be like this. But where do you call your `Dao`? Where do you save the information that you assigned to `currentDate` to the data base? – cewaphi Sep 05 '20 at 16:20
  • I believe, I haven't saved that in database(i.e Dao class). I am not quite sure how to save that in to database. I request you to guide me through thanks. – Chandrakishore Reddy Sep 07 '20 at 08:30
  • I have included in the constructor the date string and added getter setter for date string and along with other attributes like title and description, date is also inserted into database and I accessed it where I needed. Your questions made me debug myself and resolved it. Thanks very much for your time. Cheers! – Chandrakishore Reddy Sep 07 '20 at 10:42
  • Congratulations! I am glad my suggestions helped you to answer your question. Can you accept the answer for closing the question then? – cewaphi Sep 07 '20 at 11:08
  • yeah sure no problem – Chandrakishore Reddy Sep 07 '20 at 11:11