Browse Source

Implemented dragable bookmarks.

pull/71/head
babaliaris 4 years ago
parent
commit
d780eedafe
  1. 1
      app/build.gradle
  2. 180
      app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksAdapter.java
  3. 94
      app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksFragment.java
  4. 43
      app/src/main/res/layout/fragment_bookmarks.xml
  5. 10
      app/src/main/res/layout/fragment_bookmarks_row.xml
  6. 2
      build.gradle

1
app/build.gradle

@ -118,4 +118,5 @@ dependencies {
testImplementation 'org.powermock:powermock-module-junit4:2.0.2' testImplementation 'org.powermock:powermock-module-junit4:2.0.2'
testImplementation 'org.powermock:powermock-api-mockito2:2.0.2' testImplementation 'org.powermock:powermock-api-mockito2:2.0.2'
testImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1' testImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1'
implementation 'com.github.woxthebox:draglistview:1.7.2'
} }

180
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<ArrayList<Bookmark>, BookmarksAdapter.BookmarksViewHolder>
{
private final BookmarksFragment m_fragment;
private final ArrayList<Bookmark> m_bookMarks;
private final Drawable m_notificationsEnabled;
private final Drawable m_notificationsDisabled;
public BookmarksAdapter(BookmarksFragment fragment, ArrayList<Bookmark> 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;
}
}
}

94
app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksFragment.java

@ -1,20 +1,22 @@
package gr.thmmy.mthmmy.activities.bookmarks; package gr.thmmy.mthmmy.activities.bookmarks;
import android.app.Activity;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat; import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
import com.woxthebox.draglistview.DragListView;
import java.util.ArrayList; import java.util.ArrayList;
import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.R;
@ -37,8 +39,8 @@ public class BookmarksFragment extends Fragment {
private TextView nothingBookmarkedTextView; private TextView nothingBookmarkedTextView;
private ArrayList<Bookmark> bookmarks = null; private ArrayList<Bookmark> bookmarks = null;
private Type type; public Type type;
private String interactionClick, interactionToggle, interactionRemove; public String interactionClick, interactionToggle, interactionRemove;
private Drawable notificationsEnabledButtonImage; private Drawable notificationsEnabledButtonImage;
private Drawable notificationsDisabledButtonImage; private Drawable notificationsDisabledButtonImage;
@ -100,66 +102,70 @@ public class BookmarksFragment extends Fragment {
Bundle savedInstanceState) { Bundle savedInstanceState) {
// Inflates the layout for this fragment // Inflates the layout for this fragment
final View rootView = layoutInflater.inflate(R.layout.fragment_bookmarks, container, false); 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); nothingBookmarkedTextView = rootView.findViewById(R.id.nothing_bookmarked);
if(this.bookmarks != null && !this.bookmarks.isEmpty()) { DragListView mDragListView = (DragListView) rootView.findViewById(R.id.fragment_bookmarks_dragList);
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); mDragListView.setDragListListener(new DragListView.DragListListener()
if (!bookmark.isNotificationsEnabled()) { {
notificationsEnabledButton.setImageDrawable(notificationsDisabledButtonImage); @Override
public void onItemDragStarted(int position)
{
} }
notificationsEnabledButton.setOnClickListener(view -> { @Override
Activity activity = getActivity(); public void onItemDragging(int itemPosition, float x, float y)
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()){ @Override
showNothingBookmarked(); 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);
} }
});
bookmarksLinearView.addView(row);
} }
});
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();
} }
} else
//Show Nothing Bookmarked.
else {
showNothingBookmarked(); showNothingBookmarked();
}
return rootView; return rootView;
} }
private void showNothingBookmarked() { public void showNothingBookmarked() {
if(nothingBookmarkedTextView!=null) if(nothingBookmarkedTextView!=null)
nothingBookmarkedTextView.setVisibility(View.VISIBLE); nothingBookmarkedTextView.setVisibility(View.VISIBLE);
} }
private void hideNothingBookmarked(){ public void hideNothingBookmarked(){
if(nothingBookmarkedTextView!=null) if(nothingBookmarkedTextView!=null)
nothingBookmarkedTextView.setVisibility(View.INVISIBLE); nothingBookmarkedTextView.setVisibility(View.INVISIBLE);
} }

43
app/src/main/res/layout/fragment_bookmarks.xml

@ -1,36 +1,33 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_height="match_parent">
<androidx.core.widget.NestedScrollView
android:id="@+id/bookmarks_nested_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top|start"
android:background="@color/primary_lighter"
android:scrollbars="none"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:id="@+id/bookmarks_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
android:showDividers="middle" >
android:divider="?android:listDivider"
android:dividerPadding="16dp"/> <com.woxthebox.draglistview.DragListView
</androidx.core.widget.NestedScrollView> android:id="@+id/fragment_bookmarks_dragList"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/nothing_bookmarked" android:id="@+id/nothing_bookmarked"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="invisible"
android:textIsSelectable="false"
android:text="@string/nothing_bookmarked_here" android:text="@string/nothing_bookmarked_here"
android:textColor="@color/accent" android:textColor="@color/accent"
android:textIsSelectable="false"
android:textSize="@dimen/medium_text" android:textSize="@dimen/medium_text"
/> android:visibility="invisible"
</FrameLayout> app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

10
app/src/main/res/layout/fragment_bookmarks_row.xml

@ -1,10 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/bookmark_row" android:id="@+id/bookmark_row"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
>
<LinearLayout
android:id="@+id/bookmark_dragable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground" android:background="?android:attr/selectableItemBackground"
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
@ -48,3 +55,4 @@
android:contentDescription="@string/remove_bookmark" android:contentDescription="@string/remove_bookmark"
app:srcCompat="@drawable/ic_delete_accent_24dp"/> app:srcCompat="@drawable/ic_delete_accent_24dp"/>
</LinearLayout> </LinearLayout>
</FrameLayout>

2
build.gradle

@ -5,6 +5,7 @@ buildscript {
repositories { repositories {
google() google()
jcenter() jcenter()
mavenCentral()
maven { url "https://jitpack.io" } maven { url "https://jitpack.io" }
} }
dependencies { dependencies {
@ -21,6 +22,7 @@ allprojects {
maven { url "https://maven.google.com" } maven { url "https://maven.google.com" }
google() google()
jcenter() jcenter()
mavenCentral()
maven { url "https://jitpack.io" } maven { url "https://jitpack.io" }
} }
} }

Loading…
Cancel
Save