diff options
19 files changed, 349 insertions, 406 deletions
diff --git a/app/src/main/java/app/fedilab/android/BaseMainActivity.java b/app/src/main/java/app/fedilab/android/BaseMainActivity.java index 6fe89afc5..ec0496909 100644 --- a/app/src/main/java/app/fedilab/android/BaseMainActivity.java +++ b/app/src/main/java/app/fedilab/android/BaseMainActivity.java @@ -900,10 +900,12 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt itemFilter.setTitle(show_filtered); } popup.setOnDismissListener(menu1 -> { - Fragment fragment = getSupportFragmentManager().findFragmentByTag("f" + binding.viewPager.getCurrentItem()); - if (fragment instanceof FragmentMastodonTimeline && fragment.isVisible()) { - FragmentMastodonTimeline fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment); - fragmentMastodonTimeline.refreshAllAdapters(); + if (binding.viewPager.getAdapter() != null) { + Fragment fragment = (Fragment) binding.viewPager.getAdapter().instantiateItem(binding.viewPager, binding.tabLayout.getSelectedTabPosition()); + if (fragment instanceof FragmentMastodonTimeline && fragment.isVisible()) { + FragmentMastodonTimeline fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment); + fragmentMastodonTimeline.refreshAllAdapters(); + } } }); String finalShow_filtered = show_filtered; @@ -990,13 +992,15 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt } public void refreshFragment() { - Fragment fragment = getSupportFragmentManager().findFragmentByTag("f" + binding.viewPager.getCurrentItem()); - if (fragment instanceof FragmentNotificationContainer) { - FragmentTransaction fragTransaction = getSupportFragmentManager().beginTransaction(); - fragTransaction.detach(fragment).commit(); - FragmentTransaction fragTransaction2 = getSupportFragmentManager().beginTransaction(); - fragTransaction2.attach(fragment); - fragTransaction2.commit(); + if (binding.viewPager.getAdapter() != null) { + Fragment fragment = (Fragment) binding.viewPager.getAdapter().instantiateItem(binding.viewPager, binding.tabLayout.getSelectedTabPosition()); + if (fragment instanceof FragmentNotificationContainer) { + FragmentTransaction fragTransaction = getSupportFragmentManager().beginTransaction(); + fragTransaction.detach(fragment).commit(); + FragmentTransaction fragTransaction2 = getSupportFragmentManager().beginTransaction(); + fragTransaction2.attach(fragment); + fragTransaction2.commit(); + } } } @@ -1035,16 +1039,18 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt */ private void scrollToTop() { - Fragment fragment = getSupportFragmentManager().findFragmentByTag("f" + binding.viewPager.getCurrentItem()); - if (fragment instanceof FragmentMastodonTimeline) { - FragmentMastodonTimeline fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment); - fragmentMastodonTimeline.scrollToTop(); - } else if (fragment instanceof FragmentMastodonConversation) { - FragmentMastodonConversation fragmentMastodonConversation = ((FragmentMastodonConversation) fragment); - fragmentMastodonConversation.scrollToTop(); - } else if (fragment instanceof FragmentNotificationContainer) { - FragmentNotificationContainer fragmentNotificationContainer = ((FragmentNotificationContainer) fragment); - fragmentNotificationContainer.scrollToTop(); + if (binding.viewPager.getAdapter() != null) { + Fragment fragment = (Fragment) binding.viewPager.getAdapter().instantiateItem(binding.viewPager, binding.tabLayout.getSelectedTabPosition()); + if (fragment instanceof FragmentMastodonTimeline) { + FragmentMastodonTimeline fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment); + fragmentMastodonTimeline.scrollToTop(); + } else if (fragment instanceof FragmentMastodonConversation) { + FragmentMastodonConversation fragmentMastodonConversation = ((FragmentMastodonConversation) fragment); + fragmentMastodonConversation.scrollToTop(); + } else if (fragment instanceof FragmentNotificationContainer) { + FragmentNotificationContainer fragmentNotificationContainer = ((FragmentNotificationContainer) fragment); + fragmentNotificationContainer.scrollToTop(); + } } } diff --git a/app/src/main/java/app/fedilab/android/activities/MediaActivity.java b/app/src/main/java/app/fedilab/android/activities/MediaActivity.java index baeb5a82a..ca275b439 100644 --- a/app/src/main/java/app/fedilab/android/activities/MediaActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/MediaActivity.java @@ -33,15 +33,18 @@ import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; import android.view.Window; import androidx.annotation.NonNull; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentActivity; -import androidx.viewpager2.adapter.FragmentStateAdapter; -import androidx.viewpager2.widget.ViewPager2; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentStatePagerAdapter; +import androidx.viewpager.widget.ViewPager; + +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -94,6 +97,7 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface { private float startX; private float startY; private ActivityMediaPagerBinding binding; + private FragmentMedia mCurrentFragment; @Override protected void onCreate(Bundle savedInstanceState) { @@ -123,7 +127,7 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface { setTitle(""); - ScreenSlidePagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(MediaActivity.this); + ScreenSlidePagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager()); binding.mediaViewpager.setAdapter(mPagerAdapter); binding.mediaViewpager.setSaveEnabled(false); binding.mediaViewpager.setCurrentItem(mediaPosition - 1); @@ -135,15 +139,14 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface { binding.mediaDescription.setText(description); } - binding.mediaViewpager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { - @Override + binding.mediaViewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + public void onPageScrollStateChanged(int state) { + } + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - super.onPageScrolled(position, positionOffset, positionOffsetPixels); } - @Override public void onPageSelected(int position) { - super.onPageSelected(position); String description = attachments.get(position).description; if (handler != null) { handler.removeCallbacksAndMessages(null); @@ -153,13 +156,9 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface { binding.mediaDescription.setText(description); } } - - @Override - public void onPageScrollStateChanged(int state) { - super.onPageScrollStateChanged(state); - } }); + setFullscreen(true); Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); @@ -358,18 +357,22 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface { | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } + public FragmentMedia getCurrentFragment() { + return mCurrentFragment; + } + /** * Media Pager */ - private class ScreenSlidePagerAdapter extends FragmentStateAdapter { - - ScreenSlidePagerAdapter(FragmentActivity fa) { - super(fa); + @SuppressWarnings("deprecation") + private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter { + ScreenSlidePagerAdapter(FragmentManager fm) { + super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); } - @NonNull + @NotNull @Override - public Fragment createFragment(int position) { + public Fragment getItem(int position) { Bundle bundle = new Bundle(); FragmentMedia mediaSliderFragment = new FragmentMedia(); bundle.putInt(Helper.ARG_MEDIA_POSITION, position); @@ -379,7 +382,15 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface { } @Override - public int getItemCount() { + public void setPrimaryItem(@NotNull ViewGroup container, int position, @NotNull Object object) { + if (getCurrentFragment() != object) { + mCurrentFragment = ((FragmentMedia) object); + } + super.setPrimaryItem(container, position, object); + } + + @Override + public int getCount() { return attachments.size(); } } diff --git a/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java b/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java index bcd6bbc6c..1226c83d2 100644 --- a/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java @@ -62,7 +62,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.Glide; import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.transition.Transition; -import com.google.android.material.tabs.TabLayoutMediator; +import com.google.android.material.tabs.TabLayout; import java.util.ArrayList; import java.util.Date; @@ -247,29 +247,27 @@ public class ProfileActivity extends BaseActivity { binding.accountTabLayout.clearOnTabSelectedListeners(); binding.accountTabLayout.removeAllTabs(); //Tablayout for timelines/following/followers - FedilabProfileTLPageAdapter fedilabProfileTLPageAdapter = new FedilabProfileTLPageAdapter(ProfileActivity.this, account); - binding.accountTabLayout.addTab(binding.accountTabLayout.newTab()); - binding.accountTabLayout.addTab(binding.accountTabLayout.newTab()); - binding.accountTabLayout.addTab(binding.accountTabLayout.newTab()); + FedilabProfileTLPageAdapter fedilabProfileTLPageAdapter = new FedilabProfileTLPageAdapter(getSupportFragmentManager(), account); + binding.accountTabLayout.addTab(binding.accountTabLayout.newTab().setText(getString(R.string.status_cnt, Helper.withSuffix(account.statuses_count)))); + binding.accountTabLayout.addTab(binding.accountTabLayout.newTab().setText(getString(R.string.following_cnt, Helper.withSuffix(account.following_count)))); + binding.accountTabLayout.addTab(binding.accountTabLayout.newTab().setText(getString(R.string.followers_cnt, Helper.withSuffix(account.followers_count)))); binding.accountViewpager.setAdapter(fedilabProfileTLPageAdapter); binding.accountViewpager.setOffscreenPageLimit(3); + binding.accountViewpager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(binding.accountTabLayout)); + binding.accountTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { + @Override + public void onTabSelected(TabLayout.Tab tab) { + binding.accountViewpager.setCurrentItem(tab.getPosition()); + } - new TabLayoutMediator(binding.accountTabLayout, binding.accountViewpager, - (tab, position) -> { - binding.accountViewpager.setCurrentItem(tab.getPosition(), true); - switch (position) { - case 0: - tab.setText(getString(R.string.status_cnt, Helper.withSuffix(account.statuses_count))); - break; - case 1: - tab.setText(getString(R.string.following_cnt, Helper.withSuffix(account.following_count))); - break; - case 2: - tab.setText(getString(R.string.followers_cnt, Helper.withSuffix(account.followers_count))); - break; - } - } - ).attach(); + @Override + public void onTabUnselected(TabLayout.Tab tab) { + } + + @Override + public void onTabReselected(TabLayout.Tab tab) { + } + }); binding.accountTabLayout.setTabTextColors(ThemeHelper.getAttColor(ProfileActivity.this, R.attr.mTextColor), ContextCompat.getColor(ProfileActivity.this, R.color.cyanea_accent_dark_reference)); binding.accountTabLayout.setTabIconTint(ThemeHelper.getColorStateList(ProfileActivity.this)); boolean disableGif = sharedpreferences.getBoolean(getString(R.string.SET_DISABLE_GIF), false); diff --git a/app/src/main/java/app/fedilab/android/activities/ScheduledActivity.java b/app/src/main/java/app/fedilab/android/activities/ScheduledActivity.java index da261e988..f01a9e1a5 100644 --- a/app/src/main/java/app/fedilab/android/activities/ScheduledActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/ScheduledActivity.java @@ -24,7 +24,7 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import androidx.core.content.ContextCompat; -import com.google.android.material.tabs.TabLayoutMediator; +import com.google.android.material.tabs.TabLayout; import app.fedilab.android.R; import app.fedilab.android.databinding.ActivityScheduledBinding; @@ -56,31 +56,30 @@ public class ScheduledActivity extends BaseActivity { MastodonHelper.loadPPMastodon(binding.profilePicture, currentAccount.mastodon_account); binding.title.setText(R.string.scheduled); - binding.scheduleTablayout.addTab(binding.scheduleTablayout.newTab()); - binding.scheduleTablayout.addTab(binding.scheduleTablayout.newTab()); - binding.scheduleTablayout.addTab(binding.scheduleTablayout.newTab()); + binding.scheduleTablayout.addTab(binding.scheduleTablayout.newTab().setText(getString(R.string.toots_server))); + binding.scheduleTablayout.addTab(binding.scheduleTablayout.newTab().setText(getString(R.string.toots_client))); + binding.scheduleTablayout.addTab(binding.scheduleTablayout.newTab().setText(getString(R.string.reblog))); - binding.scheduleViewpager.setAdapter(new FedilabScheduledPageAdapter(ScheduledActivity.this)); + binding.scheduleViewpager.setAdapter(new FedilabScheduledPageAdapter(getSupportFragmentManager())); binding.scheduleViewpager.setOffscreenPageLimit(3); + binding.scheduleViewpager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(binding.scheduleTablayout)); binding.scheduleTablayout.setTabTextColors(ThemeHelper.getAttColor(ScheduledActivity.this, R.attr.mTextColor), ContextCompat.getColor(ScheduledActivity.this, R.color.cyanea_accent_dark_reference)); binding.scheduleTablayout.setTabIconTint(ThemeHelper.getColorStateList(ScheduledActivity.this)); - new TabLayoutMediator(binding.scheduleTablayout, binding.scheduleViewpager, - (tab, position) -> { - binding.scheduleViewpager.setCurrentItem(tab.getPosition(), true); - switch (position) { - case 0: - tab.setText(getString(R.string.toots_server)); - break; - case 1: - tab.setText(getString(R.string.toots_client)); - break; - case 2: - tab.setText(getString(R.string.reblog)); - break; - } - } - ).attach(); + binding.scheduleTablayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { + @Override + public void onTabSelected(TabLayout.Tab tab) { + binding.scheduleViewpager.setCurrentItem(tab.getPosition()); + } + + @Override + public void onTabUnselected(TabLayout.Tab tab) { + } + + @Override + public void onTabReselected(TabLayout.Tab tab) { + } + }); } @Override diff --git a/app/src/main/java/app/fedilab/android/activities/SearchResultTabActivity.java b/app/src/main/java/app/fedilab/android/activities/SearchResultTabActivity.java index 04195b35b..7fee806a8 100644 --- a/app/src/main/java/app/fedilab/android/activities/SearchResultTabActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/SearchResultTabActivity.java @@ -21,6 +21,7 @@ import android.os.Bundle; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; +import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.widget.Toast; @@ -28,11 +29,12 @@ import androidx.annotation.NonNull; import androidx.appcompat.widget.SearchView; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentActivity; -import androidx.viewpager2.adapter.FragmentStateAdapter; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentStatePagerAdapter; +import androidx.viewpager.widget.PagerAdapter; +import androidx.viewpager.widget.ViewPager; import com.google.android.material.tabs.TabLayout; -import com.google.android.material.tabs.TabLayoutMediator; import org.jetbrains.annotations.NotNull; @@ -75,35 +77,12 @@ public class SearchResultTabActivity extends BaseActivity { getSupportActionBar().setBackgroundDrawable(new ColorDrawable(ContextCompat.getColor(this, R.color.cyanea_primary))); } setTitle(search); - binding.searchTabLayout.addTab(binding.searchTabLayout.newTab()); - binding.searchTabLayout.addTab(binding.searchTabLayout.newTab()); - binding.searchTabLayout.addTab(binding.searchTabLayout.newTab()); - binding.searchTabLayout.addTab(binding.searchTabLayout.newTab()); + binding.searchTabLayout.addTab(binding.searchTabLayout.newTab().setText(getString(R.string.tags))); + binding.searchTabLayout.addTab(binding.searchTabLayout.newTab().setText(getString(R.string.accounts))); + binding.searchTabLayout.addTab(binding.searchTabLayout.newTab().setText(getString(R.string.toots))); + binding.searchTabLayout.addTab(binding.searchTabLayout.newTab().setText(getString(R.string.action_cache))); binding.searchTabLayout.setTabTextColors(ThemeHelper.getAttColor(SearchResultTabActivity.this, R.attr.mTextColor), ContextCompat.getColor(SearchResultTabActivity.this, R.color.cyanea_accent_dark_reference)); binding.searchTabLayout.setTabIconTint(ThemeHelper.getColorStateList(SearchResultTabActivity.this)); - ScreenSlidePagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(SearchResultTabActivity.this); - binding.searchViewpager.setAdapter(mPagerAdapter); - binding.searchViewpager.setSaveEnabled(false); - binding.searchViewpager.setOffscreenPageLimit(3); - new TabLayoutMediator(binding.searchTabLayout, binding.searchViewpager, - (tab, position) -> { - binding.searchViewpager.setCurrentItem(tab.getPosition(), true); - switch (position) { - case 0: - tab.setText(getString(R.string.tags)); - break; - case 1: - tab.setText(getString(R.string.accounts)); - break; - case 2: - tab.setText(getString(R.string.toots)); - break; - case 3: - tab.setText(getString(R.string.action_cache)); - break; - } - } - ).attach(); binding.searchTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { @@ -112,21 +91,22 @@ public class SearchResultTabActivity extends BaseActivity { @Override public void onTabUnselected(TabLayout.Tab tab) { - } - @Override public void onTabReselected(TabLayout.Tab tab) { - Fragment fragment = getSupportFragmentManager().findFragmentByTag("f" + binding.searchViewpager.getCurrentItem()); - if (fragment instanceof FragmentMastodonAccount) { - FragmentMastodonAccount fragmentMastodonAccount = ((FragmentMastodonAccount) fragment); - fragmentMastodonAccount.scrollToTop(); - } else if (fragment instanceof FragmentMastodonTimeline) { - FragmentMastodonTimeline fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment); - fragmentMastodonTimeline.scrollToTop(); - } else if (fragment instanceof FragmentMastodonTag) { - FragmentMastodonTag fragmentMastodonTag = ((FragmentMastodonTag) fragment); - fragmentMastodonTag.scrollToTop(); + Fragment fragment; + if (binding.searchViewpager.getAdapter() != null) { + fragment = (Fragment) binding.searchViewpager.getAdapter().instantiateItem(binding.searchViewpager, tab.getPosition()); + if (fragment instanceof FragmentMastodonAccount) { + FragmentMastodonAccount fragmentMastodonAccount = ((FragmentMastodonAccount) fragment); + fragmentMastodonAccount.scrollToTop(); + } else if (fragment instanceof FragmentMastodonTimeline) { + FragmentMastodonTimeline fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment); + fragmentMastodonTimeline.scrollToTop(); + } else if (fragment instanceof FragmentMastodonTag) { + FragmentMastodonTag fragmentMastodonTag = ((FragmentMastodonTag) fragment); + fragmentMastodonTag.scrollToTop(); + } } } }); @@ -149,7 +129,7 @@ public class SearchResultTabActivity extends BaseActivity { imm.hideSoftInputFromWindow(binding.searchTabLayout.getWindowToken(), 0); query = query.replaceAll("^#+", ""); search = query.trim(); - ScreenSlidePagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(SearchResultTabActivity.this); + ScreenSlidePagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager()); binding.searchViewpager.setAdapter(mPagerAdapter); searchView.clearFocus(); setTitle(search); @@ -172,7 +152,24 @@ public class SearchResultTabActivity extends BaseActivity { searchView.setIconified(false); }); + PagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager()); + binding.searchViewpager.setAdapter(mPagerAdapter); + binding.searchViewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + } + + @Override + public void onPageSelected(int position) { + TabLayout.Tab tab = binding.searchTabLayout.getTabAt(position); + if (tab != null) + tab.select(); + } + @Override + public void onPageScrollStateChanged(int state) { + } + }); return true; } @@ -193,16 +190,15 @@ public class SearchResultTabActivity extends BaseActivity { /** * Pager adapter for the 4 fragments */ - private class ScreenSlidePagerAdapter extends FragmentStateAdapter { - - ScreenSlidePagerAdapter(FragmentActivity fa) { - super(fa); + @SuppressWarnings("deprecation") + private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter { + ScreenSlidePagerAdapter(FragmentManager fm) { + super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); } - - @NonNull + @NotNull @Override - public Fragment createFragment(int position) { + public Fragment getItem(int position) { Bundle bundle = new Bundle(); switch (position) { case 0: @@ -229,7 +225,11 @@ public class SearchResultTabActivity extends BaseActivity { } @Override - public int getItemCount() { + public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { + } + + @Override + public int getCount() { return 4; } } diff --git a/app/src/main/java/app/fedilab/android/helper/NestedScrollableHost.kt b/app/src/main/java/app/fedilab/android/helper/NestedScrollableHost.kt deleted file mode 100644 index 2f23c9418..000000000 --- a/app/src/main/java/app/fedilab/android/helper/NestedScrollableHost.kt +++ /dev/null @@ -1,113 +0,0 @@ -package app.fedilab.android.helper - -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -import android.content.Context -import android.util.AttributeSet -import android.view.MotionEvent -import android.view.View -import android.view.ViewConfiguration -import android.widget.FrameLayout -import androidx.viewpager2.widget.ViewPager2 -import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL -import kotlin.math.absoluteValue -import kotlin.math.sign - -/** - * Layout to wrap a scrollable component inside a ViewPager2. Provided as a solution to the problem - * where pages of ViewPager2 have nested scrollable elements that scroll in the same direction as - * ViewPager2. The scrollable element needs to be the immediate and only child of this host layout. - * - * This solution has limitations when using multiple levels of nested scrollable elements - * (e.g. a horizontal RecyclerView in a vertical RecyclerView in a horizontal ViewPager2). - */ -class NestedScrollableHost : FrameLayout { - constructor(context: Context) : super(context) - constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) - - private var touchSlop = 0 - private var initialX = 0f - private var initialY = 0f - private val parentViewPager: ViewPager2? - get() { - var v: View? = parent as? View - while (v != null && v !is ViewPager2) { - v = v.parent as? View - } - return v as? ViewPager2 - } - - private val child: View? get() = if (childCount > 0) getChildAt(0) else null - - init { - touchSlop = ViewConfiguration.get(context).scaledTouchSlop - } - - private fun canChildScroll(orientation: Int, delta: Float): Boolean { - val direction = -delta.sign.toInt() - return when (orientation) { - 0 -> child?.canScrollHorizontally(direction) ?: false - 1 -> child?.canScrollVertically(direction) ?: false - else -> throw IllegalArgumentException() - } - } - - override fun onInterceptTouchEvent(e: MotionEvent): Boolean { - handleInterceptTouchEvent(e) - return super.onInterceptTouchEvent(e) - } - - private fun handleInterceptTouchEvent(e: MotionEvent) { - val orientation = parentViewPager?.orientation ?: return - - // Early return if child can't scroll in same direction as parent - if (!canChildScroll(orientation, -1f) && !canChildScroll(orientation, 1f)) { - return - } - - if (e.action == MotionEvent.ACTION_DOWN) { - initialX = e.x - initialY = e.y - parent.requestDisallowInterceptTouchEvent(true) - } else if (e.action == MotionEvent.ACTION_MOVE) { - val dx = e.x - initialX - val dy = e.y - initialY - val isVpHorizontal = orientation == ORIENTATION_HORIZONTAL - - // assuming ViewPager2 touch-slop is 2x touch-slop of child - val scaledDx = dx.absoluteValue * if (isVpHorizontal) .5f else 1f - val scaledDy = dy.absoluteValue * if (isVpHorizontal) 1f else .5f - - if (scaledDx > touchSlop || scaledDy > touchSlop) { - if (isVpHorizontal == (scaledDy > scaledDx)) { - // Gesture is perpendicular, allow all parents to intercept - parent.requestDisallowInterceptTouchEvent(false) - } else { - // Gesture is parallel, query child if movement in that direction is possible - if (canChildScroll(orientation, if (isVpHorizontal) dx else dy)) { - // Child can scroll, disallow all parents to intercept - parent.requestDisallowInterceptTouchEvent(true) - } else { - // Child cannot scroll, allow all parents to intercept - parent.requestDisallowInterceptTouchEvent(false) - } - } - } - } - } -}
\ No newline at end of file diff --git a/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java b/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java index 61586270a..d0b4cd04c 100644 --- a/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java +++ b/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java @@ -26,16 +26,14 @@ import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.LinearLayout; -import android.widget.TextView; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.PopupMenu; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentTransaction; -import androidx.viewpager2.widget.ViewPager2; +import androidx.viewpager.widget.ViewPager; import com.google.android.material.tabs.TabLayout; -import com.google.android.material.tabs.TabLayoutMediator; import java.util.ArrayList; import java.util.Arrays; @@ -149,18 +147,11 @@ public class PinnedTimelineHelper { activityMainBinding.tabLayout.removeAllTabs(); //Small hack to hide first tabs (they represent the item of the bottom menu) int toRemove = itemToRemoveInBottomMenu(activity); - List<String> tabTitle = new ArrayList<>(); - List<RemoteInstance.InstanceType> tabTypeRemote = new ArrayList<>(); - List<Timeline.TimeLineEnum> tabType = new ArrayList<>(); for (int i = 0; i < (BOTTOM_TIMELINE_COUNT - toRemove); i++) { activityMainBinding.tabLayout.addTab(activityMainBinding.tabLayout.newTab()); - tabTitle.add(""); - tabType.add(Timeline.TimeLineEnum.HOME); - tabTypeRemote.add(RemoteInstance.InstanceType.MASTODON); ((ViewGroup) activityMainBinding.tabLayout.getChildAt(0)).getChildAt(i).setVisibility(View.GONE); } List<PinnedTimeline> pinnedTimelineVisibleList = new ArrayList<>(); - for (PinnedTimeline pinnedTimeline : pinned.pinnedTimelines) { if (pinnedTimeline.displayed) { TabLayout.Tab tab = activityMainBinding.tabLayout.newTab(); @@ -176,16 +167,40 @@ public class PinnedTimelineHelper { name = pinnedTimeline.remoteInstance.host; break; } - TextView tv = (TextView) LayoutInflater.from(activity).inflate(R.layout.custom_tab_instance, new LinearLayout(activity), false); - tv.setText(name); - tabTitle.add(name); - tabType.add(pinnedTimeline.type); - if (pinnedTimeline.type == Timeline.TimeLineEnum.REMOTE) { - tabTypeRemote.add(pinnedTimeline.remoteInstance.type); - } else { - tabTypeRemote.add(null); + TabCustomViewBinding tabCustomViewBinding = TabCustomViewBinding.inflate(activity.getLayoutInflater()); + tabCustomViewBinding.title.setText(name); + switch (pinnedTimeline.type) { |