Migrate to ViewPager2 (#1544)

* migrate MainActivty to ViewPager2

* migrate AccountActivty to ViewPager2

* migrate ViewMediaActivty to ViewPager2

* migrate SearchActivity to ViewPager2

* checkin missing AccountPagerAdapter file

* remove unused class ImageViewPager

* replace SparseArray with MutableList
This commit is contained in:
Konrad Pozniak 2019-11-06 20:17:53 +01:00 committed by GitHub
parent 52ac26a797
commit d2ca776b34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 213 additions and 349 deletions

View File

@ -114,6 +114,7 @@ dependencies {
implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.preference:preference:1.1.0' implementation 'androidx.preference:preference:1.1.0'
implementation 'androidx.sharetarget:sharetarget:1.0.0-beta01' implementation 'androidx.sharetarget:sharetarget:1.0.0-beta01'
implementation "androidx.viewpager2:viewpager2:1.0.0-rc01"
implementation "com.squareup.retrofit2:retrofit:$retrofitVersion" implementation "com.squareup.retrofit2:retrofit:$retrofitVersion"
implementation "com.squareup.retrofit2:converter-gson:$retrofitVersion" implementation "com.squareup.retrofit2:converter-gson:$retrofitVersion"
implementation "com.squareup.retrofit2:adapter-rxjava2:$retrofitVersion" implementation "com.squareup.retrofit2:adapter-rxjava2:$retrofitVersion"

View File

@ -37,6 +37,7 @@ import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProviders
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.viewpager2.widget.MarginPageTransformer
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.CollapsingToolbarLayout import com.google.android.material.appbar.CollapsingToolbarLayout
@ -45,6 +46,7 @@ import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.shape.ShapeAppearanceModel import com.google.android.material.shape.ShapeAppearanceModel
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.keylesspalace.tusky.adapter.AccountFieldAdapter import com.keylesspalace.tusky.adapter.AccountFieldAdapter
import com.keylesspalace.tusky.components.report.ReportActivity import com.keylesspalace.tusky.components.report.ReportActivity
import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.di.ViewModelFactory
@ -187,16 +189,21 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
*/ */
private fun setupTabs() { private fun setupTabs() {
// Setup the tabs and timeline pager. // Setup the tabs and timeline pager.
adapter = AccountPagerAdapter(supportFragmentManager, viewModel.accountId) adapter = AccountPagerAdapter(this, viewModel.accountId)
val pageTitles = arrayOf(getString(R.string.title_statuses), getString(R.string.title_statuses_with_replies), getString(R.string.title_statuses_pinned), getString(R.string.title_media))
adapter.setPageTitles(pageTitles)
accountFragmentViewPager.pageMargin = resources.getDimensionPixelSize(R.dimen.tab_page_margin)
val pageMarginDrawable = ThemeUtils.getDrawable(this, R.attr.tab_page_margin_drawable,
R.drawable.tab_page_margin_dark)
accountFragmentViewPager.setPageMarginDrawable(pageMarginDrawable)
accountFragmentViewPager.adapter = adapter accountFragmentViewPager.adapter = adapter
accountFragmentViewPager.offscreenPageLimit = 2 accountFragmentViewPager.offscreenPageLimit = 2
accountTabLayout.setupWithViewPager(accountFragmentViewPager)
val pageTitles = arrayOf(getString(R.string.title_statuses), getString(R.string.title_statuses_with_replies), getString(R.string.title_statuses_pinned), getString(R.string.title_media))
TabLayoutMediator(accountTabLayout, accountFragmentViewPager) {
tab, position ->
tab.text = pageTitles[position]
}.attach()
val pageMargin = resources.getDimensionPixelSize(R.dimen.tab_page_margin)
accountFragmentViewPager.setPageTransformer(MarginPageTransformer(pageMargin))
accountTabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { accountTabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabReselected(tab: TabLayout.Tab?) { override fun onTabReselected(tab: TabLayout.Tab?) {
tab?.position?.let { position -> tab?.position?.let { position ->

View File

@ -33,11 +33,13 @@ import androidx.emoji.text.EmojiCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle; import androidx.lifecycle.Lifecycle;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import androidx.viewpager.widget.ViewPager; import androidx.viewpager2.widget.MarginPageTransformer;
import androidx.viewpager2.widget.ViewPager2;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import com.keylesspalace.tusky.appstore.CacheUpdater; import com.keylesspalace.tusky.appstore.CacheUpdater;
import com.keylesspalace.tusky.appstore.EventHub; import com.keylesspalace.tusky.appstore.EventHub;
import com.keylesspalace.tusky.appstore.MainTabsChangedEvent; import com.keylesspalace.tusky.appstore.MainTabsChangedEvent;
@ -53,7 +55,6 @@ import com.keylesspalace.tusky.pager.MainPagerAdapter;
import com.keylesspalace.tusky.util.CustomEmojiHelper; import com.keylesspalace.tusky.util.CustomEmojiHelper;
import com.keylesspalace.tusky.util.NotificationHelper; import com.keylesspalace.tusky.util.NotificationHelper;
import com.keylesspalace.tusky.util.ShareShortcutHelper; import com.keylesspalace.tusky.util.ShareShortcutHelper;
import com.keylesspalace.tusky.util.ThemeUtils;
import com.mikepenz.google_material_typeface_library.GoogleMaterial; import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import com.mikepenz.materialdrawer.AccountHeader; import com.mikepenz.materialdrawer.AccountHeader;
import com.mikepenz.materialdrawer.AccountHeaderBuilder; import com.mikepenz.materialdrawer.AccountHeaderBuilder;
@ -114,7 +115,7 @@ public final class MainActivity extends BottomSheetActivity implements ActionBut
private AccountHeader headerResult; private AccountHeader headerResult;
private Drawer drawer; private Drawer drawer;
private TabLayout tabLayout; private TabLayout tabLayout;
private ViewPager viewPager; private ViewPager2 viewPager;
private int notificationTabPosition; private int notificationTabPosition;
private MainPagerAdapter adapter; private MainPagerAdapter adapter;
@ -207,10 +208,7 @@ public final class MainActivity extends BottomSheetActivity implements ActionBut
setupTabs(showNotificationTab); setupTabs(showNotificationTab);
int pageMargin = getResources().getDimensionPixelSize(R.dimen.tab_page_margin); int pageMargin = getResources().getDimensionPixelSize(R.dimen.tab_page_margin);
viewPager.setPageMargin(pageMargin); viewPager.setPageTransformer(new MarginPageTransformer(pageMargin));
Drawable pageMarginDrawable = ThemeUtils.getDrawable(this, R.attr.tab_page_margin_drawable,
R.drawable.tab_page_margin_dark);
viewPager.setPageMarginDrawable(pageMarginDrawable);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override @Override
@ -467,10 +465,11 @@ public final class MainActivity extends BottomSheetActivity implements ActionBut
private void setupTabs(boolean selectNotificationTab) { private void setupTabs(boolean selectNotificationTab) {
List<TabData> tabs = accountManager.getActiveAccount().getTabPreferences(); List<TabData> tabs = accountManager.getActiveAccount().getTabPreferences();
adapter = new MainPagerAdapter(tabs, getSupportFragmentManager()); adapter = new MainPagerAdapter(tabs, this);
viewPager.setAdapter(adapter); viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager); new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> { }).attach();
tabLayout.removeAllTabs(); tabLayout.removeAllTabs();
for (int i = 0; i < tabs.size(); i++) { for (int i = 0; i < tabs.size(); i++) {
TabLayout.Tab tab = tabLayout.newTab() TabLayout.Tab tab = tabLayout.newTab()

View File

@ -37,9 +37,10 @@ import android.view.View
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import android.widget.Toast import android.widget.Toast
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.viewpager.widget.PagerAdapter import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager.widget.ViewPager import androidx.viewpager2.widget.ViewPager2
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.FutureTarget import com.bumptech.glide.request.FutureTarget
import com.keylesspalace.tusky.BuildConfig.APPLICATION_ID import com.keylesspalace.tusky.BuildConfig.APPLICATION_ID
@ -110,23 +111,23 @@ class ViewMediaActivity : BaseActivity(), ViewImageFragment.PhotoActionsListener
// Adapter is actually of existential type PageAdapter & SharedElementsTransitionListener // Adapter is actually of existential type PageAdapter & SharedElementsTransitionListener
// but it cannot be expressed and if I don't specify type explicitly compilation fails // but it cannot be expressed and if I don't specify type explicitly compilation fails
// (probably a bug in compiler) // (probably a bug in compiler)
val adapter: PagerAdapter = if (attachments != null) { val adapter: ViewMediaAdapter = if (attachments != null) {
val realAttachs = attachments!!.map(AttachmentViewData::attachment) val realAttachs = attachments!!.map(AttachmentViewData::attachment)
// Setup the view pager. // Setup the view pager.
ImagePagerAdapter(supportFragmentManager, realAttachs, initialPosition) ImagePagerAdapter(this, realAttachs, initialPosition)
} else { } else {
val avatarUrl = intent.getStringExtra(EXTRA_AVATAR_URL) val avatarUrl = intent.getStringExtra(EXTRA_AVATAR_URL)
?: throw IllegalArgumentException("attachment list or avatar url has to be set") ?: throw IllegalArgumentException("attachment list or avatar url has to be set")
AvatarImagePagerAdapter(supportFragmentManager, avatarUrl) AvatarImagePagerAdapter(this, avatarUrl)
} }
viewPager.adapter = adapter viewPager.adapter = adapter
viewPager.currentItem = initialPosition viewPager.setCurrentItem(initialPosition, false)
viewPager.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() { viewPager.registerOnPageChangeCallback(object: ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) { override fun onPageSelected(position: Int) {
toolbar.title = adapter.getPageTitle(position) toolbar.title = getPageTitle(position)
} }
}) })
@ -136,7 +137,7 @@ class ViewMediaActivity : BaseActivity(), ViewImageFragment.PhotoActionsListener
if (actionBar != null) { if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true) actionBar.setDisplayHomeAsUpEnabled(true)
actionBar.setDisplayShowHomeEnabled(true) actionBar.setDisplayShowHomeEnabled(true)
actionBar.title = adapter.getPageTitle(initialPosition) actionBar.title = getPageTitle(initialPosition)
} }
toolbar.setNavigationOnClickListener { supportFinishAfterTransition() } toolbar.setNavigationOnClickListener { supportFinishAfterTransition() }
toolbar.setOnMenuItemClickListener { item: MenuItem -> toolbar.setOnMenuItemClickListener { item: MenuItem ->
@ -153,7 +154,7 @@ class ViewMediaActivity : BaseActivity(), ViewImageFragment.PhotoActionsListener
window.statusBarColor = Color.BLACK window.statusBarColor = Color.BLACK
window.sharedElementEnterTransition.addListener(object : NoopTransitionListener { window.sharedElementEnterTransition.addListener(object : NoopTransitionListener {
override fun onTransitionEnd(transition: Transition) { override fun onTransitionEnd(transition: Transition) {
(adapter as SharedElementTransitionListener).onTransitionEnd() adapter.onTransitionEnd(viewPager.currentItem)
window.sharedElementEnterTransition.removeListener(this) window.sharedElementEnterTransition.removeListener(this)
} }
}) })
@ -198,6 +199,13 @@ class ViewMediaActivity : BaseActivity(), ViewImageFragment.PhotoActionsListener
.start() .start()
} }
private fun getPageTitle(position: Int): CharSequence {
if(attachments == null) {
return ""
}
return String.format(Locale.getDefault(), "%d/%d", position + 1, attachments?.size)
}
private fun downloadMedia() { private fun downloadMedia() {
val url = attachments!![viewPager.currentItem].attachment.url val url = attachments!![viewPager.currentItem].attachment.url
val filename = Uri.parse(url).lastPathSegment val filename = Uri.parse(url).lastPathSegment
@ -323,8 +331,8 @@ class ViewMediaActivity : BaseActivity(), ViewImageFragment.PhotoActionsListener
} }
} }
interface SharedElementTransitionListener { abstract class ViewMediaAdapter(activity: FragmentActivity): FragmentStateAdapter(activity) {
fun onTransitionEnd() abstract fun onTransitionEnd(position: Int)
} }
interface NoopTransitionListener : Transition.TransitionListener { interface NoopTransitionListener : Transition.TransitionListener {

View File

@ -23,6 +23,7 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProviders
import com.google.android.material.tabs.TabLayoutMediator
import com.keylesspalace.tusky.BottomSheetActivity import com.keylesspalace.tusky.BottomSheetActivity
import com.keylesspalace.tusky.R import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.components.search.adapter.SearchPagerAdapter import com.keylesspalace.tusky.components.search.adapter.SearchPagerAdapter
@ -57,8 +58,12 @@ class SearchActivity : BottomSheetActivity(), SearchView.OnQueryTextListener, Ha
} }
private fun setupPages() { private fun setupPages() {
pages.adapter = SearchPagerAdapter(this, supportFragmentManager) pages.adapter = SearchPagerAdapter(this)
tabs.setupWithViewPager(pages)
TabLayoutMediator(tabs, pages) {
tab, position ->
tab.text = getPageTitle(position)
}.attach()
} }
override fun onNewIntent(intent: Intent) { override fun onNewIntent(intent: Intent) {
@ -99,6 +104,15 @@ class SearchActivity : BottomSheetActivity(), SearchView.OnQueryTextListener, Ha
return false return false
} }
private fun getPageTitle(position: Int): CharSequence? {
return when (position) {
0 -> getString(R.string.title_statuses)
1 -> getString(R.string.title_accounts)
2 -> getString(R.string.title_hashtags_dialog)
else -> throw IllegalArgumentException("Unknown page index: $position")
}
}
private fun handleIntent(intent: Intent) { private fun handleIntent(intent: Intent) {
if (Intent.ACTION_SEARCH == intent.action) { if (Intent.ACTION_SEARCH == intent.action) {
viewModel.currentQuery = intent.getStringExtra(SearchManager.QUERY) viewModel.currentQuery = intent.getStringExtra(SearchManager.QUERY)

View File

@ -15,18 +15,16 @@
package com.keylesspalace.tusky.components.search.adapter package com.keylesspalace.tusky.components.search.adapter
import android.content.Context
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentPagerAdapter import androidx.viewpager2.adapter.FragmentStateAdapter
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.components.search.SearchType
import com.keylesspalace.tusky.components.search.fragments.SearchAccountsFragment import com.keylesspalace.tusky.components.search.fragments.SearchAccountsFragment
import com.keylesspalace.tusky.components.search.fragments.SearchHashtagsFragment import com.keylesspalace.tusky.components.search.fragments.SearchHashtagsFragment
import com.keylesspalace.tusky.components.search.fragments.SearchStatusesFragment import com.keylesspalace.tusky.components.search.fragments.SearchStatusesFragment
class SearchPagerAdapter(private val context: Context, manager: FragmentManager) : FragmentPagerAdapter(manager) { class SearchPagerAdapter(activity: FragmentActivity) : FragmentStateAdapter(activity) {
override fun getItem(position: Int): Fragment {
override fun createFragment(position: Int): Fragment {
return when (position) { return when (position) {
0 -> SearchStatusesFragment.newInstance() 0 -> SearchStatusesFragment.newInstance()
1 -> SearchAccountsFragment.newInstance() 1 -> SearchAccountsFragment.newInstance()
@ -35,14 +33,6 @@ class SearchPagerAdapter(private val context: Context, manager: FragmentManager)
} }
} }
override fun getPageTitle(position: Int): CharSequence? { override fun getItemCount() = 3
return when (position) {
0 -> context.getString(R.string.title_statuses)
1 -> context.getString(R.string.title_accounts)
2 -> context.getString(R.string.title_hashtags_dialog)
else -> throw IllegalArgumentException("Unknown page index: $position")
}
}
override fun getCount(): Int = 3
} }

View File

@ -81,7 +81,6 @@ class AccountMediaFragment : BaseFragment(), RefreshableFragment, Injectable {
private var currentCall: Call<List<Status>>? = null private var currentCall: Call<List<Status>>? = null
private val statuses = mutableListOf<Status>() private val statuses = mutableListOf<Status>()
private var fetchingStatus = FetchingStatus.NOT_FETCHING private var fetchingStatus = FetchingStatus.NOT_FETCHING
private var isVisibleToUser: Boolean = false
private lateinit var accountId: String private lateinit var accountId: String
@ -216,7 +215,7 @@ class AccountMediaFragment : BaseFragment(), RefreshableFragment, Injectable {
} }
}) })
if (isVisibleToUser) doInitialLoadingIfNeeded() doInitialLoadingIfNeeded()
} }
private fun refresh() { private fun refresh() {
@ -235,14 +234,6 @@ class AccountMediaFragment : BaseFragment(), RefreshableFragment, Injectable {
topProgressBar?.show() topProgressBar?.show()
} }
// That's sort of an optimization to only load media once user has opened the tab
// Attention: can be called before *any* lifecycle method!
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
this.isVisibleToUser = isVisibleToUser
if (isVisibleToUser && isAdded) doInitialLoadingIfNeeded()
}
private fun doInitialLoadingIfNeeded() { private fun doInitialLoadingIfNeeded() {
if (isAdded) { if (isAdded) {
statusView.hide() statusView.hide()

View File

@ -18,13 +18,12 @@ package com.keylesspalace.tusky.fragment
import android.os.Bundle import android.os.Bundle
import android.text.TextUtils import android.text.TextUtils
import android.widget.TextView import android.widget.TextView
import com.keylesspalace.tusky.SharedElementTransitionListener
import com.keylesspalace.tusky.ViewMediaActivity import com.keylesspalace.tusky.ViewMediaActivity
import com.keylesspalace.tusky.entity.Attachment import com.keylesspalace.tusky.entity.Attachment
import com.keylesspalace.tusky.util.visible import com.keylesspalace.tusky.util.visible
abstract class ViewMediaFragment : BaseFragment(), SharedElementTransitionListener { abstract class ViewMediaFragment : BaseFragment() {
private var toolbarVisibiltyDisposable: Function0<Boolean>? = null private var toolbarVisibiltyDisposable: Function0<Boolean>? = null
abstract fun setupMediaView(url: String, previewUrl: String?) abstract fun setupMediaView(url: String, previewUrl: String?)
@ -71,6 +70,8 @@ abstract class ViewMediaFragment : BaseFragment(), SharedElementTransitionListen
} }
} }
abstract fun onTransitionEnd()
protected fun finalizeViewSetup(url: String, previewUrl: String?, description: String?) { protected fun finalizeViewSetup(url: String, previewUrl: String?, description: String?) {
val mediaActivity = activity as ViewMediaActivity val mediaActivity = activity as ViewMediaActivity
setupMediaView(url, previewUrl) setupMediaView(url, previewUrl)

View File

@ -1,120 +0,0 @@
/* Copyright 2017 Andrew Dawson
*
* This file is a part of Tusky.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.pager;
import android.util.SparseArray;
import android.view.ViewGroup;
import com.keylesspalace.tusky.fragment.AccountMediaFragment;
import com.keylesspalace.tusky.fragment.TimelineFragment;
import com.keylesspalace.tusky.interfaces.RefreshableFragment;
import java.util.HashSet;
import java.util.Set;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
public class AccountPagerAdapter extends FragmentPagerAdapter {
private static final int TAB_COUNT = 4;
private String accountId;
private String[] pageTitles;
private SparseArray<Fragment> fragments = new SparseArray<>(TAB_COUNT);
private final Set<Integer> pagesToRefresh = new HashSet<>();
public AccountPagerAdapter(FragmentManager manager, String accountId) {
super(manager);
this.accountId = accountId;
}
public void setPageTitles(String[] titles) {
pageTitles = titles;
}
@NonNull
@Override
public Fragment getItem(int position) {
switch (position) {
case 0: {
return TimelineFragment.newInstance(TimelineFragment.Kind.USER, accountId,false);
}
case 1: {
return TimelineFragment.newInstance(TimelineFragment.Kind.USER_WITH_REPLIES, accountId,false);
}
case 2: {
return TimelineFragment.newInstance(TimelineFragment.Kind.USER_PINNED, accountId,false);
}
case 3: {
return AccountMediaFragment.newInstance(accountId,false);
}
default: {
throw new AssertionError("Page " + position + " is out of AccountPagerAdapter bounds");
}
}
}
@Override
public int getCount() {
return TAB_COUNT;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
Object fragment = super.instantiateItem(container, position);
if (fragment instanceof Fragment)
fragments.put(position, (Fragment) fragment);
if (pagesToRefresh.contains(position)) {
if (fragment instanceof RefreshableFragment)
((RefreshableFragment) fragment).refreshContent();
pagesToRefresh.remove(position);
}
return fragment;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
super.destroyItem(container, position, object);
fragments.remove(position);
}
@Override
public CharSequence getPageTitle(int position) {
return pageTitles[position];
}
@Nullable
public Fragment getFragment(int position) {
return fragments.get(position);
}
public void refreshContent(){
for (int i=0;i<getCount();i++){
Fragment fragment = getFragment(i);
if (fragment instanceof RefreshableFragment){
((RefreshableFragment) fragment).refreshContent();
}
else{
pagesToRefresh.add(i);
}
}
}
}

View File

@ -0,0 +1,65 @@
/* Copyright 2019 Tusky Contributors
*
* This file is a part of Tusky.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.pager
import androidx.fragment.app.*
import com.keylesspalace.tusky.fragment.AccountMediaFragment
import com.keylesspalace.tusky.fragment.TimelineFragment
import com.keylesspalace.tusky.interfaces.RefreshableFragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import java.lang.ref.WeakReference
class AccountPagerAdapter(
activity: FragmentActivity,
private val accountId: String
) : FragmentStateAdapter(activity) {
private val fragments = MutableList<WeakReference<Fragment>?>(TAB_COUNT) { null }
override fun getItemCount() = TAB_COUNT
override fun createFragment(position: Int): Fragment {
val fragment: Fragment = when (position) {
0 -> TimelineFragment.newInstance(TimelineFragment.Kind.USER, accountId, false)
1 -> TimelineFragment.newInstance(TimelineFragment.Kind.USER_WITH_REPLIES, accountId, false)
2 -> TimelineFragment.newInstance(TimelineFragment.Kind.USER_PINNED, accountId, false)
3 -> AccountMediaFragment.newInstance(accountId, false)
else -> throw AssertionError("Page $position is out of AccountPagerAdapter bounds")
}
fragments[position] = WeakReference(fragment)
return fragment
}
fun getFragment(position: Int): Fragment? {
return fragments[position]?.get()
}
fun refreshContent() {
for (i in 0 until TAB_COUNT) {
val fragment = getFragment(i)
if (fragment != null && fragment is RefreshableFragment) {
(fragment as RefreshableFragment).refreshContent()
}
}
}
companion object {
private const val TAB_COUNT = 4
}
}

View File

@ -1,13 +1,16 @@
package com.keylesspalace.tusky.pager package com.keylesspalace.tusky.pager
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentPagerAdapter import com.keylesspalace.tusky.ViewMediaAdapter
import com.keylesspalace.tusky.SharedElementTransitionListener
import com.keylesspalace.tusky.fragment.ViewMediaFragment import com.keylesspalace.tusky.fragment.ViewMediaFragment
class AvatarImagePagerAdapter(fragmentManager: FragmentManager, private val avatarUrl: String) : FragmentPagerAdapter(fragmentManager), SharedElementTransitionListener { class AvatarImagePagerAdapter(
override fun getItem(position: Int): Fragment { activity: FragmentActivity,
private val avatarUrl: String
) : ViewMediaAdapter(activity) {
override fun createFragment(position: Int): Fragment {
return if (position == 0) { return if (position == 0) {
ViewMediaFragment.newAvatarInstance(avatarUrl) ViewMediaFragment.newAvatarInstance(avatarUrl)
} else { } else {
@ -15,8 +18,8 @@ class AvatarImagePagerAdapter(fragmentManager: FragmentManager, private val avat
} }
} }
override fun getCount() = 1 override fun getItemCount() = 1
override fun onTransitionEnd() { override fun onTransitionEnd(position: Int) {
} }
} }

View File

@ -1,53 +1,42 @@
package com.keylesspalace.tusky.pager package com.keylesspalace.tusky.pager
import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentStatePagerAdapter import com.keylesspalace.tusky.ViewMediaAdapter
import com.keylesspalace.tusky.SharedElementTransitionListener
import com.keylesspalace.tusky.entity.Attachment import com.keylesspalace.tusky.entity.Attachment
import com.keylesspalace.tusky.fragment.ViewMediaFragment import com.keylesspalace.tusky.fragment.ViewMediaFragment
import java.util.* import java.lang.ref.WeakReference
class ImagePagerAdapter( class ImagePagerAdapter(
fragmentManager: FragmentManager, activity: FragmentActivity,
private val attachments: List<Attachment>, private val attachments: List<Attachment>,
private val initialPosition: Int private val initialPosition: Int
) : FragmentStatePagerAdapter(fragmentManager), SharedElementTransitionListener { ) : ViewMediaAdapter(activity) {
private var primaryItem: ViewMediaFragment? = null
private var didTransition = false private var didTransition = false
private val fragments = MutableList<WeakReference<ViewMediaFragment>?>(attachments.size) { null }
override fun setPrimaryItem(container: ViewGroup, position: Int, item: Any) { override fun getItemCount() = attachments.size
super.setPrimaryItem(container, position, item)
this.primaryItem = item as ViewMediaFragment
}
override fun getItem(position: Int): Fragment { override fun createFragment(position: Int): Fragment {
return if (position >= 0 && position < attachments.size) { if (position >= 0 && position < attachments.size) {
// Fragment should not wait for or start transition if it already happened but we // Fragment should not wait for or start transition if it already happened but we
// instantiate the same fragment again, e.g. open the first photo, scroll to the // instantiate the same fragment again, e.g. open the first photo, scroll to the
// forth photo and then back to the first. The first fragment will trz to start the // forth photo and then back to the first. The first fragment will try to start the
// transition and wait until it's over and it will never take place. // transition and wait until it's over and it will never take place.
ViewMediaFragment.newInstance( val fragment = ViewMediaFragment.newInstance(
attachment = attachments[position], attachment = attachments[position],
shouldStartPostponedTransition = !didTransition && position == initialPosition shouldStartPostponedTransition = !didTransition && position == initialPosition
) )
fragments[position] = WeakReference(fragment)
return fragment
} else { } else {
throw IllegalStateException() throw IllegalStateException()
} }
} }
override fun getCount(): Int { override fun onTransitionEnd(position: Int) {
return attachments.size
}
override fun getPageTitle(position: Int): CharSequence {
return String.format(Locale.getDefault(), "%d/%d", position + 1, attachments.size)
}
override fun onTransitionEnd() {
this.didTransition = true this.didTransition = true
primaryItem?.onTransitionEnd() fragments[position]?.get()?.onTransitionEnd()
} }
} }

View File

@ -15,49 +15,23 @@
package com.keylesspalace.tusky.pager package com.keylesspalace.tusky.pager
import android.util.SparseArray
import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentPagerAdapter import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager.widget.PagerAdapter
import com.keylesspalace.tusky.TabData import com.keylesspalace.tusky.TabData
import java.lang.ref.WeakReference
class MainPagerAdapter(val tabs: List<TabData>, manager: FragmentManager) : FragmentPagerAdapter(manager) { class MainPagerAdapter(val tabs: List<TabData>, activity: FragmentActivity) : FragmentStateAdapter(activity) {
private val fragments = SparseArray<Fragment>(tabs.size) private val fragments = MutableList<WeakReference<Fragment>?>(tabs.size) { null }
override fun getItem(position: Int): Fragment { override fun createFragment(position: Int): Fragment {
val tab = tabs[position] val tab = tabs[position]
return tab.fragment(tab.arguments) val fragment = tab.fragment(tab.arguments)
} fragments[position] = WeakReference(fragment)
override fun getCount(): Int {
return tabs.size
}
override fun getPageTitle(position: Int): CharSequence? {
return null
}
override fun getItemId(position: Int): Long {
return tabs[position].hashCode() + position.toLong()
}
override fun getItemPosition(item: Any): Int {
return PagerAdapter.POSITION_NONE
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val fragment = super.instantiateItem(container, position)
if (fragment is Fragment)
fragments.put(position, fragment)
return fragment return fragment
} }
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) { override fun getItemCount() = tabs.size
super.destroyItem(container, position, `object`)
fragments.remove(position)
}
fun getFragment(position: Int): Fragment? = fragments[position] fun getFragment(position: Int): Fragment? = fragments[position]?.get()
} }

View File

@ -1,45 +0,0 @@
/* Copyright 2017 Andrew Dawson
*
* This file is a part of Tusky.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.view;
import android.content.Context;
import androidx.viewpager.widget.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
/**
* This class is entirely to address a known issue with com.github.chrisbanes.photoview.PhotoView.
* ViewPager will throw exceptions when a PhotoView is placed within it, so this subclass eats those
* exceptions.
*/
public class ImageViewPager extends ViewPager {
public ImageViewPager(Context context) {
super(context);
}
public ImageViewPager(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
try {
return super.onInterceptTouchEvent(ev);
} catch (IllegalArgumentException e) {
return false;
}
}
}

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/tab_page_margin_black" />
</shape>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/tab_page_margin_dark" />
</shape>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/tab_page_margin_light" />
</shape>

View File

@ -3,8 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:background="?attr/tab_page_margin_drawable">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="640dp" android:layout_width="640dp"
@ -45,16 +44,17 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/elephant_error" tools:src="@drawable/elephant_error"
tools:visibility="visible" /> tools:visibility="visible" />
<androidx.core.widget.ContentLoadingProgressBar <androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/topProgressBar" android:id="@+id/topProgressBar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
app:layout_constraintTop_toTopOf="parent"
android:indeterminate="true" android:indeterminate="true"
app:layout_constraintStart_toStartOf="parent" android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="parent" app:layout_constraintBottom_toTopOf="parent"
android:visibility="gone"/> app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout> </FrameLayout>

View File

@ -3,8 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:background="?attr/tab_page_margin_drawable">
<androidx.coordinatorlayout.widget.CoordinatorLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="640dp" android:layout_width="640dp"
@ -80,9 +79,7 @@
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:layout_gravity="center"
android:src="@android:color/transparent"
android:visibility="gone" android:visibility="gone"
tools:src="@drawable/elephant_error"
tools:visibility="visible" /> tools:visibility="visible" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
</FrameLayout> </FrameLayout>

View File

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:background="?attr/tab_page_margin_drawable">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout" android:id="@+id/swipeRefreshLayout"

View File

@ -333,10 +333,11 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager <androidx.viewpager2.widget.ViewPager2
android:id="@+id/accountFragmentViewPager" android:id="@+id/accountFragmentViewPager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/tab_page_margin_color"
app:layout_behavior="@string/appbar_scrolling_view_behavior" /> app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton

View File

@ -33,8 +33,9 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager <androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager" android:id="@+id/pager"
android:background="?attr/tab_page_margin_color"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_below="@id/tab_layout" android:layout_below="@id/tab_layout"

View File

@ -32,7 +32,7 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager <androidx.viewpager2.widget.ViewPager2
android:id="@+id/pages" android:id="@+id/pages"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"

View File

@ -6,7 +6,7 @@
android:background="@android:color/black" android:background="@android:color/black"
android:orientation="vertical"> android:orientation="vertical">
<com.keylesspalace.tusky.view.ImageViewPager <androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager" android:id="@+id/viewPager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />

View File

@ -4,20 +4,20 @@
android:id="@+id/layoutRoot" android:id="@+id/layoutRoot"
android:layout_width="@dimen/timeline_width" android:layout_width="@dimen/timeline_width"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/tab_page_margin_drawable"> android:background="?attr/tab_page_margin_color">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout" android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/searchRecyclerView" android:id="@+id/searchRecyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="center" android:layout_gravity="center"
android:background="?attr/window_background" android:background="?attr/window_background"
tools:listitem="@layout/item_account"/> tools:listitem="@layout/item_account" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

View File

@ -3,7 +3,9 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:background="?attr/window_background">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout" android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -29,23 +31,22 @@
android:id="@+id/statusView" android:id="@+id/statusView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:src="@android:color/transparent"
android:visibility="gone" android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/elephant_error" tools:visibility="visible" />
tools:visibility="visible"/>
<androidx.core.widget.ContentLoadingProgressBar <androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/topProgressBar" android:id="@+id/topProgressBar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
app:layout_constraintTop_toTopOf="parent"
android:indeterminate="true" android:indeterminate="true"
app:layout_constraintStart_toStartOf="parent" android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="parent" app:layout_constraintBottom_toTopOf="parent"
android:visibility="gone"/> app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -58,7 +58,8 @@
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView" android:id="@+id/recyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent"
android:background="?attr/window_background" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

View File

@ -9,5 +9,7 @@
android:id="@+id/recyclerView" android:id="@+id/recyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/window_background"
android:scrollbars="vertical" /> android:scrollbars="vertical" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

View File

@ -41,7 +41,7 @@
<item name="android:listDivider">@drawable/status_divider_dark</item> <item name="android:listDivider">@drawable/status_divider_dark</item>
<item name="conversation_thread_line_drawable">@drawable/conversation_thread_line_dark</item> <item name="conversation_thread_line_drawable">@drawable/conversation_thread_line_dark</item>
<item name="tab_icon_selected_tint">@color/tusky_blue</item> <item name="tab_icon_selected_tint">@color/tusky_blue</item>
<item name="tab_page_margin_drawable">@drawable/tab_page_margin_dark</item> <item name="tab_page_margin_color">@color/tab_page_margin_dark</item>
<item name="account_header_background_color">@color/color_background_dark</item> <item name="account_header_background_color">@color/color_background_dark</item>
<item name="account_toolbar_icon_tint_uncollapsed">@color/toolbar_icon_dark</item> <item name="account_toolbar_icon_tint_uncollapsed">@color/toolbar_icon_dark</item>
<item name="account_toolbar_icon_tint_collapsed">@color/account_toolbar_icon_collapsed_dark</item> <item name="account_toolbar_icon_tint_collapsed">@color/account_toolbar_icon_collapsed_dark</item>

View File

@ -25,7 +25,7 @@
<attr name="media_preview_unloaded_drawable" format="reference" /> <attr name="media_preview_unloaded_drawable" format="reference" />
<attr name="conversation_thread_line_drawable" format="reference" /> <attr name="conversation_thread_line_drawable" format="reference" />
<attr name="tab_icon_selected_tint" format="reference|color" /> <attr name="tab_icon_selected_tint" format="reference|color" />
<attr name="tab_page_margin_drawable" format="reference" /> <attr name="tab_page_margin_color" format="reference|color" />
<attr name="account_header_background_color" format="reference|color" /> <attr name="account_header_background_color" format="reference|color" />
<attr name="account_toolbar_icon_tint_uncollapsed" format="reference|color" /> <attr name="account_toolbar_icon_tint_uncollapsed" format="reference|color" />
<attr name="account_toolbar_icon_tint_collapsed" format="reference|color" /> <attr name="account_toolbar_icon_tint_collapsed" format="reference|color" />

View File

@ -96,7 +96,7 @@
<item name="conversation_thread_line_drawable">@drawable/conversation_thread_line_light <item name="conversation_thread_line_drawable">@drawable/conversation_thread_line_light
</item> </item>
<item name="tab_icon_selected_tint">@color/tusky_blue</item> <item name="tab_icon_selected_tint">@color/tusky_blue</item>
<item name="tab_page_margin_drawable">@drawable/tab_page_margin_light</item> <item name="tab_page_margin_color">@color/tab_page_margin_light</item>
<item name="account_header_background_color">@color/color_primary_dark_light</item> <item name="account_header_background_color">@color/color_primary_dark_light</item>
<item name="account_toolbar_icon_tint_uncollapsed">@color/toolbar_icon_dark <item name="account_toolbar_icon_tint_uncollapsed">@color/toolbar_icon_dark
</item> <!--Default to dark on purpose, because header backgrounds with gradients are always dark.--> </item> <!--Default to dark on purpose, because header backgrounds with gradients are always dark.-->
@ -200,7 +200,7 @@
<item name="material_drawer_selected">@color/color_primary_black</item> <item name="material_drawer_selected">@color/color_primary_black</item>
<item name="material_drawer_selected_text">@color/text_color_primary_black</item> <item name="material_drawer_selected_text">@color/text_color_primary_black</item>
<item name="material_drawer_header_selection_text">@color/text_color_primary_black</item> <item name="material_drawer_header_selection_text">@color/text_color_primary_black</item>
<item name="tab_page_margin_drawable">@drawable/tab_page_margin_black</item> <item name="tab_page_margin_color">@color/tab_page_margin_black</item>
</style> </style>
<style name="TuskyBlackTheme" parent="TuskyBlackThemeBase" /> <style name="TuskyBlackTheme" parent="TuskyBlackThemeBase" />