From 4e6abdcd7d11e69b60a90af32ef0a4ef4f62ddca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=C3=AA=CC=83n=20Quang=20Minh=20=28NQM=29?= Date: Sun, 19 Nov 2023 23:51:00 +0700 Subject: [PATCH] fix --- .../quickmem/adapter/CardLeanAdapter.kt | 46 ++++ .../quickmem/adapter/FolderAdapter.java | 2 +- .../quickmem/ui/activities/MainActivity.java | 2 +- .../ui/activities/learn/LearnActivity.kt | 250 +++++++++++++++++- .../ui/activities/set/ViewSetActivity.java | 4 +- .../quickmem/utils/CardDiffCallback.kt | 26 ++ app/src/main/res/layout/activity_learn.xml | 90 +++++++ app/src/main/res/layout/item_learn_set.xml | 1 - app/src/main/res/values/strings.xml | 1 + 9 files changed, 416 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/com/daominh/quickmem/adapter/CardLeanAdapter.kt create mode 100644 app/src/main/java/com/daominh/quickmem/utils/CardDiffCallback.kt diff --git a/app/src/main/java/com/daominh/quickmem/adapter/CardLeanAdapter.kt b/app/src/main/java/com/daominh/quickmem/adapter/CardLeanAdapter.kt new file mode 100644 index 0000000..31abf69 --- /dev/null +++ b/app/src/main/java/com/daominh/quickmem/adapter/CardLeanAdapter.kt @@ -0,0 +1,46 @@ +package com.daominh.quickmem.adapter + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.daominh.quickmem.data.model.Card +import com.daominh.quickmem.databinding.ItemLearnSetBinding + +class CardLeanAdapter( + private var cardList: List +) : RecyclerView.Adapter() { + + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CardLeanAdapter.ViewHolder { + val layoutInflater = LayoutInflater.from(parent.context) + val binding = ItemLearnSetBinding.inflate(layoutInflater, parent, false) + return ViewHolder(binding) + } + + override fun onBindViewHolder(holder: CardLeanAdapter.ViewHolder, position: Int) { + val card = cardList[position] + holder.bind(card) + } + + override fun getItemCount(): Int { + return cardList.size + } + + fun setCards(cards: List) { + this.cardList = cards + } + + fun getCards(): List { + return cardList + } + + class ViewHolder(private val binding: ItemLearnSetBinding) : RecyclerView.ViewHolder(binding.root) { + + fun bind(card: Card) { + binding.itemFont.text = card.front + binding.itemBack.text = card.back + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/daominh/quickmem/adapter/FolderAdapter.java b/app/src/main/java/com/daominh/quickmem/adapter/FolderAdapter.java index 0fa5e3a..f757168 100644 --- a/app/src/main/java/com/daominh/quickmem/adapter/FolderAdapter.java +++ b/app/src/main/java/com/daominh/quickmem/adapter/FolderAdapter.java @@ -52,7 +52,7 @@ public int getItemCount() { return folders.size(); } - public class FolderViewHolder extends RecyclerView.ViewHolder { + public static class FolderViewHolder extends RecyclerView.ViewHolder { private final ItemFolderBinding binding; public FolderViewHolder(@NonNull @NotNull View itemView) { diff --git a/app/src/main/java/com/daominh/quickmem/ui/activities/MainActivity.java b/app/src/main/java/com/daominh/quickmem/ui/activities/MainActivity.java index eb37b0a..0a55019 100644 --- a/app/src/main/java/com/daominh/quickmem/ui/activities/MainActivity.java +++ b/app/src/main/java/com/daominh/quickmem/ui/activities/MainActivity.java @@ -33,7 +33,7 @@ protected void onCreate(Bundle savedInstanceState) { private void setupNavigation() { userSharePreferences = new UserSharePreferences(MainActivity.this); - int role = 0; + int role = userSharePreferences.getRole(); navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main); diff --git a/app/src/main/java/com/daominh/quickmem/ui/activities/learn/LearnActivity.kt b/app/src/main/java/com/daominh/quickmem/ui/activities/learn/LearnActivity.kt index b87787c..0dfb50f 100644 --- a/app/src/main/java/com/daominh/quickmem/ui/activities/learn/LearnActivity.kt +++ b/app/src/main/java/com/daominh/quickmem/ui/activities/learn/LearnActivity.kt @@ -2,11 +2,257 @@ package com.daominh.quickmem.ui.activities.learn import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import android.util.Log +import android.view.View +import android.view.animation.AccelerateInterpolator +import android.view.animation.DecelerateInterpolator +import android.view.animation.LinearInterpolator +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DiffUtil import com.daominh.quickmem.R +import com.daominh.quickmem.adapter.CardLeanAdapter +import com.daominh.quickmem.data.dao.CardDAO +import com.daominh.quickmem.data.model.Card +import com.daominh.quickmem.databinding.ActivityLearnBinding +import com.daominh.quickmem.utils.CardDiffCallback +import com.yuyakaido.android.cardstackview.* + +class LearnActivity : AppCompatActivity(), CardStackListener { + private val binding: ActivityLearnBinding by lazy { + ActivityLearnBinding.inflate(layoutInflater) + } + private val manager by lazy { CardStackLayoutManager(this, this) } + private val adapter by lazy { CardLeanAdapter(createCards()) } + private val cardDAO by lazy { CardDAO(this) } + -class LearnActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_learn) + setContentView(binding.root) + + setupCardStackView() + setupButton() + + binding.skipButton.setOnClickListener { + binding.cardStackView.swipe() + } + + binding.rewindButton.setOnClickListener { + binding.cardStackView.rewind() + } + + binding.likeButton.setOnClickListener { + binding.cardStackView.swipe() + } + } + + override fun onCardDragging(direction: Direction?, ratio: Float) { + Log.d("CardStackView", "onCardDragging: d = $direction, r = $ratio") + } + + override fun onCardSwiped(direction: Direction?) { + Log.d("CardStackView", "onCardSwiped: p = ${manager.topPosition}, d = $direction") + if (manager.topPosition == adapter.itemCount - 5) { + paginate() + } + if (manager.topPosition == adapter.itemCount) { + addLast(1) + } + } + + override fun onCardRewound() { + Log.d("CardStackView", "onCardRewound: ${manager.topPosition}") } + + override fun onCardCanceled() { + Log.d("CardStackView", "onCardCanceled: ${manager.topPosition}") + } + + override fun onCardAppeared(view: View?, position: Int) { + Log.d("CardStackView", "onCardAppeared: ($position)") + binding.skipButton.visibility = View.VISIBLE + binding.rewindButton.visibility = View.VISIBLE + binding.likeButton.visibility = View.VISIBLE + } + + override fun onCardDisappeared(view: View?, position: Int) { + Log.d("CardStackView", "onCardDisappeared: ($position)") + binding.skipButton.visibility = View.GONE + binding.rewindButton.visibility = View.GONE + binding.likeButton.visibility = View.GONE + } + + private fun setupButton() { + binding.skipButton.setOnClickListener { + val setting = SwipeAnimationSetting.Builder() + .setDirection(Direction.Left) + .setDuration(Duration.Normal.duration) + .setInterpolator(AccelerateInterpolator()) + .build() + manager.setSwipeAnimationSetting(setting) + binding.cardStackView.swipe() + } + + binding.rewindButton.setOnClickListener { + val setting = RewindAnimationSetting.Builder() + .setDirection(Direction.Bottom) + .setDuration(Duration.Normal.duration) + .setInterpolator(DecelerateInterpolator()) + .build() + manager.setRewindAnimationSetting(setting) + binding.cardStackView.rewind() + } + + binding.likeButton.setOnClickListener { + val setting = SwipeAnimationSetting.Builder() + .setDirection(Direction.Right) + .setDuration(Duration.Normal.duration) + .setInterpolator(AccelerateInterpolator()) + .build() + manager.setSwipeAnimationSetting(setting) + binding.cardStackView.swipe() + } + } + + private fun setupCardStackView() { + initialize() + } + + private fun createCards(): List { + val id: String = intent.getStringExtra("id").toString() + return cardDAO.getCardsByFlashCardId(id) + } + + private fun creatCard(): Card { + return createCards().first() + } + + + private fun initialize() { + manager.setStackFrom(StackFrom.Bottom) + manager.setVisibleCount(3) + manager.setTranslationInterval(8.0f) + manager.setScaleInterval(0.95f) + manager.setSwipeThreshold(0.3f) + manager.setMaxDegree(20.0f) + manager.setDirections(Direction.HORIZONTAL) + manager.setCanScrollHorizontal(true) + manager.setCanScrollVertical(true) + manager.setSwipeableMethod(SwipeableMethod.AutomaticAndManual) + manager.setOverlayInterpolator(LinearInterpolator()) + binding.cardStackView.layoutManager = manager + binding.cardStackView.adapter = adapter + binding.cardStackView.itemAnimator.apply { + if (this is DefaultItemAnimator) { + supportsChangeAnimations = false + } + } + } + + private fun paginate() { + val old = adapter.getCards() + val new = old.plus(createCards()) + val callback = CardDiffCallback(old, new) + val result = DiffUtil.calculateDiff(callback) + adapter.setCards(new) + result.dispatchUpdatesTo(adapter) + } + + private fun reload() { + val old = adapter.getCards() + val new = createCards() + val callback = CardDiffCallback(old, new) + val result = DiffUtil.calculateDiff(callback) + adapter.setCards(new) + result.dispatchUpdatesTo(adapter) + } + + private fun addFirst(size: Int) { + val old = adapter.getCards() + val new = mutableListOf().apply { + addAll(old) + for (i in 0 until size) { + add(manager.topPosition, creatCard()) + } + } + val callback = CardDiffCallback(old, new) + val result = DiffUtil.calculateDiff(callback) + adapter.setCards(new) + result.dispatchUpdatesTo(adapter) + } + + private fun addLast(size: Int) { + val old = adapter.getCards() + val new = mutableListOf().apply { + addAll(old) + addAll(List(size) { creatCard() }) + } + val callback = CardDiffCallback(old, new) + val result = DiffUtil.calculateDiff(callback) + adapter.setCards(new) + result.dispatchUpdatesTo(adapter) + } + + private fun removeFirst(size: Int) { + if (adapter.getCards().isEmpty()) { + return + } + + val old = adapter.getCards() + val new = mutableListOf().apply { + addAll(old) + for (i in 0 until size) { + removeAt(manager.topPosition) + } + } + val callback = CardDiffCallback(old, new) + val result = DiffUtil.calculateDiff(callback) + adapter.setCards(new) + result.dispatchUpdatesTo(adapter) + } + + private fun removeLast(size: Int) { + if (adapter.getCards().isEmpty()) { + return + } + + val old = adapter.getCards() + val new = mutableListOf().apply { + addAll(old) + for (i in 0 until size) { + removeAt(this.size - 1) + } + } + val callback = CardDiffCallback(old, new) + val result = DiffUtil.calculateDiff(callback) + adapter.setCards(new) + result.dispatchUpdatesTo(adapter) + } + + private fun replace() { + val old = adapter.getCards() + val new = mutableListOf().apply { + addAll(old) + removeAt(manager.topPosition) + add(manager.topPosition, creatCard()) + } + adapter.setCards(new) + adapter.notifyItemChanged(manager.topPosition) + } + + private fun swap() { + val old = adapter.getCards() + val new = mutableListOf().apply { + addAll(old) + val first = removeAt(manager.topPosition) + val last = removeAt(this.size - 1) + add(manager.topPosition, last) + add(first) + } + val callback = CardDiffCallback(old, new) + val result = DiffUtil.calculateDiff(callback) + adapter.setCards(new) + result.dispatchUpdatesTo(adapter) + } + } \ No newline at end of file diff --git a/app/src/main/java/com/daominh/quickmem/ui/activities/set/ViewSetActivity.java b/app/src/main/java/com/daominh/quickmem/ui/activities/set/ViewSetActivity.java index c0c7146..6777907 100644 --- a/app/src/main/java/com/daominh/quickmem/ui/activities/set/ViewSetActivity.java +++ b/app/src/main/java/com/daominh/quickmem/ui/activities/set/ViewSetActivity.java @@ -62,7 +62,9 @@ public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { binding.reviewCl.setOnClickListener(v -> { - startActivity(new Intent(this, LearnActivity.class)); + Intent intent = new Intent(this, LearnActivity.class); + intent.putExtra("id", getIntent().getStringExtra("id")); + startActivity(intent); }); } diff --git a/app/src/main/java/com/daominh/quickmem/utils/CardDiffCallback.kt b/app/src/main/java/com/daominh/quickmem/utils/CardDiffCallback.kt new file mode 100644 index 0000000..b1a6c5c --- /dev/null +++ b/app/src/main/java/com/daominh/quickmem/utils/CardDiffCallback.kt @@ -0,0 +1,26 @@ +package com.daominh.quickmem.utils + +import androidx.recyclerview.widget.DiffUtil +import com.daominh.quickmem.data.model.Card + +class CardDiffCallback( + private val oldList: List, + private val newList: List +) : DiffUtil.Callback( +) { + override fun getOldListSize(): Int { + return oldList.size + } + + override fun getNewListSize(): Int { + return newList.size + } + + override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { + return oldList[oldItemPosition].id == newList[newItemPosition].id + } + + override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { + return oldList[oldItemPosition] == newList[newItemPosition] + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_learn.xml b/app/src/main/res/layout/activity_learn.xml index e7b3ee0..44f5eca 100644 --- a/app/src/main/res/layout/activity_learn.xml +++ b/app/src/main/res/layout/activity_learn.xml @@ -7,4 +7,94 @@ android:layout_height="match_parent" tools:context=".ui.activities.learn.LearnActivity"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_learn_set.xml b/app/src/main/res/layout/item_learn_set.xml index c71025e..97788e8 100644 --- a/app/src/main/res/layout/item_learn_set.xml +++ b/app/src/main/res/layout/item_learn_set.xml @@ -22,7 +22,6 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center_vertical" - android:background="@drawable/gradation_black" android:orientation="vertical" android:padding="16dp"> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8599b76..7b48427 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -92,4 +92,5 @@ number memmber Flashcards Review terms and definitions + Learn \ No newline at end of file