Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix part of #140: Topic play animation #486

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ dependencies {
'com.google.android.material:material:1.0.0',
'com.google.dagger:dagger:2.24',
'com.google.guava:guava:28.1-android',
'net.cachapa.expandablelayout:expandablelayout:2.9.2',
"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version",
'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1',
'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.1',
Expand Down
46 changes: 24 additions & 22 deletions app/src/main/java/org/oppia/app/topic/play/StorySummaryAdapter.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package org.oppia.app.topic.play

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import org.oppia.app.R
import org.oppia.app.databinding.TopicPlayStorySummaryBinding
import org.oppia.app.databinding.TopicPlayTitleBinding
import org.oppia.app.model.ChapterPlayState
Expand All @@ -15,6 +19,7 @@ private const val VIEW_TYPE_STORY_ITEM = 2

/** Adapter to bind StorySummary to [RecyclerView] inside [TopicPlayFragment]. */
class StorySummaryAdapter(
private val context: Context,
private val itemList: MutableList<TopicPlayItemViewModel>,
private val chapterSummarySelector: ChapterSummarySelector,
private val expandedChapterListIndexListener: ExpandedChapterListIndexListener,
Expand Down Expand Up @@ -86,11 +91,6 @@ class StorySummaryAdapter(
inner class StorySummaryViewHolder(private val binding: TopicPlayStorySummaryBinding) :
RecyclerView.ViewHolder(binding.root) {
internal fun bind(storySummaryViewModel: StorySummaryViewModel, position: Int) {
var isChapterListVisible = false
if (currentExpandedChapterListIndex != null) {
isChapterListVisible = currentExpandedChapterListIndex!! == position
}
binding.isListExpanded = isChapterListVisible
binding.viewModel = storySummaryViewModel

val chapterSummaries = storySummaryViewModel.storySummary.chapterList
Expand All @@ -109,25 +109,27 @@ class StorySummaryAdapter(

val chapterList = storySummaryViewModel.storySummary.chapterList
binding.chapterRecyclerView.adapter = ChapterSummaryAdapter(chapterList, chapterSummarySelector)
if (currentExpandedChapterListIndex != null && currentExpandedChapterListIndex == position) {
val rotate = AnimationUtils.loadAnimation(context, R.anim.rotation_clockwise_180)
binding.chapterListDropDownIcon.startAnimation(rotate)
binding.chapterListContainer.expand()
} else {
val rotate = AnimationUtils.loadAnimation(context, R.anim.rotation_anti_clockwise_180)
binding.chapterListDropDownIcon.startAnimation(rotate)
binding.chapterListContainer.collapse()
}

binding.root.setOnClickListener {
val previousIndex: Int? = currentExpandedChapterListIndex
currentExpandedChapterListIndex =
if (currentExpandedChapterListIndex != null && currentExpandedChapterListIndex == position) {
null
} else {
position
}
expandedChapterListIndexListener.onExpandListIconClicked(currentExpandedChapterListIndex)
if (previousIndex != null && currentExpandedChapterListIndex != null && previousIndex == currentExpandedChapterListIndex) {
notifyItemChanged(currentExpandedChapterListIndex!!)
binding.storyContainer.setOnClickListener {
val previousItem = currentExpandedChapterListIndex
if (binding.chapterListContainer.isVisible) {
currentExpandedChapterListIndex = null
} else {
if (previousIndex != null) {
notifyItemChanged(previousIndex)
}
if (currentExpandedChapterListIndex != null) {
notifyItemChanged(currentExpandedChapterListIndex!!)
}
currentExpandedChapterListIndex = position
}
expandedChapterListIndexListener.onExpandListIconClicked(currentExpandedChapterListIndex)
notifyItemChanged(position)
if (previousItem != null && previousItem != position) {
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic isn't trivial to follow. Can we add tests to make sure that the expand/collapse works as expected & stays working? We shouldn't test the animations, just that the state changes are being reflected correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated all test cases:

Check the following tests which checks this functionality:
testTopicPlayFragment_loadFragmentWithTopicTestId0_clickExpandListIconIndex0_clickExpandListIconIndex1_chapterListForIndex0IsNotDisplayed
testTopicPlayFragment_loadFragmentWithTopicTestId0_clickExpandListIconIndex1_clickExpandListIconIndex0_chapterListForIndex0IsNotDisplayed

notifyItemChanged(previousItem)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import javax.inject.Inject
/** The presenter for [TopicPlayFragment]. */
@FragmentScope
class TopicPlayFragmentPresenter @Inject constructor(
activity: AppCompatActivity,
private val activity: AppCompatActivity,
private val fragment: Fragment,
private val logger: Logger,
private val explorationDataController: ExplorationDataController,
Expand Down Expand Up @@ -86,6 +86,7 @@ class TopicPlayFragmentPresenter @Inject constructor(
}
val storySummaryAdapter =
StorySummaryAdapter(
activity,
itemList,
this as ChapterSummarySelector,
expandedChapterListIndexListener,
Expand Down
12 changes: 12 additions & 0 deletions app/src/main/res/anim/rotation_anti_clockwise_180.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http:https://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:fillEnabled="true"
android:interpolator="@android:anim/linear_interpolator">
<rotate
android:duration="@integer/topic_play_animation_time_ms"
android:fromDegrees="180"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="0" />
</set>
12 changes: 12 additions & 0 deletions app/src/main/res/anim/rotation_clockwise_180.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http:https://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:fillEnabled="true"
android:interpolator="@android:anim/linear_interpolator">
<rotate
android:duration="@integer/topic_play_animation_time_ms"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="180" />
</set>
4 changes: 2 additions & 2 deletions app/src/main/res/anim/slide_out_left.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<set xmlns:android="http:https://schemas.android.com/apk/res/android">
<translate
android:duration="@integer/duration_anim_300_ms"
android:duration="@integer/default_fade_anim_time_ms"
android:fromXDelta="0"
android:toXDelta="-100%" />
<alpha
android:duration="@integer/duration_anim_300_ms"
android:duration="@integer/default_fade_anim_time_ms"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
</set>
4 changes: 2 additions & 2 deletions app/src/main/res/anim/slide_right_in.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<set xmlns:android="http:https://schemas.android.com/apk/res/android">
<translate
android:duration="@integer/duration_anim_300_ms"
android:duration="@integer/default_fade_anim_time_ms"
android:fromXDelta="100%"
android:interpolator="@android:interpolator/accelerate_decelerate"
android:toXDelta="0" />
<alpha
android:duration="@integer/duration_anim_300_ms"
android:duration="@integer/default_fade_anim_time_ms"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
</set>
9 changes: 0 additions & 9 deletions app/src/main/res/drawable/ic_arrow_drop_up_black_24dp.xml

This file was deleted.

53 changes: 30 additions & 23 deletions app/src/main/res/layout/topic_play_story_summary.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@

<import type="android.view.View" />

<variable
name="isListExpanded"
type="Boolean" />

<variable
name="storyPercentage"
type="Integer" />
Expand All @@ -20,6 +16,7 @@
</data>

<com.google.android.material.card.MaterialCardView
android:id="@+id/story_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
Expand Down Expand Up @@ -126,38 +123,48 @@
android:minHeight="48dp">

<ImageView
android:id="@+id/chapter_list_drop_down_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:contentDescription="@{@string/show_hide_chapter_list(viewModel.storySummary.storyName)}"
android:src="@{isListExpanded? @drawable/ic_arrow_drop_up_black_24dp : @drawable/ic_arrow_drop_down_black_24dp}" />
android:src="@drawable/ic_arrow_drop_down_black_24dp" />
</FrameLayout>
</LinearLayout>
</LinearLayout>

<LinearLayout
<net.cachapa.expandablelayout.ExpandableLayout
android:id="@+id/chapter_list_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/whiteLight"
android:orientation="vertical"
android:visibility="@{isListExpanded? View.VISIBLE : View.GONE}">
android:background="@color/colorPrimaryDark"
app:el_duration="300"
app:el_expanded="true">

<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_gravity="center_horizontal"
android:background="@drawable/dashed_divider" />

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/chapter_recycler_view"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="56dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>
android:background="@color/whiteLight"
android:orientation="vertical"
>

<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_gravity="center_horizontal"
android:background="@drawable/dashed_divider" />

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/chapter_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="56dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>

</net.cachapa.expandablelayout.ExpandableLayout>

</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</layout>
2 changes: 1 addition & 1 deletion app/src/main/res/values-v21/integers.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="duration_anim_300_ms">300</integer>
<integer name="default_fade_anim_time_ms">300</integer>
</resources>
4 changes: 4 additions & 0 deletions app/src/main/res/values/integers.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="default_fade_anim_time_ms">300</integer>
</resources>
Loading