From b1603894cb7e9362968db629afcb31082614ff59 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 25 Jun 2022 19:35:12 +0200 Subject: [PATCH] Fix issue with pagination --- app/src/main/AndroidManifest.xml | 2 + .../app/fedilab/android/BaseMainActivity.java | 10 +- .../android/activities/ProfileActivity.java | 47 ++++---- .../android/activities/ScheduledActivity.java | 40 +++---- .../activities/SearchResultTabActivity.java | 80 ++++++------- .../android/helper/NestedScrollableHost.kt | 113 ++++++++++++++++++ .../android/helper/PinnedTimelineHelper.java | 56 ++++----- .../helper/ZoomOutPageTransformer.java | 44 +++++++ .../fragment/admin/FragmentAdminAccount.java | 2 +- .../fragment/admin/FragmentAdminReport.java | 4 +- .../timeline/FragmentMastodonAccount.java | 4 +- .../timeline/FragmentMastodonContext.java | 3 + .../FragmentMastodonNotification.java | 20 ++-- .../timeline/FragmentMastodonTag.java | 3 + .../timeline/FragmentMastodonTimeline.java | 4 +- .../FragmentNotificationContainer.java | 80 +++++++++---- app/src/main/res/layout/activity_profile.xml | 20 ++-- .../layout/activity_search_result_tabs.xml | 14 ++- 18 files changed, 370 insertions(+), 176 deletions(-) create mode 100644 app/src/main/java/app/fedilab/android/helper/NestedScrollableHost.kt create mode 100644 app/src/main/java/app/fedilab/android/helper/ZoomOutPageTransformer.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b79bd1f0..b736d8d6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -18,12 +18,14 @@ android:icon="@mipmap/ic_launcher" android:usesCleartextTraffic="true" android:label="@string/app_name" + android:configChanges="orientation|screenSize" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppThemeDark" > diff --git a/app/src/main/java/app/fedilab/android/BaseMainActivity.java b/app/src/main/java/app/fedilab/android/BaseMainActivity.java index 80abbd81..08b715c7 100644 --- a/app/src/main/java/app/fedilab/android/BaseMainActivity.java +++ b/app/src/main/java/app/fedilab/android/BaseMainActivity.java @@ -55,6 +55,7 @@ import androidx.core.app.ActivityOptionsCompat; import androidx.core.content.ContextCompat; import androidx.core.view.GravityCompat; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentTransaction; import androidx.lifecycle.ViewModelProvider; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.navigation.NavController; @@ -838,8 +839,13 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt } public void refreshFragment() { - if (binding.viewPager.getAdapter() != null) { - binding.viewPager.getAdapter().notifyDataSetChanged(); + 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(); } } 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 3cb3ac0a..616fb732 100644 --- a/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java @@ -59,12 +59,11 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.preference.PreferenceManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import androidx.viewpager2.widget.ViewPager2; 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.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; import java.util.ArrayList; import java.util.Date; @@ -249,34 +248,28 @@ public class ProfileActivity extends BaseActivity { binding.accountTabLayout.removeAllTabs(); //Tablayout for timelines/following/followers FedilabProfileTLPageAdapter fedilabProfileTLPageAdapter = new FedilabProfileTLPageAdapter(ProfileActivity.this, 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.accountTabLayout.addTab(binding.accountTabLayout.newTab()); + binding.accountTabLayout.addTab(binding.accountTabLayout.newTab()); + binding.accountTabLayout.addTab(binding.accountTabLayout.newTab()); binding.accountViewpager.setAdapter(fedilabProfileTLPageAdapter); binding.accountViewpager.setOffscreenPageLimit(3); - binding.accountViewpager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { - @Override - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - super.onPageScrolled(position, positionOffset, positionOffsetPixels); - binding.accountTabLayout.selectTab(binding.accountTabLayout.getTabAt(position)); - } - }); - binding.accountTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { - @Override - public void onTabSelected(TabLayout.Tab tab) { - binding.accountViewpager.setCurrentItem(tab.getPosition()); - } - @Override - public void onTabUnselected(TabLayout.Tab tab) { - - } - - @Override - public void onTabReselected(TabLayout.Tab tab) { - - } - }); + 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.statuses_count))); + break; + case 2: + tab.setText(getString(R.string.followers_cnt, Helper.withSuffix(account.statuses_count))); + break; + } + } + ).attach(); 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 4ea741e5..da261e98 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.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; import app.fedilab.android.R; import app.fedilab.android.databinding.ActivityScheduledBinding; @@ -56,31 +56,31 @@ public class ScheduledActivity extends BaseActivity { MastodonHelper.loadPPMastodon(binding.profilePicture, currentAccount.mastodon_account); binding.title.setText(R.string.scheduled); - 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.scheduleTablayout.addTab(binding.scheduleTablayout.newTab()); + binding.scheduleTablayout.addTab(binding.scheduleTablayout.newTab()); + binding.scheduleTablayout.addTab(binding.scheduleTablayout.newTab()); binding.scheduleViewpager.setAdapter(new FedilabScheduledPageAdapter(ScheduledActivity.this)); binding.scheduleViewpager.setOffscreenPageLimit(3); 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)); - 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) { - - } - }); + 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(); } @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 c09fac97..b7814e67 100644 --- a/app/src/main/java/app/fedilab/android/activities/SearchResultTabActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/SearchResultTabActivity.java @@ -30,9 +30,9 @@ 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 com.google.android.material.tabs.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; import org.jetbrains.annotations.NotNull; @@ -75,13 +75,34 @@ public class SearchResultTabActivity extends BaseActivity { getSupportActionBar().setBackgroundDrawable(new ColorDrawable(ContextCompat.getColor(this, R.color.cyanea_primary))); } setTitle(search); - 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.addTab(binding.searchTabLayout.newTab()); + binding.searchTabLayout.addTab(binding.searchTabLayout.newTab()); + binding.searchTabLayout.addTab(binding.searchTabLayout.newTab()); + binding.searchTabLayout.addTab(binding.searchTabLayout.newTab()); 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.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) { @@ -95,19 +116,16 @@ public class SearchResultTabActivity extends BaseActivity { @Override public void onTabReselected(TabLayout.Tab tab) { - Fragment fragment; - if (binding.searchViewpager.getAdapter() != null) { - 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 = 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(); } } }); @@ -122,8 +140,6 @@ public class SearchResultTabActivity extends BaseActivity { SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView(); searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); searchView.setIconifiedByDefault(false); - - searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { @@ -156,29 +172,7 @@ public class SearchResultTabActivity extends BaseActivity { }); - ScreenSlidePagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(SearchResultTabActivity.this); - binding.searchViewpager.setAdapter(mPagerAdapter); - binding.searchViewpager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { - @Override - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - super.onPageScrolled(position, positionOffset, positionOffsetPixels); - binding.searchTabLayout.selectTab(binding.searchTabLayout.getTabAt(position)); - } - - @Override - public void onPageSelected(int position) { - super.onPageSelected(position); - TabLayout.Tab tab = binding.searchTabLayout.getTabAt(position); - if (tab != null) - tab.select(); - } - - @Override - public void onPageScrollStateChanged(int state) { - super.onPageScrollStateChanged(state); - } - }); return true; } diff --git a/app/src/main/java/app/fedilab/android/helper/NestedScrollableHost.kt b/app/src/main/java/app/fedilab/android/helper/NestedScrollableHost.kt new file mode 100644 index 00000000..2f23c941 --- /dev/null +++ b/app/src/main/java/app/fedilab/android/helper/NestedScrollableHost.kt @@ -0,0 +1,113 @@ +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 514a5f3b..fb5769b1 100644 --- a/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java +++ b/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java @@ -35,6 +35,7 @@ import androidx.fragment.app.FragmentTransaction; import androidx.viewpager2.widget.ViewPager2; import com.google.android.material.tabs.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; import java.util.ArrayList; import java.util.Arrays; @@ -147,11 +148,14 @@ 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 tabTitle = new ArrayList<>(); for (int i = 0; i < (BOTTOM_TIMELINE_COUNT - toRemove); i++) { activityMainBinding.tabLayout.addTab(activityMainBinding.tabLayout.newTab()); + tabTitle.add(""); ((ViewGroup) activityMainBinding.tabLayout.getChildAt(0)).getChildAt(i).setVisibility(View.GONE); } List pinnedTimelineVisibleList = new ArrayList<>(); + for (PinnedTimeline pinnedTimeline : pinned.pinnedTimelines) { if (pinnedTimeline.displayed) { TabLayout.Tab tab = activityMainBinding.tabLayout.newTab(); @@ -172,7 +176,7 @@ public class PinnedTimelineHelper { } TextView tv = (TextView) LayoutInflater.from(activity).inflate(R.layout.custom_tab_instance, new LinearLayout(activity), false); tv.setText(name); - + tabTitle.add(name); tab.setCustomView(tv); activityMainBinding.tabLayout.addTab(tab); @@ -205,16 +209,10 @@ public class PinnedTimelineHelper { FedilabPageAdapter fedilabPageAdapter = new FedilabPageAdapter(activity, activity, pinned, bottomMenu); activityMainBinding.viewPager.setAdapter(fedilabPageAdapter); + activityMainBinding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { - @Override - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - super.onPageScrolled(position, positionOffset, positionOffsetPixels); - activityMainBinding.tabLayout.selectTab(activityMainBinding.tabLayout.getTabAt(position)); - } - @Override public void onPageSelected(int position) { - super.onPageSelected(position); if (position < BOTTOM_TIMELINE_COUNT - toRemove) { activityMainBinding.bottomNavView.getMenu().getItem(position).setChecked(true); } else { @@ -225,18 +223,14 @@ public class PinnedTimelineHelper { activityMainBinding.bottomNavView.getMenu().setGroupCheckable(0, true, true); } } - - @Override - public void onPageScrollStateChanged(int state) { - super.onPageScrollStateChanged(state); - } }); - + new TabLayoutMediator(activityMainBinding.tabLayout, activityMainBinding.viewPager, + (tab, position) -> tab.setText(tabTitle.get(position)) + ).attach(); activityMainBinding.tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { - activityMainBinding.viewPager.setCurrentItem(tab.getPosition()); } @Override @@ -245,7 +239,7 @@ public class PinnedTimelineHelper { @Override public void onTabReselected(TabLayout.Tab tab) { - Fragment fragment = (Fragment) activity.getSupportFragmentManager().findFragmentByTag("f" + activityMainBinding.viewPager.getCurrentItem()); + Fragment fragment = activity.getSupportFragmentManager().findFragmentByTag("f" + activityMainBinding.viewPager.getCurrentItem()); if (fragment instanceof FragmentMastodonTimeline) { ((FragmentMastodonTimeline) fragment).scrollToTop(); } else if (fragment instanceof FragmentMastodonConversation) { @@ -319,7 +313,7 @@ public class PinnedTimelineHelper { if (changes[0]) { FragmentMastodonTimeline fragmentMastodonTimeline; if (activityMainBinding.viewPager.getAdapter() != null) { - Fragment fragment = (Fragment) activity.getSupportFragmentManager().findFragmentByTag("f" + activityMainBinding.viewPager.getCurrentItem()); + Fragment fragment = activity.getSupportFragmentManager().findFragmentByTag("f" + activityMainBinding.viewPager.getCurrentItem()); if (fragment instanceof FragmentMastodonTimeline && fragment.isVisible()) { fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment); FragmentTransaction fragTransaction = activity.getSupportFragmentManager().beginTransaction(); @@ -376,7 +370,7 @@ public class PinnedTimelineHelper { } } else if (itemId == R.id.action_any) { AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(activity, Helper.dialogStyle()); - LayoutInflater inflater = ((BaseMainActivity) activity).getLayoutInflater(); + LayoutInflater inflater = activity.getLayoutInflater(); View dialogView = inflater.inflate(R.layout.tags_any, new LinearLayout(activity), false); dialogBuilder.setView(dialogView); final EditText editText = dialogView.findViewById(R.id.filter_any); @@ -405,7 +399,7 @@ public class PinnedTimelineHelper { View dialogView; AlertDialog alertDialog; dialogBuilder = new AlertDialog.Builder(activity, Helper.dialogStyle()); - inflater = ((BaseMainActivity) activity).getLayoutInflater(); + inflater = activity.getLayoutInflater(); dialogView = inflater.inflate(R.layout.tags_all, new LinearLayout(activity), false); dialogBuilder.setView(dialogView); final EditText editTextAll = dialogView.findViewById(R.id.filter_all); @@ -434,7 +428,7 @@ public class PinnedTimelineHelper { View dialogView; AlertDialog alertDialog; dialogBuilder = new AlertDialog.Builder(activity, Helper.dialogStyle()); - inflater = ((BaseMainActivity) activity).getLayoutInflater(); + inflater = activity.getLayoutInflater(); dialogView = inflater.inflate(R.layout.tags_all, new LinearLayout(activity), false); dialogBuilder.setView(dialogView); final EditText editTextNone = dialogView.findViewById(R.id.filter_all); @@ -463,7 +457,7 @@ public class PinnedTimelineHelper { View dialogView; AlertDialog alertDialog; dialogBuilder = new AlertDialog.Builder(activity, Helper.dialogStyle()); - inflater = ((BaseMainActivity) activity).getLayoutInflater(); + inflater = activity.getLayoutInflater(); dialogView = inflater.inflate(R.layout.tags_name, new LinearLayout(activity), false); dialogBuilder.setView(dialogView); final EditText editTextName = dialogView.findViewById(R.id.column_name); @@ -536,14 +530,14 @@ public class PinnedTimelineHelper { changes[0] = true; FragmentMastodonTimeline fragmentMastodonTimeline = null; if (activityMainBinding.viewPager.getAdapter() != null) { - Fragment fragment = (Fragment) activity.getSupportFragmentManager().findFragmentByTag("f" + activityMainBinding.viewPager.getCurrentItem()); + Fragment fragment = activity.getSupportFragmentManager().findFragmentByTag("f" + activityMainBinding.viewPager.getCurrentItem()); if (fragment instanceof FragmentMastodonTimeline && fragment.isVisible()) { fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment); } } if (fragmentMastodonTimeline == null) return false; - FragmentTransaction fragTransaction1 = ((BaseMainActivity) activity).getSupportFragmentManager().beginTransaction(); + FragmentTransaction fragTransaction1 = activity.getSupportFragmentManager().beginTransaction(); pinned.pinnedTimelines.get(offSetPosition).remoteInstance.filteredWith = null; remoteInstance.filteredWith = null; @@ -561,7 +555,7 @@ public class PinnedTimelineHelper { bundle.putString("timelineId", remoteInstance.id); bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.REMOTE); fragmentMastodonTimeline.setArguments(bundle); - FragmentTransaction fragTransaction2 = ((BaseMainActivity) activity).getSupportFragmentManager().beginTransaction(); + FragmentTransaction fragTransaction2 = activity.getSupportFragmentManager().beginTransaction(); fragTransaction2.attach(fragmentMastodonTimeline); fragTransaction2.commit(); popup.getMenu().close(); @@ -583,13 +577,13 @@ public class PinnedTimelineHelper { item.setOnMenuItemClickListener(item1 -> { FragmentMastodonTimeline fragmentMastodonTimeline = null; if (activityMainBinding.viewPager.getAdapter() != null) { - Fragment fragment = (Fragment) activity.getSupportFragmentManager().findFragmentByTag("f" + activityMainBinding.viewPager.getCurrentItem()); + Fragment fragment = activity.getSupportFragmentManager().findFragmentByTag("f" + activityMainBinding.viewPager.getCurrentItem()); if (fragment instanceof FragmentMastodonTimeline && fragment.isVisible()) { fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment); fragmentMastodonTimeline.refreshAllAdapters(); } } - FragmentTransaction fragTransaction1 = ((BaseMainActivity) activity).getSupportFragmentManager().beginTransaction(); + FragmentTransaction fragTransaction1 = activity.getSupportFragmentManager().beginTransaction(); if (fragmentMastodonTimeline == null) return false; pinned.pinnedTimelines.get(offSetPosition).remoteInstance.filteredWith = tag; @@ -608,7 +602,7 @@ public class PinnedTimelineHelper { bundle.putString("currentfilter", remoteInstance.filteredWith); bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.REMOTE); fragmentMastodonTimeline.setArguments(bundle); - FragmentTransaction fragTransaction2 = ((BaseMainActivity) activity).getSupportFragmentManager().beginTransaction(); + FragmentTransaction fragTransaction2 = activity.getSupportFragmentManager().beginTransaction(); fragTransaction2.attach(fragmentMastodonTimeline); fragTransaction2.commit(); return false; @@ -634,7 +628,7 @@ public class PinnedTimelineHelper { }); changes[0] = true; AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(activity, Helper.dialogStyle()); - LayoutInflater inflater = ((BaseMainActivity) activity).getLayoutInflater(); + LayoutInflater inflater = activity.getLayoutInflater(); View dialogView = inflater.inflate(R.layout.tags_instance, new LinearLayout(activity), false); dialogBuilder.setView(dialogView); final EditText editText = dialogView.findViewById(R.id.filter_words); @@ -666,13 +660,13 @@ public class PinnedTimelineHelper { if (changes[0]) { FragmentMastodonTimeline fragmentMastodonTimeline = null; if (activityMainBinding.viewPager.getAdapter() != null) { - Fragment fragment = (Fragment) activity.getSupportFragmentManager().findFragmentByTag("f" + activityMainBinding.viewPager.getCurrentItem()); + Fragment fragment = activity.getSupportFragmentManager().findFragmentByTag("f" + activityMainBinding.viewPager.getCurrentItem()); if (fragment instanceof FragmentMastodonTimeline && fragment.isVisible()) { fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment); fragmentMastodonTimeline.refreshAllAdapters(); } } - FragmentTransaction fragTransaction1 = ((BaseMainActivity) activity).getSupportFragmentManager().beginTransaction(); + FragmentTransaction fragTransaction1 = activity.getSupportFragmentManager().beginTransaction(); if (fragmentMastodonTimeline == null) return; fragTransaction1.detach(fragmentMastodonTimeline).commit(); @@ -685,7 +679,7 @@ public class PinnedTimelineHelper { } bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.REMOTE); fragmentMastodonTimeline.setArguments(bundle); - FragmentTransaction fragTransaction2 = ((BaseMainActivity) activity).getSupportFragmentManager().beginTransaction(); + FragmentTransaction fragTransaction2 = activity.getSupportFragmentManager().beginTransaction(); fragTransaction2.attach(fragmentMastodonTimeline); fragTransaction2.commit(); } diff --git a/app/src/main/java/app/fedilab/android/helper/ZoomOutPageTransformer.java b/app/src/main/java/app/fedilab/android/helper/ZoomOutPageTransformer.java new file mode 100644 index 00000000..b61b6cc9 --- /dev/null +++ b/app/src/main/java/app/fedilab/android/helper/ZoomOutPageTransformer.java @@ -0,0 +1,44 @@ +package app.fedilab.android.helper; + +import android.view.View; + +import androidx.viewpager2.widget.ViewPager2; + +public class ZoomOutPageTransformer implements ViewPager2.PageTransformer { + private static final float MIN_SCALE = 0.85f; + private static final float MIN_ALPHA = 0.5f; + + public void transformPage(View view, float position) { + int pageWidth = view.getWidth(); + int pageHeight = view.getHeight(); + + if (position < -1) { // [-Infinity,-1) + // This page is way off-screen to the left. + view.setAlpha(0f); + + } else if (position <= 1) { // [-1,1] + // Modify the default slide transition to shrink the page as well + float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position)); + float vertMargin = pageHeight * (1 - scaleFactor) / 2; + float horzMargin = pageWidth * (1 - scaleFactor) / 2; + if (position < 0) { + view.setTranslationX(horzMargin - vertMargin / 2); + } else { + view.setTranslationX(-horzMargin + vertMargin / 2); + } + + // Scale the page down (between MIN_SCALE and 1) + view.setScaleX(scaleFactor); + view.setScaleY(scaleFactor); + + // Fade the page relative to its size. + view.setAlpha(MIN_ALPHA + + (scaleFactor - MIN_SCALE) / + (1 - MIN_SCALE) * (1 - MIN_ALPHA)); + + } else { // (1,+Infinity] + // This page is way off-screen to the right. + view.setAlpha(0f); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/admin/FragmentAdminAccount.java b/app/src/main/java/app/fedilab/android/ui/fragment/admin/FragmentAdminAccount.java index 3de6cca9..756b1c12 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/admin/FragmentAdminAccount.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/admin/FragmentAdminAccount.java @@ -177,7 +177,7 @@ public class FragmentAdminAccount extends Fragment { * @param adminAccounts AdminAccounts */ private void dealWithPagination(AdminAccounts adminAccounts) { - if (binding == null) { + if (binding == null || !isAdded() || getActivity() == null) { return; } binding.loadingNextElements.setVisibility(View.GONE); diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/admin/FragmentAdminReport.java b/app/src/main/java/app/fedilab/android/ui/fragment/admin/FragmentAdminReport.java index 35f1ebe1..26e77f0d 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/admin/FragmentAdminReport.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/admin/FragmentAdminReport.java @@ -98,7 +98,7 @@ public class FragmentAdminReport extends Fragment { * @param adminReports {@link AdminReports} */ private void initializeStatusesCommonView(final AdminReports adminReports) { - if (binding == null) { + if (binding == null || !isAdded() || getActivity() == null) { return; } binding.loader.setVisibility(View.GONE); @@ -180,7 +180,7 @@ public class FragmentAdminReport extends Fragment { */ private void dealWithPagination(AdminReports admReports) { - if (binding == null) { + if (binding == null || !isAdded() || getActivity() == null) { return; } binding.loadingNextElements.setVisibility(View.GONE); diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonAccount.java b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonAccount.java index 8c8252d2..8b8c3444 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonAccount.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonAccount.java @@ -172,7 +172,7 @@ public class FragmentMastodonAccount extends Fragment { */ private void initializeAccountCommonView(final Accounts accounts) { flagLoading = false; - if (binding == null) { + if (binding == null || !isAdded() || getActivity() == null) { return; } binding.loader.setVisibility(View.GONE); @@ -242,7 +242,7 @@ public class FragmentMastodonAccount extends Fragment { */ private void dealWithPagination(Accounts fetched_accounts) { flagLoading = false; - if (binding == null) { + if (binding == null || !isAdded() || getActivity() == null) { return; } binding.loadingNextElements.setVisibility(View.GONE); diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonContext.java b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonContext.java index bbeaa3e9..7d544ce1 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonContext.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonContext.java @@ -227,6 +227,9 @@ public class FragmentMastodonContext extends Fragment { Helper.sendToastMessage(requireActivity(), Helper.RECEIVE_TOAST_TYPE_ERROR, getString(R.string.toast_error)); return; } + if (binding == null || !isAdded() || getActivity() == null) { + return; + } if (pullToRefresh) { pullToRefresh = false; int size = this.statuses.size(); diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonNotification.java b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonNotification.java index e2bb8bb6..c7313f55 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonNotification.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonNotification.java @@ -192,7 +192,7 @@ public class FragmentMastodonNotification extends Fragment implements Notificati */ private void initializeNotificationView(final Notifications notifications) { flagLoading = false; - if (binding == null) { + if (binding == null || !isAdded() || getActivity() == null) { return; } binding.loader.setVisibility(View.GONE); @@ -283,10 +283,10 @@ public class FragmentMastodonNotification extends Fragment implements Notificati * @param direction - DIRECTION null if first call, then is set to TOP or BOTTOM depending of scroll */ private void route(FragmentMastodonTimeline.DIRECTION direction, boolean fetchingMissing) { + if (binding == null || !isAdded() || getActivity() == null) { + return; + } new Thread(() -> { - if (binding == null) { - return; - } QuickLoad quickLoad = new QuickLoad(requireActivity()).getSavedValue(MainActivity.currentUserID, MainActivity.currentInstance, notificationType); if (direction != FragmentMastodonTimeline.DIRECTION.REFRESH && !fetchingMissing && !binding.swipeContainer.isRefreshing() && direction == null && quickLoad != null && quickLoad.notifications != null && quickLoad.notifications.size() > 0) { Notifications notifications = new Notifications(); @@ -365,10 +365,9 @@ public class FragmentMastodonNotification extends Fragment implements Notificati * @param fetched_notifications Notifications */ private synchronized void dealWithPagination(Notifications fetched_notifications, FragmentMastodonTimeline.DIRECTION direction, boolean fetchingMissing) { - if (binding == null) { + if (binding == null || !isAdded() || getActivity() == null) { return; } - int currentPosition = mLayoutManager.findFirstVisibleItemPosition(); binding.swipeContainer.setRefreshing(false); binding.loadingNextElements.setVisibility(View.GONE); flagLoading = false; @@ -376,10 +375,7 @@ public class FragmentMastodonNotification extends Fragment implements Notificati flagLoading = fetched_notifications.pagination.max_id == null; binding.noAction.setVisibility(View.GONE); //Update the timeline with new statuses - int inserted = updateNotificationListWith(direction, fetched_notifications.notifications, fetchingMissing); - if (fetchingMissing) { - // binding.recyclerView.scrollToPosition(currentPosition + inserted); - } + updateNotificationListWith(direction, fetched_notifications.notifications, fetchingMissing); if (!fetchingMissing) { if (fetched_notifications.pagination.max_id == null) { flagLoading = true; @@ -400,9 +396,8 @@ public class FragmentMastodonNotification extends Fragment implements Notificati * * @param notificationsReceived - List Notifications received * @param fetchingMissing - boolean if the call concerns fetching messages (ie: refresh of from fetch more button) - * @return int - Number of messages that have been inserted in the middle of the timeline (ie between other statuses) */ - private int updateNotificationListWith(FragmentMastodonTimeline.DIRECTION direction, List notificationsReceived, boolean fetchingMissing) { + private void updateNotificationListWith(FragmentMastodonTimeline.DIRECTION direction, List notificationsReceived, boolean fetchingMissing) { int numberInserted = 0; int lastInsertedPosition = 0; int initialInsertedPosition = NOTIFICATION_PRESENT; @@ -438,7 +433,6 @@ public class FragmentMastodonNotification extends Fragment implements Notificati notificationAdapter.notifyItemInserted(insertAt); } } - return numberInserted; } /** diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTag.java b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTag.java index 0274ea8d..eca47184 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTag.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTag.java @@ -95,6 +95,9 @@ public class FragmentMastodonTag extends Fragment { * @param tags List of {@link Tag} */ private void initializeTagCommonView(final List tags) { + if (binding == null || !isAdded() || getActivity() == null) { + return; + } binding.loader.setVisibility(View.GONE); binding.noAction.setVisibility(View.GONE); binding.swipeContainer.setRefreshing(false); diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java index 9c652458..7eeeb17a 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java @@ -260,7 +260,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. */ private void initializeStatusesCommonView(final Statuses statuses, int position) { flagLoading = false; - if (binding == null) { + if (binding == null || !isAdded() || getActivity() == null) { return; } binding.loader.setVisibility(View.GONE); @@ -376,7 +376,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. * @param fetched_statuses Statuses */ private synchronized void dealWithPagination(Statuses fetched_statuses, DIRECTION direction, boolean fetchingMissing) { - if (binding == null) { + if (binding == null || !isAdded() || getActivity() == null) { return; } binding.swipeContainer.setRefreshing(false); diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentNotificationContainer.java b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentNotificationContainer.java index 8b0ec8a6..b02a6048 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentNotificationContainer.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentNotificationContainer.java @@ -33,6 +33,7 @@ import androidx.preference.PreferenceManager; import com.google.android.material.button.MaterialButton; import com.google.android.material.tabs.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; import java.util.ArrayList; import java.util.List; @@ -60,19 +61,19 @@ public class FragmentNotificationContainer extends Fragment { SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity()); boolean display_all_notification = sharedpreferences.getBoolean(getString(R.string.SET_DISPLAY_ALL_NOTIFICATIONS_TYPE) + BaseMainActivity.currentUserID + BaseMainActivity.currentInstance, false); if (!display_all_notification) { - binding.tabLayout.addTab(binding.tabLayout.newTab().setText(getString(R.string.all))); - binding.tabLayout.addTab(binding.tabLayout.newTab().setText(getString(R.string.mention))); + binding.tabLayout.addTab(binding.tabLayout.newTab()); + binding.tabLayout.addTab(binding.tabLayout.newTab()); binding.tabLayout.setTabMode(TabLayout.MODE_FIXED); binding.viewpager.setAdapter(new FedilabNotificationPageAdapter(requireActivity(), false)); } else { binding.tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE); - binding.tabLayout.addTab(binding.tabLayout.newTab().setText(getString(R.string.all))); - binding.tabLayout.addTab(binding.tabLayout.newTab().setIcon(R.drawable.ic_baseline_reply_24)); - binding.tabLayout.addTab(binding.tabLayout.newTab().setIcon(R.drawable.ic_baseline_star_24)); - binding.tabLayout.addTab(binding.tabLayout.newTab().setIcon(R.drawable.ic_repeat)); - binding.tabLayout.addTab(binding.tabLayout.newTab().setIcon(R.drawable.ic_baseline_poll_24)); - binding.tabLayout.addTab(binding.tabLayout.newTab().setIcon(R.drawable.ic_baseline_home_24)); - binding.tabLayout.addTab(binding.tabLayout.newTab().setIcon(R.drawable.ic_baseline_person_add_alt_1_24)); + binding.tabLayout.addTab(binding.tabLayout.newTab()); + binding.tabLayout.addTab(binding.tabLayout.newTab()); + binding.tabLayout.addTab(binding.tabLayout.newTab()); + binding.tabLayout.addTab(binding.tabLayout.newTab()); + binding.tabLayout.addTab(binding.tabLayout.newTab()); + binding.tabLayout.addTab(binding.tabLayout.newTab()); + binding.tabLayout.addTab(binding.tabLayout.newTab()); binding.viewpager.setAdapter(new FedilabNotificationPageAdapter(requireActivity(), true)); } AtomicBoolean changes = new AtomicBoolean(false); @@ -187,7 +188,6 @@ public class FragmentNotificationContainer extends Fragment { } }); dialogBuilder.setPositiveButton(R.string.close, (dialog, id) -> { - if (changes.get()) { SharedPreferences.Editor editor = sharedpreferences.edit(); if (excludedCategoriesList.size() > 0) { @@ -202,7 +202,6 @@ public class FragmentNotificationContainer extends Fragment { } else { editor.putString(getString(R.string.SET_EXCLUDED_NOTIFICATIONS_TYPE) + BaseMainActivity.currentUserID + BaseMainActivity.currentInstance, null); } - editor.commit(); ((BaseMainActivity) requireActivity()).refreshFragment(); } @@ -214,6 +213,47 @@ public class FragmentNotificationContainer extends Fragment { binding.tabLayout.setTabTextColors(ThemeHelper.getAttColor(requireActivity(), R.attr.mTextColor), ContextCompat.getColor(requireActivity(), R.color.cyanea_accent_dark_reference)); binding.tabLayout.setTabIconTint(ThemeHelper.getColorStateList(requireActivity())); + + new TabLayoutMediator(binding.tabLayout, binding.viewpager, + (tab, position) -> { + binding.viewpager.setCurrentItem(tab.getPosition(), true); + if (!display_all_notification) { + switch (position) { + case 0: + tab.setText(getString(R.string.all)); + break; + case 1: + tab.setText(getString(R.string.mention)); + break; + } + } else { + switch (position) { + case 0: + tab.setText(getString(R.string.all)); + break; + case 1: + tab.setIcon(R.drawable.ic_baseline_reply_24); + break; + case 2: + tab.setIcon(R.drawable.ic_baseline_star_24); + break; + case 3: + tab.setIcon(R.drawable.ic_repeat); + break; + case 4: + tab.setIcon(R.drawable.ic_baseline_poll_24); + break; + case 5: + tab.setIcon(R.drawable.ic_baseline_home_24); + break; + case 6: + tab.setIcon(R.drawable.ic_baseline_person_add_alt_1_24); + break; + } + } + + } + ).attach(); binding.tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { @@ -227,15 +267,11 @@ public class FragmentNotificationContainer extends Fragment { @Override public void onTabReselected(TabLayout.Tab tab) { - Fragment fragment; - if (binding.viewpager.getAdapter() != null) { - fragment = (Fragment) requireActivity().getSupportFragmentManager().findFragmentByTag("f" + binding.viewpager.getCurrentItem()); - if (fragment instanceof FragmentMastodonNotification) { - FragmentMastodonNotification fragmentMastodonNotification = ((FragmentMastodonNotification) fragment); - fragmentMastodonNotification.scrollToTop(); - } + Fragment fragment = requireActivity().getSupportFragmentManager().findFragmentByTag("f" + binding.viewpager.getCurrentItem()); + if (fragment instanceof FragmentMastodonNotification) { + FragmentMastodonNotification fragmentMastodonNotification = ((FragmentMastodonNotification) fragment); + fragmentMastodonNotification.scrollToTop(); } - } }); return binding.getRoot(); @@ -244,9 +280,9 @@ public class FragmentNotificationContainer extends Fragment { public void scrollToTop() { if (binding != null) { - FragmentMastodonNotification fragmentMastodonNotification = (FragmentMastodonNotification) requireActivity().getSupportFragmentManager().findFragmentByTag("f" + binding.viewpager.getCurrentItem()); - if (fragmentMastodonNotification != null) { - fragmentMastodonNotification.scrollToTop(); + Fragment fragment = requireActivity().getSupportFragmentManager().findFragmentByTag("f" + binding.viewpager.getCurrentItem()); + if (fragment instanceof FragmentMastodonNotification) { + ((FragmentMastodonNotification) fragment).scrollToTop(); } } } diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml index 2af54f02..d1ff16c4 100644 --- a/app/src/main/res/layout/activity_profile.xml +++ b/app/src/main/res/layout/activity_profile.xml @@ -532,6 +532,14 @@ + + + + - - - + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_search_result_tabs.xml b/app/src/main/res/layout/activity_search_result_tabs.xml index 7d4b3af7..43d1c398 100644 --- a/app/src/main/res/layout/activity_search_result_tabs.xml +++ b/app/src/main/res/layout/activity_search_result_tabs.xml @@ -30,9 +30,15 @@ app:tabIndicatorColor="@color/cyanea_accent_dark_reference" app:tabMode="scrollable" /> - + android:layout_height="wrap_content"> + + + + > \ No newline at end of file