From 83f3f7ff2ef03d1bd7ac9dfcd60ff6af3f164440 Mon Sep 17 00:00:00 2001 From: Blatzar <46196380+Blatzar@users.noreply.github.com> Date: Sun, 27 Mar 2022 18:45:02 +0200 Subject: [PATCH] heavily improved android tv anime page navigation --- .../lagradost/cloudstream3/MainActivity.kt | 8 +- .../cloudstream3/ui/result/ResultFragment.kt | 143 ++- .../cloudstream3/ui/result/ResultViewModel.kt | 18 +- app/src/main/res/color/tag_stroke_color.xml | 6 + app/src/main/res/layout/fragment_result.xml | 995 +++++++++--------- app/src/main/res/layout/result_tag.xml | 40 +- app/src/main/res/values/styles.xml | 36 +- 7 files changed, 667 insertions(+), 579 deletions(-) create mode 100644 app/src/main/res/color/tag_stroke_color.xml diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt index 11977c10..053c41f6 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt @@ -333,7 +333,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { } // this pulls the latest data so ppl don't have to update to simply change provider url - if(downloadFromGithub) { + if (downloadFromGithub) { try { runBlocking { withContext(Dispatchers.IO) { @@ -379,10 +379,12 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { apis = allProviders.filter { api -> val name = api.javaClass.simpleName // if the provider does not exist in the json file, then it is shown by default - !providersJsonMap.containsKey(name) || acceptableProviders.contains(name) || restrictedApis.contains(name) + !providersJsonMap.containsKey(name) || acceptableProviders.contains( + name + ) || restrictedApis.contains(name) } } - } catch (e : Exception) { + } catch (e: Exception) { logError(e) } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt index 2242abed..fd3a27fe 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt @@ -39,6 +39,7 @@ import com.google.android.gms.cast.framework.CastContext import com.google.android.gms.cast.framework.CastState import com.google.android.material.button.MaterialButton import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.APIHolder.getApiDubstatusSettings import com.lagradost.cloudstream3.APIHolder.getApiFromName import com.lagradost.cloudstream3.APIHolder.getId import com.lagradost.cloudstream3.AcraApplication.Companion.context @@ -583,7 +584,6 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio @SuppressLint("SetTextI18n") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - result_cast_items?.let { PanelsChildGestureRegionObserver.Provider.get().register(it) } @@ -1077,6 +1077,65 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio } } + /** + * Sets next focus to allow navigation up and down between 2 views + * if either of them is null nothing happens. + **/ + fun setFocusUpAndDown(upper: View?, down: View?) { + if (upper == null || down == null) return + upper.nextFocusDownId = down.id + down.nextFocusUpId = upper.id + } + + // This is to band-aid FireTV navigation + result_season_button?.isFocusableInTouchMode = context?.isTvSettings() == true + result_episode_select?.isFocusableInTouchMode = context?.isTvSettings() == true + result_dub_select?.isFocusableInTouchMode = context?.isTvSettings() == true + + observe(viewModel.selectedSeason) { season -> + result_season_button?.text = fromIndexToSeasonText(season) + } + + observe(viewModel.seasonSelections) { seasonList -> + result_season_button?.visibility = if (seasonList.size <= 1) GONE else VISIBLE.also { + + // If the season button is visible the result season button will be next focus down + if (result_series_parent?.isVisible == true) + setFocusUpAndDown(result_resume_series_button, result_season_button) + else + setFocusUpAndDown(result_bookmark_button, result_season_button) + } + + result_season_button?.setOnClickListener { + result_season_button?.popupMenuNoIconsAndNoStringRes( + items = seasonList + .map { Pair(it ?: -2, fromIndexToSeasonText(it)) }, + ) { + val id = this.itemId + + viewModel.changeSeason(if (id == -2) null else id) + } + } + } + + observe(viewModel.selectedRange) { range -> + result_episode_select?.text = range + } + + observe(viewModel.rangeOptions) { range -> + episodeRanges = range + result_episode_select?.visibility = if (range.size <= 1) GONE else VISIBLE.also { + + // If Season button is invisible then the bookmark button next focus is episode select + if (result_season_button?.isVisible != true) { + if (result_series_parent?.isVisible == true) + setFocusUpAndDown(result_resume_series_button, result_episode_select) + else + setFocusUpAndDown(result_bookmark_button, result_episode_select) + } + } + } + observe(viewModel.episodes) { episodeList -> lateFixDownloadButton(episodeList.size <= 1) // movies can have multible parts but still be *movies* this will fix this var isSeriesVisible = false @@ -1118,6 +1177,17 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio } result_series_parent?.isVisible = isSeriesVisible + if (isSeriesVisible) { + val down = when { + result_season_button?.isVisible == true -> result_season_button + result_episode_select?.isVisible == true -> result_episode_select + result_dub_select?.isVisible == true -> result_dub_select + else -> null + } + setFocusUpAndDown(result_resume_series_button, down) + setFocusUpAndDown(result_bookmark_button, result_resume_series_button) + } + result_resume_progress_holder?.isVisible = isProgressVisible context?.getString(if (isProgressVisible) R.string.resume else R.string.play_movie_button) ?.let { @@ -1150,28 +1220,7 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio startValue = null } - observe(viewModel.selectedSeason) - { season -> - result_season_button?.text = fromIndexToSeasonText(season) - } - - observe(viewModel.seasonSelections) - { seasonList -> - result_season_button?.visibility = if (seasonList.size <= 1) GONE else VISIBLE - result_season_button?.setOnClickListener { - result_season_button?.popupMenuNoIconsAndNoStringRes( - items = seasonList - .map { Pair(it ?: -2, fromIndexToSeasonText(it)) }, - ) { - val id = this.itemId - - viewModel.changeSeason(if (id == -2) null else id) - } - } - } - - observe(viewModel.publicEpisodes) - { episodes -> + observe(viewModel.publicEpisodes) { episodes -> when (episodes) { is Resource.Failure -> { result_episode_loading?.isVisible = false @@ -1193,42 +1242,50 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio } } - observe(viewModel.dubStatus) - { status -> + observe(viewModel.dubStatus) { status -> result_dub_select?.text = status.toString() } - observe(viewModel.dubSubSelections) - { range -> + val preferDub = context?.getApiDubstatusSettings()?.all { it == DubStatus.Dubbed } == true + + observe(viewModel.dubSubSelections) { range -> dubRange = range + + if (preferDub && dubRange?.contains(DubStatus.Dubbed) == true){ + viewModel.changeDubStatus(DubStatus.Dubbed) + } + result_dub_select?.visibility = if (range.size <= 1) GONE else VISIBLE + + if (result_season_button?.isVisible != true && result_episode_select?.isVisible != true) { + if (result_series_parent?.isVisible == true) + setFocusUpAndDown(result_resume_series_button, result_dub_select) + else + setFocusUpAndDown(result_bookmark_button, result_dub_select) + } + } + + result_cast_items?.setOnFocusChangeListener { v, hasFocus -> + // Always escape focus + if (hasFocus) result_bookmark_button?.requestFocus() } result_dub_select.setOnClickListener { val ranges = dubRange if (ranges != null) { - it.popupMenuNoIconsAndNoStringRes(ranges.map { status -> - Pair( - status.ordinal, - status.toString() - ) - } + it.popupMenuNoIconsAndNoStringRes(ranges + .map { status -> + Pair( + status.ordinal, + status.toString() + ) + } .toList()) { viewModel.changeDubStatus(DubStatus.values()[itemId]) } } } - observe(viewModel.selectedRange) - { range -> - result_episode_select?.text = range - } - - observe(viewModel.rangeOptions) { range -> - episodeRanges = range - result_episode_select?.visibility = if (range.size <= 1) GONE else VISIBLE - } - result_episode_select.setOnClickListener { val ranges = episodeRanges if (ranges != null) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt index 22e44bbd..fc346256 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt @@ -44,7 +44,6 @@ class ResultViewModel : ViewModel() { private var repo: APIRepository? = null private var generator: IGenerator? = null - private val _resultResponse: MutableLiveData> = MutableLiveData() private val _episodes: MutableLiveData> = MutableLiveData() private val episodeById: MutableLiveData> = @@ -190,7 +189,7 @@ class ResultViewModel : ViewModel() { } fun changeDubStatus(status: DubStatus?) { - if(status == null) return + if (status == null) return dubSubEpisodes.value?.get(status)?.let { episodes -> id.value?.let { setDub(it, status) @@ -220,7 +219,10 @@ class ResultViewModel : ViewModel() { currentSubs.add(sub) }) - return@safeApiCall Pair(currentLinks.toSet(), currentSubs.toSet()) as Pair, Set> + return@safeApiCall Pair( + currentLinks.toSet(), + currentSubs.toSet() + ) } } @@ -247,13 +249,15 @@ class ResultViewModel : ViewModel() { generator = RepoLinkGenerator(list) val set = HashMap() + val range = selectedRangeInt.value list.withIndex().forEach { set[it.value.id] = it.index } episodeById.postValue(set) filterEpisodes( list, - if (selection == -1) getResultSeason(localId ?: id.value ?: return) else selection, null + if (selection == -1) getResultSeason(localId ?: id.value ?: return) else selection, + range ) } @@ -330,9 +334,7 @@ class ResultViewModel : ViewModel() { val status = getDub(mainId) val statuses = d.episodes.map { it.key } val dubStatus = if (statuses.contains(status)) status else statuses.first() - _dubStatus.postValue(dubStatus) - _dubSubSelections.postValue(d.episodes.keys) val fillerEpisodes = if (showFillers) safeApiCall { getFillerEpisodes(d.name) } else null @@ -366,10 +368,14 @@ class ResultViewModel : ViewModel() { Pair(ep.key, episodes) }.toMap() + + // These posts needs to be in this order as to make the preferDub in ResultFragment work _dubSubEpisodes.postValue(res) res[dubStatus]?.let { episodes -> updateEpisodes(mainId, episodes, -1) } + _dubStatus.postValue(dubStatus) + _dubSubSelections.postValue(d.episodes.keys) } is TvSeriesLoadResponse -> { diff --git a/app/src/main/res/color/tag_stroke_color.xml b/app/src/main/res/color/tag_stroke_color.xml new file mode 100644 index 00000000..1e4b50c5 --- /dev/null +++ b/app/src/main/res/color/tag_stroke_color.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_result.xml b/app/src/main/res/layout/fragment_result.xml index 53a28d49..7fed424b 100644 --- a/app/src/main/res/layout/fragment_result.xml +++ b/app/src/main/res/layout/fragment_result.xml @@ -1,46 +1,46 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/result_root" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="?attr/primaryBlackBackground" + android:clickable="true" + android:focusable="true"> + android:id="@+id/result_loading" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="center" + android:orientation="vertical" + app:shimmer_auto_start="true" + app:shimmer_base_alpha="0.2" + app:shimmer_duration="@integer/loading_time" + app:shimmer_highlight_alpha="0.3" + tools:visibility="gone"> + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="@dimen/result_padding" + android:orientation="vertical"> + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_marginBottom="@dimen/loading_margin" + android:orientation="horizontal"> + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_marginStart="@dimen/loading_margin" + android:layout_marginEnd="@dimen/loading_margin" + android:orientation="vertical"> @@ -55,9 +55,9 @@ + android:layout_width="match_parent" + android:layout_height="20dp" + tools:ignore="ContentDescription" /> @@ -74,94 +74,94 @@ android:layout_width="50dp" android:layout_height="50dp"> --> + + + android:layout_margin="5dp" + android:minWidth="200dp" + android:text="@string/reload_error" + app:icon="@drawable/ic_baseline_autorenew_24" /> - - + android:layout_gravity="center" + android:layout_margin="5dp" + android:minWidth="200dp" + android:text="@string/result_open_in_browser" + app:icon="@drawable/ic_baseline_public_24" /> + android:id="@+id/result_error_text" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:layout_margin="5dp" + android:gravity="center" + android:textColor="?attr/textColor" /> + android:id="@+id/result_finish_loading" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:visibility="gone" + tools:visibility="visible"> + + + android:layout_height="match_parent" + android:alpha="0" + android:background="?attr/primaryGrayBackground" + android:scaleType="centerCrop" + tools:ignore="ContentDescription" + tools:src="@drawable/example_poster" /> - - + android:layout_width="match_parent" + android:layout_height="30dp" + android:layout_gravity="bottom" + android:src="@drawable/background_shadow" + tools:ignore="ContentDescription" /> + android:layout_height="wrap_content" + android:background="?attr/primaryGrayBackground"> + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="?attr/primaryBlackBackground" + android:orientation="vertical"> + android:layout_width="match_parent" + android:layout_height="match_parent" + android:clipToPadding="false" + android:orientation="vertical" + android:paddingStart="@dimen/result_padding" + android:paddingEnd="@dimen/result_padding"> + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="10dp" + android:layout_marginBottom="15dp" + android:orientation="horizontal" + android:visibility="visible"> + android:id="@+id/result_poster_holder" + android:layout_width="100dp" + android:layout_height="140dp" + app:cardCornerRadius="@dimen/rounded_image_radius"> + android:layout_width="match_parent" + android:layout_height="match_parent" + android:contentDescription="@string/result_poster_img_des" + android:foreground="@drawable/outline_drawable" + android:scaleType="centerCrop" + tools:src="@drawable/example_poster" /> + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_marginStart="10dp" + android:orientation="vertical"> + android:id="@+id/result_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="5dp" + android:maxLines="2" + android:textColor="?attr/textColor" + android:textSize="20sp" + android:textStyle="bold" + tools:text="The Perfect Run The Perfect Run" /> + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:itemSpacing="10dp"> + android:id="@+id/result_meta_site" + style="@style/SmallBlackButton" + android:layout_gravity="center_vertical" + tools:text="Gogoanime" /> + android:id="@+id/result_meta_type" + style="@style/ResultInfoText" + tools:text="Movie" /> + android:id="@+id/result_meta_year" + style="@style/ResultInfoText" + tools:text="2022" /> + android:id="@+id/result_meta_rating" + style="@style/ResultInfoText" + tools:text="Rated: 8.5/10.0" /> + android:id="@+id/result_meta_status" + style="@style/ResultInfoText" + tools:text="Ongoing" /> + android:id="@+id/result_meta_duration" + style="@style/ResultInfoText" + tools:text="121min" /> + android:layout_width="match_parent" + android:layout_height="match_parent"> + android:paddingTop="5dp" + android:paddingBottom="0dp" + android:textColor="?attr/textColor" + android:textSize="15sp" + tools:text="Ryan Quicksave Romano is an eccentric adventurer with a strange power: he can create a save-point in time and redo his life whenever he dies. Arriving in New Rome, the glitzy capital of sin of a rebuilding Europe, he finds the city torn between mega-corporations, sponsored heroes, superpowered criminals, and true monsters. It's a time of chaos, where potions can grant the power to rule the world and dangers lurk everywhere. " /> + android:layout_width="match_parent" + android:layout_height="30dp" + android:layout_gravity="bottom" + android:src="@drawable/background_shadow" + tools:ignore="ContentDescription" /> + android:nextFocusDown="@id/result_play_movie" + android:paddingTop="0dp" + app:cornerRadius="4dp" + app:icon="@drawable/ic_baseline_bookmark_24" + tools:text="Bookmark" + tools:visibility="gone"> + android:id="@+id/result_cast_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="5dp" + android:ellipsize="end" + android:maxLines="2" + android:textColor="?attr/grayTextColor" + android:textSize="15sp" + tools:text="Cast: Joe Ligma" /> + android:id="@+id/result_cast_items" + android:layout_width="match_parent" + android:descendantFocusability="afterDescendants" + android:layout_height="wrap_content" + android:fadingEdge="horizontal" + android:focusableInTouchMode="false" + android:focusable="false" + android:orientation="horizontal" + android:paddingTop="5dp" + android:requiresFadingEdge="horizontal" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" + tools:itemCount="2" + tools:listitem="@layout/cast_item" /> + android:id="@+id/result_vpn" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textColor="?attr/grayTextColor" + android:textSize="15sp" + tools:text="@string/vpn_torrent" /> + android:id="@+id/result_info" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="5dp" + android:textColor="?attr/grayTextColor" + android:textSize="15sp" + tools:text="@string/provider_info_meta" /> + android:id="@+id/result_tag_holder" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="10dp" + android:layout_marginBottom="10dp" + android:text="@string/result_tags" + android:textColor="?attr/textColor" + android:textSize="17sp" + android:textStyle="normal" + android:visibility="gone" /> + android:id="@+id/result_tag" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + android:id="@+id/result_coming_soon" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:gravity="center" + android:paddingTop="50dp" + android:text="@string/coming_soon" + android:textColor="?attr/textColor" + android:textSize="20sp" + android:textStyle="bold" + android:visibility="gone" /> + android:id="@+id/result_data_holder" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + + + + - - - - + android:nextFocusUp="@id/result_bookmark_button" + android:nextFocusDown="@id/result_download_movie" + android:text="@string/play_movie_button" + android:visibility="visible" + app:icon="@drawable/ic_baseline_play_arrow_24" /> + android:layout_width="match_parent" + android:layout_height="wrap_content"> + android:nextFocusUp="@id/result_play_movie" + android:nextFocusDown="@id/result_season_button" + android:visibility="visible" /> + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:gravity="center" + android:orientation="horizontal"> + android:id="@+id/result_movie_progress_downloaded" + style="?android:attr/progressBarStyleHorizontal" + android:layout_width="25dp" + android:layout_height="25dp" + android:layout_gravity="end|center_vertical" + android:layout_margin="5dp" + android:background="@drawable/circle_shape" + android:indeterminate="false" + android:max="100" + android:paddingStart="5dp" + android:paddingEnd="5dp" + android:progress="30" + android:progressDrawable="@drawable/circular_progress_bar_filled" + android:visibility="visible" /> + android:id="@+id/result_movie_download_icon" + android:layout_width="30dp" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:background="?selectableItemBackgroundBorderless" + android:contentDescription="@string/download" + android:src="@drawable/ic_baseline_play_arrow_24" + android:visibility="visible" + app:tint="?attr/white" /> + android:id="@+id/result_movie_download_text" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:gravity="center" + android:letterSpacing="0.09" + android:textAllCaps="false" + android:textColor="?attr/textColor" + android:textSize="15sp" + android:textStyle="bold" + tools:text="Downloading" /> + android:id="@+id/result_movie_download_text_precentage" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:gravity="center" + android:letterSpacing="0.09" + android:paddingStart="5dp" + android:paddingEnd="5dp" + android:textAllCaps="false" + android:textColor="?attr/textColor" + android:textSize="15sp" + android:textStyle="bold" + android:visibility="gone" + tools:text="68%" /> @@ -639,179 +643,178 @@ + android:id="@+id/result_series_parent" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="5dp" + android:orientation="vertical" + android:visibility="gone" + tools:visibility="visible"> + android:layout_gravity="center_vertical" + android:layout_marginStart="0dp" + android:layout_marginEnd="0dp" + android:layout_marginBottom="10dp" + android:nextFocusUp="@id/result_bookmark_button" + android:nextFocusDown="@id/result_download_movie" + android:text="@string/resume" + android:visibility="visible" + app:icon="@drawable/ic_baseline_play_arrow_24" + tools:visibility="visible" /> - - - - - - + android:layout_gravity="center_vertical" + android:layout_marginStart="0dp" + android:layout_marginEnd="0dp" + android:layout_marginBottom="10dp" + android:nextFocusUp="@id/result_bookmark_button" + android:nextFocusDown="@id/result_download_movie" + android:text="@string/next_episode" + android:visibility="gone" + app:icon="@drawable/cast_ic_mini_controller_skip_next" /> - - - + android:textColor="?attr/textColor" + android:textSize="17sp" + android:textStyle="bold" + tools:text="S1E1 Episode 1" /> + + + + + + + + + + + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="10dp" + android:gravity="center_vertical" + android:orientation="horizontal"> + android:id="@+id/result_season_button" + style="@style/MultiSelectButton" + android:layout_gravity="center_vertical" + android:layout_marginStart="0dp" + android:nextFocusLeft="@id/result_episode_select" + android:nextFocusRight="@id/result_episode_select" + android:nextFocusUp="@id/result_descript" + android:nextFocusDown="@id/result_episodes" + android:visibility="gone" + tools:text="Season 1" + tools:visibility="visible" /> + android:nextFocusUp="@id/result_descript" + android:nextFocusDown="@id/result_episodes" + android:visibility="gone" + tools:text="50-100" + tools:visibility="visible" /> + android:nextFocusUp="@id/result_descript" + android:nextFocusDown="@id/result_episodes" + android:visibility="gone" + tools:text="Dubbed" + tools:visibility="visible" /> + android:id="@+id/result_episodes_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:paddingTop="10dp" + android:paddingBottom="10dp" + android:textColor="?attr/textColor" + android:textSize="17sp" + android:textStyle="normal" + tools:text="8 Episodes" /> + android:id="@+id/result_episode_loading" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="center" + android:layout_marginTop="15dp" + android:orientation="vertical" + app:shimmer_auto_start="true" + app:shimmer_base_alpha="0.2" + app:shimmer_duration="@integer/loading_time" + app:shimmer_highlight_alpha="0.3" + tools:visibility="visible"> + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> @@ -831,14 +834,14 @@ android:layout_height="50dp" />--> + android:id="@+id/result_episodes" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="0dp" + android:clipToPadding="false" + android:descendantFocusability="afterDescendants" + android:paddingBottom="100dp" + tools:listitem="@layout/result_episode" /> diff --git a/app/src/main/res/layout/result_tag.xml b/app/src/main/res/layout/result_tag.xml index b83a800c..9a75b58d 100644 --- a/app/src/main/res/layout/result_tag.xml +++ b/app/src/main/res/layout/result_tag.xml @@ -1,28 +1,28 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="-4dp" + android:layout_marginBottom="-4dp" + android:paddingLeft="2dp" + android:paddingTop="-10dp" + android:paddingRight="2dp"> + android:id="@+id/result_tag_card" + style="@style/Tag" + android:layout_width="wrap_content" + android:layout_height="37dp" + android:minWidth="0dp" + android:minHeight="0dp" + android:textAllCaps="false" + android:textColor="?attr/textColor" + android:textSize="12sp" + app:cornerRadius="100dp" + tools:text="Test"> \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 389c8c8e..8527d4bc 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -186,8 +186,7 @@ ?attr/primaryBlackBackground - - + + @@ -242,8 +241,8 @@ wrap_content 24dp 0dp - + + + + + + + \ No newline at end of file