diff --git a/app/src/main/java/org/houxg/leamonax/adapter/NoteAdapter.java b/app/src/main/java/org/houxg/leamonax/adapter/NoteAdapter.java index e24f741..f9f4e44 100644 --- a/app/src/main/java/org/houxg/leamonax/adapter/NoteAdapter.java +++ b/app/src/main/java/org/houxg/leamonax/adapter/NoteAdapter.java @@ -12,16 +12,23 @@ import android.text.style.BackgroundColorSpan; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageView; import android.widget.TextView; +import com.bumptech.glide.Glide; + import org.houxg.leamonax.R; import org.houxg.leamonax.database.AppDataBase; import org.houxg.leamonax.model.Note; +import org.houxg.leamonax.model.NoteFile; import org.houxg.leamonax.model.Notebook; import org.houxg.leamonax.service.AccountService; +import org.houxg.leamonax.service.NoteFileService; +import org.houxg.leamonax.utils.FileUtils; import org.houxg.leamonax.utils.TimeUtils; import org.houxg.leamonax.widget.NoteList; +import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -34,6 +41,7 @@ import butterknife.ButterKnife; public class NoteAdapter extends RecyclerView.Adapter { + public static final int TYPE_DETAIL_PLACEHOLDER = 233; private List mData; private Map mNotebookId2TitleMaps; @@ -41,6 +49,7 @@ public class NoteAdapter extends RecyclerView.Adapter { private Pattern mTitleHighlight; private int mCurrentType = NoteList.TYPE_SIMPLE; private List mSelectedNotes = new ArrayList<>(); + private boolean isScrolling = false; public NoteAdapter(NoteAdapterListener listener) { mListener = listener; @@ -60,6 +69,10 @@ public class NoteAdapter extends RecyclerView.Adapter { } } + public void setScrolling(boolean scrolling) { + isScrolling = scrolling; + } + public void setType(int type) { mCurrentType = type; } @@ -81,12 +94,15 @@ public class NoteAdapter extends RecyclerView.Adapter { @Override public NoteAdapter.NoteHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = null; + int layoutId = -1; if (viewType == NoteList.TYPE_SIMPLE) { - view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_note_simple, parent, false); + layoutId = R.layout.item_note_simple; } else if (viewType == NoteList.TYPE_DETAIL) { - view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_note, parent, false); + layoutId = R.layout.item_note; + } else if (viewType == TYPE_DETAIL_PLACEHOLDER) { + layoutId = R.layout.item_note_detail_placeholder; } + View view = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false); return new NoteHolder(view); } @@ -100,50 +116,29 @@ public class NoteAdapter extends RecyclerView.Adapter { @Override public int getItemViewType(int position) { - return mCurrentType; + if (isScrolling && mCurrentType == NoteList.TYPE_DETAIL) { + return TYPE_DETAIL_PLACEHOLDER; + } else { + return mCurrentType; + } } @Override public void onBindViewHolder(NoteAdapter.NoteHolder holder, int position) { final Note note = mData.get(position); - if (getItemViewType(position) == NoteList.TYPE_DETAIL) { - renderDetail(holder, note); - } else { - renderSimple(holder, note); + int type = getItemViewType(position); + switch (type) { + case NoteList.TYPE_DETAIL: + case TYPE_DETAIL_PLACEHOLDER: + renderDetailMeta(holder, note); + if (type == NoteList.TYPE_DETAIL) { + renderDetailContent(holder, note); + } + break; + case NoteList.TYPE_SIMPLE: + renderSimple(holder, note); + break; } - holder.container.setSelected(mSelectedNotes.contains(note.getId())); - } - - private void renderDetail(NoteHolder holder, final Note note) { - if (TextUtils.isEmpty(note.getTitle())) { - holder.titleTv.setText(R.string.untitled); - } else { - holder.titleTv.setText(getHighlightedText(note.getTitle())); - } - if (note.isMarkDown()) { - holder.contentTv.setText(note.getContent()); - } else { - Spanned spannedContent = Html.fromHtml(note.getContent()); - String contentStr = spannedContent.toString(); - contentStr = contentStr.replaceAll("\\n\\n+", "\n"); - holder.contentTv.setText(contentStr); - } - - holder.notebookTv.setText(mNotebookId2TitleMaps.get(note.getNoteBookId())); - long updateTime = note.getUpdatedTimeVal(); - Context context = holder.updateTimeTv.getContext(); - String time; - if (updateTime >= TimeUtils.getToday().getTimeInMillis()) { - time = TimeUtils.toTimeFormat(updateTime); - } else if (updateTime >= TimeUtils.getYesterday().getTimeInMillis()) { - time = context.getString(R.string.time_yesterday, TimeUtils.toTimeFormat(updateTime)); - } else if (updateTime >= TimeUtils.getThisYear().getTimeInMillis()) { - time = TimeUtils.toDateFormat(updateTime); - } else { - time = TimeUtils.toYearFormat(updateTime); - } - holder.updateTimeTv.setText(time); - holder.dirtyTv.setVisibility(note.isDirty() ? View.VISIBLE : View.GONE); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -161,6 +156,59 @@ public class NoteAdapter extends RecyclerView.Adapter { return true; } }); + holder.container.setSelected(mSelectedNotes.contains(note.getId())); + } + + private void renderDetailMeta(NoteHolder holder, final Note note) { + if (holder.imageView != null) { + holder.imageView.setImageDrawable(null); + } + if (TextUtils.isEmpty(note.getTitle())) { + holder.titleTv.setText(R.string.untitled); + } else { + holder.titleTv.setText(getHighlightedText(note.getTitle())); + } + + holder.notebookTv.setText(mNotebookId2TitleMaps.get(note.getNoteBookId())); + long updateTime = note.getUpdatedTimeVal(); + String time; + if (updateTime >= TimeUtils.getToday().getTimeInMillis()) { + time = TimeUtils.toTimeFormat(updateTime); + } else if (updateTime >= TimeUtils.getYesterday().getTimeInMillis()) { + time = holder.updateTimeTv.getContext().getString(R.string.time_yesterday, TimeUtils.toTimeFormat(updateTime)); + } else if (updateTime >= TimeUtils.getThisYear().getTimeInMillis()) { + time = TimeUtils.toDateFormat(updateTime); + } else { + time = TimeUtils.toYearFormat(updateTime); + } + holder.updateTimeTv.setText(time); + holder.dirtyTv.setVisibility(note.isDirty() ? View.VISIBLE : View.GONE); + } + + private void renderDetailContent(NoteHolder holder, final Note note) { + List noteFiles = NoteFileService.getRelatedNoteFiles(note.getId()); + holder.imageView.setImageDrawable(null); + for (NoteFile noteFile : noteFiles) { + if (TextUtils.isEmpty(noteFile.getLocalPath())) { + continue; + } + File file = new File(noteFile.getLocalPath()); + if (FileUtils.isImageFile(file)) { + Glide.with(holder.container.getContext()) + .load(file) + .fitCenter() + .into(holder.imageView); + break; + } + } + if (note.isMarkDown()) { + holder.contentTv.setText(note.getContent()); + } else { + Spanned spannedContent = Html.fromHtml(note.getContent()); + String contentStr = spannedContent.toString(); + contentStr = contentStr.replaceAll("\\n\\n+", "\n"); + holder.contentTv.setText(contentStr); + } } private void renderSimple(final NoteHolder holder, final Note note) { @@ -185,23 +233,6 @@ public class NoteAdapter extends RecyclerView.Adapter { } holder.updateTimeTv.setText(time); holder.dirtyTv.setVisibility(note.isDirty() ? View.VISIBLE : View.GONE); - holder.itemView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (mListener != null) { - mListener.onClickNote(note); - } - } - }); - holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - if (mListener != null) { - mListener.onLongClickNote(note); - } - return true; - } - }); } private CharSequence getHighlightedText(String text) { @@ -247,6 +278,9 @@ public class NoteAdapter extends RecyclerView.Adapter { TextView dirtyTv; @BindView(R.id.container) View container; + @Nullable + @BindView(R.id.iv_image) + ImageView imageView; public NoteHolder(View itemView) { super(itemView); diff --git a/app/src/main/java/org/houxg/leamonax/service/NoteFileService.java b/app/src/main/java/org/houxg/leamonax/service/NoteFileService.java index 8a3e747..656f1eb 100644 --- a/app/src/main/java/org/houxg/leamonax/service/NoteFileService.java +++ b/app/src/main/java/org/houxg/leamonax/service/NoteFileService.java @@ -16,6 +16,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URI; +import java.util.List; import java.util.Locale; import okio.BufferedSource; @@ -72,6 +73,10 @@ public class NoteFileService { } } + public static List getRelatedNoteFiles(long noteLocalId) { + return AppDataBase.getAllRelatedFile(noteLocalId); + } + public static InputStream getImage(String localId) { NoteFile noteFile = AppDataBase.getNoteFileByLocalId(localId); if (noteFile == null) { diff --git a/app/src/main/java/org/houxg/leamonax/utils/FileUtils.java b/app/src/main/java/org/houxg/leamonax/utils/FileUtils.java new file mode 100644 index 0000000..b29f996 --- /dev/null +++ b/app/src/main/java/org/houxg/leamonax/utils/FileUtils.java @@ -0,0 +1,10 @@ +package org.houxg.leamonax.utils; + + +import java.io.File; + +public class FileUtils { + public static boolean isImageFile(File file) { + return file != null && file.isFile() && file.getName().matches("([^\\s]+(\\.(?i)(jpg|png|gif|bmp))$)"); + } +} diff --git a/app/src/main/java/org/houxg/leamonax/widget/NoteList.java b/app/src/main/java/org/houxg/leamonax/widget/NoteList.java index ddfa6a4..89706de 100644 --- a/app/src/main/java/org/houxg/leamonax/widget/NoteList.java +++ b/app/src/main/java/org/houxg/leamonax/widget/NoteList.java @@ -39,6 +39,10 @@ public class NoteList { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); + mAdapter.setScrolling(newState != RecyclerView.SCROLL_STATE_IDLE); + if (newState == RecyclerView.SCROLL_STATE_IDLE) { + mAdapter.notifyDataSetChanged(); + } } @Override diff --git a/app/src/main/res/drawable/shape_placeholder.xml b/app/src/main/res/drawable/shape_placeholder.xml new file mode 100644 index 0000000..376f80b --- /dev/null +++ b/app/src/main/res/drawable/shape_placeholder.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_note.xml b/app/src/main/res/layout/item_note.xml index a3a2740..0a4bc43 100644 --- a/app/src/main/res/layout/item_note.xml +++ b/app/src/main/res/layout/item_note.xml @@ -28,20 +28,35 @@ android:fontFamily="sans-serif-medium" android:textColor="@color/primary_text_light" android:textSize="20sp" + android:layout_marginBottom="4dp" tools:text="Leanote API" /> - + android:orientation="horizontal"> + + + + + diff --git a/app/src/main/res/layout/item_note_detail_placeholder.xml b/app/src/main/res/layout/item_note_detail_placeholder.xml new file mode 100644 index 0000000..5640dde --- /dev/null +++ b/app/src/main/res/layout/item_note_detail_placeholder.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file