From d780eedafe71cc46aae175e434e7b4d2650d98e0 Mon Sep 17 00:00:00 2001 From: babaliaris Date: Fri, 13 Nov 2020 15:00:05 +0200 Subject: [PATCH] Implemented dragable bookmarks. --- app/build.gradle | 1 + .../bookmarks/BookmarksAdapter.java | 180 ++++++++++++++++++ .../bookmarks/BookmarksFragment.java | 108 ++++++----- .../main/res/layout/fragment_bookmarks.xml | 45 ++--- .../res/layout/fragment_bookmarks_row.xml | 88 +++++---- build.gradle | 2 + 6 files changed, 309 insertions(+), 115 deletions(-) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksAdapter.java diff --git a/app/build.gradle b/app/build.gradle index 0c95158c..9ceb69fd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -118,4 +118,5 @@ dependencies { testImplementation 'org.powermock:powermock-module-junit4:2.0.2' testImplementation 'org.powermock:powermock-api-mockito2:2.0.2' testImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1' + implementation 'com.github.woxthebox:draglistview:1.7.2' } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksAdapter.java new file mode 100644 index 00000000..0049cdc1 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksAdapter.java @@ -0,0 +1,180 @@ +package gr.thmmy.mthmmy.activities.bookmarks; + +import android.app.Activity; +import android.graphics.drawable.Drawable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; + +import com.woxthebox.draglistview.DragItemAdapter; + +import java.util.ArrayList; + +import gr.thmmy.mthmmy.R; +import gr.thmmy.mthmmy.model.Bookmark; + + + + +public class BookmarksAdapter extends DragItemAdapter, BookmarksAdapter.BookmarksViewHolder> +{ + private final BookmarksFragment m_fragment; + private final ArrayList m_bookMarks; + private final Drawable m_notificationsEnabled; + private final Drawable m_notificationsDisabled; + + public BookmarksAdapter(BookmarksFragment fragment, ArrayList bookmarks, Drawable noteEnabled, Drawable noteDisabled) + { + this.m_fragment = fragment; + this.m_bookMarks = bookmarks; + this.m_notificationsEnabled = noteEnabled; + this.m_notificationsDisabled = noteDisabled; + } + + @Override + public long getUniqueItemId(int position) + { + return m_bookMarks.get(position).getId().hashCode(); + } + + @NonNull + @Override + public BookmarksAdapter.BookmarksViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) + { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_bookmarks_row, parent, false); + return new BookmarksViewHolder(view, view.findViewById(R.id.bookmark_dragable).getId(), true); + } + + @Override + public void onBindViewHolder(@NonNull BookmarksViewHolder holder, int position) + { + super.onBindViewHolder(holder, position); + + //Check if bookMarks ArrayList Exists and is not empty. + if(m_bookMarks != null && !m_bookMarks.isEmpty()) + { + //Check if the current bookmark exists and has a title. + if (m_bookMarks.get(position) != null && m_bookMarks.get(position).getTitle() != null) + { + + //Set the title. + holder.m_textView.setText(m_bookMarks.get(position).getTitle()); + + //Set Notifications Enabled Image Indicator. + if (m_bookMarks.get(position).isNotificationsEnabled()) + holder.m_noteView.setImageDrawable(m_notificationsEnabled); + + //Set Notifications Disabled Image Indicator. + else + holder.m_noteView.setImageDrawable(m_notificationsDisabled); + + + //On Bookmark Click. + holder.mGrabView.setOnClickListener(v -> { + + //Get the activity. + Activity activity = m_fragment.getActivity(); + + //Go to the bookmarked activity. + if (activity instanceof BookmarksActivity) + ((BookmarksActivity) activity).onFragmentRowInteractionListener( + m_fragment.type, + m_fragment.interactionClick, + m_bookMarks.get(position)); + }); + + + //On Notifications Toggle. + holder.m_noteView.setOnClickListener(v -> { + + //Toggle the current local instance. + m_bookMarks.get(position).toggleNotificationsEnabled(); + + //Get the fragment activity. + Activity activity = m_fragment.getActivity(); + + //Check if it is indeed the fragment activity. + if (activity instanceof BookmarksActivity) + { + + //Trigger the toggle functionality and set the Enabled notifications image. + if (((BookmarksActivity) activity).onFragmentRowInteractionListener( + m_fragment.type, + m_fragment.interactionToggle, + m_bookMarks.get(position))) + { + holder.m_noteView.setImageDrawable(m_notificationsEnabled); + } + + //Trigger returned false, so set the notifications disabled image. + else + holder.m_noteView.setImageDrawable(m_notificationsDisabled); + } + }); + + + //Remove Item. + holder.m_removeView.setOnClickListener(v -> { + + //Get fragment's activity. + Activity activity = m_fragment.getActivity(); + + if (activity instanceof BookmarksActivity) + { + + //Trigger the bookmark remove functionality. + ((BookmarksActivity) activity).onFragmentRowInteractionListener( + m_fragment.type, + m_fragment.interactionRemove, + m_bookMarks.get(position)); + { + notifyItemRemoved(position); + notifyItemRangeChanged(position, m_bookMarks.size()); + m_bookMarks.remove(m_bookMarks.get(position)); + } + } + + //If the bookmarks are empty then show nothing marked. + if (m_bookMarks.isEmpty()) + { + m_fragment.showNothingBookmarked(); + } + + }); + } + } + } + + @Override + public int getItemCount() + { + if (m_bookMarks != null) + return m_bookMarks.size(); + + return 0; + } + + //View Holder. + static class BookmarksViewHolder extends DragItemAdapter.ViewHolder + { + + public final TextView m_textView; + public final ImageView m_noteView; + public final ImageView m_removeView; + public final View m_thisView; + + public BookmarksViewHolder(View itemView, int handleResId, boolean dragOnLongPress) + { + super(itemView, handleResId, dragOnLongPress); + this.m_textView = itemView.findViewById(R.id.bookmark_title); + this.m_noteView = itemView.findViewById(R.id.toggle_notification); + this.m_removeView = itemView.findViewById(R.id.remove_bookmark); + this.m_thisView = itemView; + } + } +} diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksFragment.java index cdd6f714..94a49b69 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksFragment.java @@ -1,20 +1,22 @@ package gr.thmmy.mthmmy.activities.bookmarks; -import android.app.Activity; + import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageButton; -import android.widget.LinearLayout; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat; +import com.woxthebox.draglistview.DragListView; + import java.util.ArrayList; import gr.thmmy.mthmmy.R; @@ -37,8 +39,8 @@ public class BookmarksFragment extends Fragment { private TextView nothingBookmarkedTextView; private ArrayList bookmarks = null; - private Type type; - private String interactionClick, interactionToggle, interactionRemove; + public Type type; + public String interactionClick, interactionToggle, interactionRemove; private Drawable notificationsEnabledButtonImage; private Drawable notificationsDisabledButtonImage; @@ -100,66 +102,70 @@ public class BookmarksFragment extends Fragment { Bundle savedInstanceState) { // Inflates the layout for this fragment final View rootView = layoutInflater.inflate(R.layout.fragment_bookmarks, container, false); - //bookmarks container - final LinearLayout bookmarksLinearView = rootView.findViewById(R.id.bookmarks_container); + + //Get the nothing bookmarked text view. nothingBookmarkedTextView = rootView.findViewById(R.id.nothing_bookmarked); - if(this.bookmarks != null && !this.bookmarks.isEmpty()) { - hideNothingBookmarked(); - for (final Bookmark bookmark : bookmarks) { - if (bookmark != null && bookmark.getTitle() != null) { - final LinearLayout row = (LinearLayout) layoutInflater.inflate( - R.layout.fragment_bookmarks_row, bookmarksLinearView, false); - row.setOnClickListener(view -> { - Activity activity = getActivity(); - if (activity instanceof BookmarksActivity) - ((BookmarksActivity) activity).onFragmentRowInteractionListener(type, interactionClick, bookmark); - }); - ((TextView) row.findViewById(R.id.bookmark_title)).setText(bookmark.getTitle()); - - final ImageButton notificationsEnabledButton = row.findViewById(R.id.toggle_notification); - if (!bookmark.isNotificationsEnabled()) { - notificationsEnabledButton.setImageDrawable(notificationsDisabledButtonImage); - } - - notificationsEnabledButton.setOnClickListener(view -> { - Activity activity = getActivity(); - if (activity instanceof BookmarksActivity) { - if (((BookmarksActivity) activity).onFragmentRowInteractionListener(type, interactionToggle, bookmark)) - notificationsEnabledButton.setImageDrawable(notificationsEnabledButtonImage); - else - notificationsEnabledButton.setImageDrawable(notificationsDisabledButtonImage); - } - }); - - (row.findViewById(R.id.remove_bookmark)).setOnClickListener(view -> { - Activity activity = getActivity(); - if (activity instanceof BookmarksActivity){ - ((BookmarksActivity) activity).onFragmentRowInteractionListener(type, interactionRemove, bookmark); - bookmarks.remove(bookmark); - } - row.setVisibility(View.GONE); - - if (bookmarks.isEmpty()){ - showNothingBookmarked(); - } - }); - bookmarksLinearView.addView(row); + DragListView mDragListView = (DragListView) rootView.findViewById(R.id.fragment_bookmarks_dragList); + + mDragListView.setDragListListener(new DragListView.DragListListener() + { + @Override + public void onItemDragStarted(int position) + { + } + + @Override + public void onItemDragging(int itemPosition, float x, float y) + { + + } + + @Override + public void onItemDragEnded(int fromPosition, int toPosition) + { + + //TODO: This only works locally. If the user exit the bookmarks + // or closes the app, the order of the bookmarks will be lost. + // make sure after the following swapping, to apply the changes + // in the actual data model of the bookmarks. + + if (fromPosition != toPosition) + { + Bookmark from = bookmarks.get(fromPosition); + + bookmarks.set(fromPosition, bookmarks.get(toPosition)); + bookmarks.set(toPosition, from); } } - } else + }); + + mDragListView.setLayoutManager(new LinearLayoutManager(getActivity())); + BookmarksAdapter adapter = new BookmarksAdapter(this, bookmarks, notificationsEnabledButtonImage, notificationsDisabledButtonImage); + mDragListView.setAdapter(adapter, false); + mDragListView.setCanDragHorizontally(false); + + //Hide Nothing Bookmarked. + if(this.bookmarks != null && !this.bookmarks.isEmpty()) + { + hideNothingBookmarked(); + } + + //Show Nothing Bookmarked. + else { showNothingBookmarked(); + } return rootView; } - private void showNothingBookmarked() { + public void showNothingBookmarked() { if(nothingBookmarkedTextView!=null) nothingBookmarkedTextView.setVisibility(View.VISIBLE); } - private void hideNothingBookmarked(){ + public void hideNothingBookmarked(){ if(nothingBookmarkedTextView!=null) nothingBookmarkedTextView.setVisibility(View.INVISIBLE); } diff --git a/app/src/main/res/layout/fragment_bookmarks.xml b/app/src/main/res/layout/fragment_bookmarks.xml index aa1bbaab..65101e44 100644 --- a/app/src/main/res/layout/fragment_bookmarks.xml +++ b/app/src/main/res/layout/fragment_bookmarks.xml @@ -1,36 +1,33 @@ - + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + > + + - - - - \ No newline at end of file + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_bookmarks_row.xml b/app/src/main/res/layout/fragment_bookmarks_row.xml index b3e17ebe..07ca07b2 100644 --- a/app/src/main/res/layout/fragment_bookmarks_row.xml +++ b/app/src/main/res/layout/fragment_bookmarks_row.xml @@ -1,50 +1,58 @@ - + > - + android:background="?android:attr/selectableItemBackground" + android:clickable="true" + android:focusable="true" + android:gravity="center_vertical" + android:orientation="horizontal"> + + - + - - \ No newline at end of file + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index a861f527..45116ef0 100644 --- a/build.gradle +++ b/build.gradle @@ -5,6 +5,7 @@ buildscript { repositories { google() jcenter() + mavenCentral() maven { url "https://jitpack.io" } } dependencies { @@ -21,6 +22,7 @@ allprojects { maven { url "https://maven.google.com" } google() jcenter() + mavenCentral() maven { url "https://jitpack.io" } } }