#12 Time Headers in List-View (Today, Yesterday, ...)

This commit is contained in:
Stefan Niedermann 2015-10-23 13:32:15 +02:00
parent ef67a889ec
commit ec062ead7d
12 changed files with 203 additions and 82 deletions

View file

@ -17,11 +17,13 @@ import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener; import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListView; import android.widget.ListView;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.model.Item;
import it.niedermann.owncloud.notes.model.ItemAdapter;
import it.niedermann.owncloud.notes.model.Note; import it.niedermann.owncloud.notes.model.Note;
import it.niedermann.owncloud.notes.model.NoteAdapter;
import it.niedermann.owncloud.notes.persistence.NoteSQLiteOpenHelper; import it.niedermann.owncloud.notes.persistence.NoteSQLiteOpenHelper;
import it.niedermann.owncloud.notes.util.ICallback; import it.niedermann.owncloud.notes.util.ICallback;
@ -39,7 +41,7 @@ public class NotesListViewActivity extends AppCompatActivity implements
private final static int about = 3; private final static int about = 3;
private ListView listView = null; private ListView listView = null;
private NoteAdapter adapter = null; private ItemAdapter adapter = null;
private ActionMode mActionMode; private ActionMode mActionMode;
private SwipeRefreshLayout swipeRefreshLayout = null; private SwipeRefreshLayout swipeRefreshLayout = null;
private NoteSQLiteOpenHelper db = null; private NoteSQLiteOpenHelper db = null;
@ -103,7 +105,31 @@ public class NotesListViewActivity extends AppCompatActivity implements
*/ */
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
public void setListView(List<Note> noteList) { public void setListView(List<Note> noteList) {
adapter = new NoteAdapter(getApplicationContext(), noteList); List<Item> itemList = new ArrayList<>();
/*
//TODO Implement #12
itemList.add(new SectionItem(getResources().getString(R.string.listview_updated_recent)));
if(noteList.size() > 0) {
itemList.add(noteList.get(0));
}
Calendar yesterday = Calendar.getInstance();
yesterday.set(Calendar.HOUR_OF_DAY, 0);
yesterday.set(Calendar.MINUTE, 0);
yesterday.set(Calendar.SECOND, 0);
yesterday.set(Calendar.MILLISECOND, 0);
boolean yesterdaySet = false;
for(int i = 1; i < noteList.size(); i++) {
if (!yesterdaySet && noteList.get(i).getModified().before(yesterday)) {
itemList.add(new SectionItem(getResources().getString(R.string.listview_updated_yesterday)));
yesterdaySet = true;
}
itemList.add(noteList.get(i));
}*/
itemList.addAll(noteList);
adapter = new ItemAdapter(getApplicationContext(), itemList);
listView = (ListView) findViewById(R.id.list_view); listView = (ListView) findViewById(R.id.list_view);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setAdapter(adapter); listView.setAdapter(adapter);
@ -130,13 +156,15 @@ public class NotesListViewActivity extends AppCompatActivity implements
removeSelection(); removeSelection();
Intent intent = new Intent(getApplicationContext(), Intent intent = new Intent(getApplicationContext(),
NoteActivity.class); NoteActivity.class);
Note note = adapter.getItem(position); Item item = adapter.getItem(position);
intent.putExtra(SELECTED_NOTE, note); if (!item.isSection()) {
intent.putExtra(SELECTED_NOTE_POSITION, position); intent.putExtra(SELECTED_NOTE, (Note) item);
Log.v("Note", intent.putExtra(SELECTED_NOTE_POSITION, position);
"notePosition | NotesListViewActivity wurde abgesendet " Log.v("Note",
+ position); "notePosition | NotesListViewActivity wurde abgesendet "
startActivityForResult(intent, show_single_note_cmd); + position);
startActivityForResult(intent, show_single_note_cmd);
}
} else { // perform long click if already something is selected } else { // perform long click if already something is selected
onListItemSelect(position); onListItemSelect(position);
} }
@ -285,7 +313,7 @@ public class NotesListViewActivity extends AppCompatActivity implements
.getCheckedItemPositions(); .getCheckedItemPositions();
for (int i = (checkedItemPositions.size() - 1); i >= 0; i--) { for (int i = (checkedItemPositions.size() - 1); i >= 0; i--) {
if (checkedItemPositions.valueAt(i)) { if (checkedItemPositions.valueAt(i)) {
Note note = adapter.getItem(checkedItemPositions Note note = (Note) adapter.getItem(checkedItemPositions
.keyAt(i)); .keyAt(i));
db.deleteNoteAndSync(note.getId()); db.deleteNoteAndSync(note.getId());
adapter.remove(note); adapter.remove(note);

View file

@ -10,12 +10,14 @@ import android.widget.AdapterView;
import android.widget.ListView; import android.widget.ListView;
import android.widget.RemoteViews; import android.widget.RemoteViews;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.android.widget.SingleNoteWidget; import it.niedermann.owncloud.notes.android.widget.SingleNoteWidget;
import it.niedermann.owncloud.notes.model.Item;
import it.niedermann.owncloud.notes.model.ItemAdapter;
import it.niedermann.owncloud.notes.model.Note; import it.niedermann.owncloud.notes.model.Note;
import it.niedermann.owncloud.notes.model.NoteAdapter;
import it.niedermann.owncloud.notes.persistence.NoteSQLiteOpenHelper; import it.niedermann.owncloud.notes.persistence.NoteSQLiteOpenHelper;
/** /**
@ -27,7 +29,7 @@ public class SelectSingleNoteActivity extends AppCompatActivity implements Adapt
int appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; int appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
private NoteSQLiteOpenHelper db = null; private NoteSQLiteOpenHelper db = null;
private ListView listView = null; private ListView listView = null;
private NoteAdapter adapter = null; private ItemAdapter adapter = null;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@ -60,7 +62,9 @@ public class SelectSingleNoteActivity extends AppCompatActivity implements Adapt
* @param noteList List&lt;Note&gt; * @param noteList List&lt;Note&gt;
*/ */
private void setListView(List<Note> noteList) { private void setListView(List<Note> noteList) {
adapter = new NoteAdapter(getApplicationContext(), noteList); List<Item> itemList = new ArrayList<>();
itemList.addAll(noteList);
adapter = new ItemAdapter(getApplicationContext(), itemList);
listView = (ListView) findViewById(R.id.select_single_note_list_view); listView = (ListView) findViewById(R.id.select_single_note_list_view);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setAdapter(adapter); listView.setAdapter(adapter);
@ -75,7 +79,7 @@ public class SelectSingleNoteActivity extends AppCompatActivity implements Adapt
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_single_note); RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_single_note);
appWidgetManager.updateAppWidget(appWidgetId, views); appWidgetManager.updateAppWidget(appWidgetId, views);
SingleNoteWidget.updateAppWidget(adapter.getItem(position), context, appWidgetManager, appWidgetId); SingleNoteWidget.updateAppWidget((Note) adapter.getItem(position), context, appWidgetManager, appWidgetId);
Intent resultValue = new Intent(); Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);

View file

@ -88,7 +88,7 @@ public class AllNotesWidget extends AppWidgetProvider {
public RemoteViews getViewAt(int position) { public RemoteViews getViewAt(int position) {
// Construct a remote views item based on the app widget item XML file, // Construct a remote views item based on the app widget item XML file,
// and set the text based on the position. // and set the text based on the position.
RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.fragment_notes_list_view); RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.fragment_notes_list_note_item);
rv.setTextViewText(R.id.list_view, mWidgetItems.get(position).getTitle()); rv.setTextViewText(R.id.list_view, mWidgetItems.get(position).getTitle());
// Return the remote views object. // Return the remote views object.

View file

@ -0,0 +1,8 @@
package it.niedermann.owncloud.notes.model;
/**
* Created by stefan on 23.10.15.
*/
public interface Item {
boolean isSection();
}

View file

@ -0,0 +1,78 @@
package it.niedermann.owncloud.notes.model;
import android.content.Context;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.List;
import it.niedermann.owncloud.notes.R;
public class ItemAdapter extends ArrayAdapter<Item> {
private List<Item> itemList = null;
public ItemAdapter(Context context, List<Item> itemList) {
super(context, android.R.layout.simple_list_item_1, itemList);
this.itemList = itemList;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
Item item = itemList.get(position);
if (item.isSection()) {
// first check to see if the view is null. if so, we have to inflate it.
// to inflate it basically means to render, or show, the view.
if (v == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.fragment_notes_list_section_item, null);
}
SectionItem section = (SectionItem) item;
TextView sectionTitle = (TextView) v.findViewById(R.id.sectionTitle);
sectionTitle.setText(section.geTitle());
} else {
// first check to see if the view is null. if so, we have to inflate it.
// to inflate it basically means to render, or show, the view.
if (v == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.fragment_notes_list_note_item, null);
}
/*
* Recall that the variable position is sent in as an argument to this
* method. The variable simply refers to the position of the current
* object in the list. (The ArrayAdapter iterates through the list we
* sent it)
*
* Therefore, i refers to the current Item object.
*/
Note note = (Note) item;
if (note != null) {
// This is how you obtain a reference to the TextViews.
// These TextViews are created in the XML files we defined.
TextView noteTitle = (TextView) v.findViewById(R.id.noteTitle);
TextView noteExcerpt = (TextView) v
.findViewById(R.id.noteExcerpt);
TextView noteModified = (TextView) v.findViewById(R.id.noteModified);
noteTitle.setText(note.getTitle());
noteExcerpt.setText(note.getExcerpt());
noteModified.setText(DateUtils.getRelativeDateTimeString(getContext(), note.getModified().getTimeInMillis(), DateUtils.MINUTE_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, 0));
}
}
// the view must be returned to our activity
return v;
}
}

View file

@ -9,8 +9,8 @@ import it.niedermann.owncloud.notes.persistence.NoteSQLiteOpenHelper;
import it.niedermann.owncloud.notes.util.NoteUtil; import it.niedermann.owncloud.notes.util.NoteUtil;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class Note implements Serializable { public class Note implements Item, Serializable {
private long id = 0; private long id = 0;
private String title = ""; private String title = "";
private Calendar modified = null; private Calendar modified = null;
private String content = ""; private String content = "";
@ -77,4 +77,9 @@ public class Note implements Serializable {
public String toString() { public String toString() {
return "#" + getId() + " " + getTitle() + " (" + getModified(NoteSQLiteOpenHelper.DATE_FORMAT) + ")"; return "#" + getId() + " " + getTitle() + " (" + getModified(NoteSQLiteOpenHelper.DATE_FORMAT) + ")";
} }
@Override
public boolean isSection() {
return false;
}
} }

View file

@ -1,64 +0,0 @@
package it.niedermann.owncloud.notes.model;
import android.content.Context;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.List;
import it.niedermann.owncloud.notes.R;
public class NoteAdapter extends ArrayAdapter<Note> {
private List<Note> noteList = null;
public NoteAdapter(Context context,
List<Note> noteList) {
super(context, android.R.layout.simple_list_item_1, noteList);
this.noteList = noteList;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
// first check to see if the view is null. if so, we have to inflate it.
// to inflate it basically means to render, or show, the view.
if (v == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.fragment_notes_list_view, null);
}
/*
* Recall that the variable position is sent in as an argument to this
* method. The variable simply refers to the position of the current
* object in the list. (The ArrayAdapter iterates through the list we
* sent it)
*
* Therefore, i refers to the current Item object.
*/
Note note = noteList.get(position);
if (note != null) {
// This is how you obtain a reference to the TextViews.
// These TextViews are created in the XML files we defined.
TextView noteTitle = (TextView) v.findViewById(R.id.noteTitle);
TextView noteExcerpt = (TextView) v
.findViewById(R.id.noteExcerpt);
TextView noteModified = (TextView) v.findViewById(R.id.noteModified);
noteTitle.setText(note.getTitle());
noteExcerpt.setText(note.getExcerpt());
noteModified.setText(DateUtils.getRelativeDateTimeString(getContext(), note.getModified().getTimeInMillis(), DateUtils.MINUTE_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, 0));
}
// the view must be returned to our activity
return v;
}
}

View file

@ -0,0 +1,25 @@
package it.niedermann.owncloud.notes.model;
/**
* Created by stefan on 23.10.15.
*/
public class SectionItem implements Item {
String title = "";
public SectionItem(String title) {
this.title = title;
}
public String geTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Override
public boolean isSection() {
return true;
}
}

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/sectionItem"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:background="@color/bg_highlighted"
android:padding="8dp">
<TextView
android:id="@+id/sectionTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="false"
android:layout_alignParentRight="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_alignWithParentIfMissing="true"
android:ellipsize="end"
android:gravity="center_vertical"
android:textColor="@drawable/list_item_color_selector"
android:textSize="14sp" />
</RelativeLayout>

View file

@ -20,6 +20,13 @@
<string name="copy">Kopie</string> <string name="copy">Kopie</string>
<string name="listview_updated_recent">Kürzlich aktualisiert</string>
<string name="listview_updated_today">Heute aktualisiert</string>
<string name="listview_updated_yesterday">Gestern aktualisiert</string>
<string name="listview_updated_this_week">Diese Woche aktualisiert</string>
<string name="listview_updated_this_month">Diesen Monat aktualisiert</string>
<string name="listview_updated_earlier">Früher aktualisiert</string>
<!-- About --> <!-- About -->
<string name="about_version_title">Version</string> <string name="about_version_title">Version</string>

View file

@ -20,6 +20,13 @@
<string name="copy">Copy</string> <string name="copy">Copy</string>
<string name="listview_updated_recent">Updated recently</string>
<string name="listview_updated_today">Updated today</string>
<string name="listview_updated_yesterday">Updated yesterday</string>
<string name="listview_updated_this_week">Updated this week</string>
<string name="listview_updated_this_month">Updated this month</string>
<string name="listview_updated_earlier">Updated earlier</string>
<!-- About --> <!-- About -->
<string name="about_version_title">Version</string> <string name="about_version_title">Version</string>