Fix issue with pagination

This commit is contained in:
Thomas 2022-06-25 19:35:12 +02:00
parent 1ac365befa
commit b1603894cb
18 changed files with 370 additions and 176 deletions

View File

@ -18,12 +18,14 @@
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
android:label="@string/app_name" android:label="@string/app_name"
android:configChanges="orientation|screenSize"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppThemeDark" android:theme="@style/AppThemeDark"
> >
<activity <activity
android:name=".activities.MainActivity" android:name=".activities.MainActivity"
android:configChanges="orientation|screenSize"
android:exported="true" android:exported="true"
> >
<intent-filter> <intent-filter>

View File

@ -55,6 +55,7 @@ import androidx.core.app.ActivityOptionsCompat;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.view.GravityCompat; import androidx.core.view.GravityCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.navigation.NavController; import androidx.navigation.NavController;
@ -838,8 +839,13 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
} }
public void refreshFragment() { public void refreshFragment() {
if (binding.viewPager.getAdapter() != null) { Fragment fragment = getSupportFragmentManager().findFragmentByTag("f" + binding.viewPager.getCurrentItem());
binding.viewPager.getAdapter().notifyDataSetChanged(); if (fragment instanceof FragmentNotificationContainer) {
FragmentTransaction fragTransaction = getSupportFragmentManager().beginTransaction();
fragTransaction.detach(fragment).commit();
FragmentTransaction fragTransaction2 = getSupportFragmentManager().beginTransaction();
fragTransaction2.attach(fragment);
fragTransaction2.commit();
} }
} }

View File

@ -59,12 +59,11 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.ViewPager2;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition; 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.ArrayList;
import java.util.Date; import java.util.Date;
@ -249,34 +248,28 @@ public class ProfileActivity extends BaseActivity {
binding.accountTabLayout.removeAllTabs(); binding.accountTabLayout.removeAllTabs();
//Tablayout for timelines/following/followers //Tablayout for timelines/following/followers
FedilabProfileTLPageAdapter fedilabProfileTLPageAdapter = new FedilabProfileTLPageAdapter(ProfileActivity.this, account); 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());
binding.accountTabLayout.addTab(binding.accountTabLayout.newTab().setText(getString(R.string.following_cnt, Helper.withSuffix(account.following_count)))); binding.accountTabLayout.addTab(binding.accountTabLayout.newTab());
binding.accountTabLayout.addTab(binding.accountTabLayout.newTab().setText(getString(R.string.followers_cnt, Helper.withSuffix(account.followers_count)))); binding.accountTabLayout.addTab(binding.accountTabLayout.newTab());
binding.accountViewpager.setAdapter(fedilabProfileTLPageAdapter); binding.accountViewpager.setAdapter(fedilabProfileTLPageAdapter);
binding.accountViewpager.setOffscreenPageLimit(3); 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 new TabLayoutMediator(binding.accountTabLayout, binding.accountViewpager,
public void onTabUnselected(TabLayout.Tab tab) { (tab, position) -> {
binding.accountViewpager.setCurrentItem(tab.getPosition(), true);
} switch (position) {
case 0:
@Override tab.setText(getString(R.string.status_cnt, Helper.withSuffix(account.statuses_count)));
public void onTabReselected(TabLayout.Tab tab) { 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.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)); binding.accountTabLayout.setTabIconTint(ThemeHelper.getColorStateList(ProfileActivity.this));
boolean disableGif = sharedpreferences.getBoolean(getString(R.string.SET_DISABLE_GIF), false); boolean disableGif = sharedpreferences.getBoolean(getString(R.string.SET_DISABLE_GIF), false);

View File

@ -24,7 +24,7 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBar;
import androidx.core.content.ContextCompat; 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.R;
import app.fedilab.android.databinding.ActivityScheduledBinding; import app.fedilab.android.databinding.ActivityScheduledBinding;
@ -56,31 +56,31 @@ public class ScheduledActivity extends BaseActivity {
MastodonHelper.loadPPMastodon(binding.profilePicture, currentAccount.mastodon_account); MastodonHelper.loadPPMastodon(binding.profilePicture, currentAccount.mastodon_account);
binding.title.setText(R.string.scheduled); binding.title.setText(R.string.scheduled);
binding.scheduleTablayout.addTab(binding.scheduleTablayout.newTab().setText(getString(R.string.toots_server))); binding.scheduleTablayout.addTab(binding.scheduleTablayout.newTab());
binding.scheduleTablayout.addTab(binding.scheduleTablayout.newTab().setText(getString(R.string.toots_client))); binding.scheduleTablayout.addTab(binding.scheduleTablayout.newTab());
binding.scheduleTablayout.addTab(binding.scheduleTablayout.newTab().setText(getString(R.string.reblog))); binding.scheduleTablayout.addTab(binding.scheduleTablayout.newTab());
binding.scheduleViewpager.setAdapter(new FedilabScheduledPageAdapter(ScheduledActivity.this)); binding.scheduleViewpager.setAdapter(new FedilabScheduledPageAdapter(ScheduledActivity.this));
binding.scheduleViewpager.setOffscreenPageLimit(3); 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.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.setTabIconTint(ThemeHelper.getColorStateList(ScheduledActivity.this));
binding.scheduleTablayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { new TabLayoutMediator(binding.scheduleTablayout, binding.scheduleViewpager,
@Override (tab, position) -> {
public void onTabSelected(TabLayout.Tab tab) { binding.scheduleViewpager.setCurrentItem(tab.getPosition(), true);
binding.scheduleViewpager.setCurrentItem(tab.getPosition()); switch (position) {
} case 0:
tab.setText(getString(R.string.toots_server));
@Override break;
public void onTabUnselected(TabLayout.Tab tab) { case 1:
tab.setText(getString(R.string.toots_client));
} break;
case 2:
@Override tab.setText(getString(R.string.reblog));
public void onTabReselected(TabLayout.Tab tab) { break;
}
} }
}); ).attach();
} }
@Override @Override

View File

@ -30,9 +30,9 @@ import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter; import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import org.jetbrains.annotations.NotNull; 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))); getSupportActionBar().setBackgroundDrawable(new ColorDrawable(ContextCompat.getColor(this, R.color.cyanea_primary)));
} }
setTitle(search); setTitle(search);
binding.searchTabLayout.addTab(binding.searchTabLayout.newTab().setText(getString(R.string.tags))); binding.searchTabLayout.addTab(binding.searchTabLayout.newTab());
binding.searchTabLayout.addTab(binding.searchTabLayout.newTab().setText(getString(R.string.accounts))); binding.searchTabLayout.addTab(binding.searchTabLayout.newTab());
binding.searchTabLayout.addTab(binding.searchTabLayout.newTab().setText(getString(R.string.toots))); binding.searchTabLayout.addTab(binding.searchTabLayout.newTab());
binding.searchTabLayout.addTab(binding.searchTabLayout.newTab().setText(getString(R.string.action_cache))); 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.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)); 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() { binding.searchTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override @Override
public void onTabSelected(TabLayout.Tab tab) { public void onTabSelected(TabLayout.Tab tab) {
@ -95,19 +116,16 @@ public class SearchResultTabActivity extends BaseActivity {
@Override @Override
public void onTabReselected(TabLayout.Tab tab) { public void onTabReselected(TabLayout.Tab tab) {
Fragment fragment; Fragment fragment = getSupportFragmentManager().findFragmentByTag("f" + binding.searchViewpager.getCurrentItem());
if (binding.searchViewpager.getAdapter() != null) { if (fragment instanceof FragmentMastodonAccount) {
fragment = (Fragment) getSupportFragmentManager().findFragmentByTag("f" + binding.searchViewpager.getCurrentItem()); FragmentMastodonAccount fragmentMastodonAccount = ((FragmentMastodonAccount) fragment);
if (fragment instanceof FragmentMastodonAccount) { fragmentMastodonAccount.scrollToTop();
FragmentMastodonAccount fragmentMastodonAccount = ((FragmentMastodonAccount) fragment); } else if (fragment instanceof FragmentMastodonTimeline) {
fragmentMastodonAccount.scrollToTop(); FragmentMastodonTimeline fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment);
} else if (fragment instanceof FragmentMastodonTimeline) { fragmentMastodonTimeline.scrollToTop();
FragmentMastodonTimeline fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment); } else if (fragment instanceof FragmentMastodonTag) {
fragmentMastodonTimeline.scrollToTop(); FragmentMastodonTag fragmentMastodonTag = ((FragmentMastodonTag) fragment);
} else if (fragment instanceof FragmentMastodonTag) { fragmentMastodonTag.scrollToTop();
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 searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false); searchView.setIconifiedByDefault(false);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override @Override
public boolean onQueryTextSubmit(String query) { 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; return true;
} }

View File

@ -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)
}
}
}
}
}
}

View File

@ -35,6 +35,7 @@ import androidx.fragment.app.FragmentTransaction;
import androidx.viewpager2.widget.ViewPager2; import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -147,11 +148,14 @@ public class PinnedTimelineHelper {
activityMainBinding.tabLayout.removeAllTabs(); activityMainBinding.tabLayout.removeAllTabs();
//Small hack to hide first tabs (they represent the item of the bottom menu) //Small hack to hide first tabs (they represent the item of the bottom menu)
int toRemove = itemToRemoveInBottomMenu(activity); int toRemove = itemToRemoveInBottomMenu(activity);
List<String> tabTitle = new ArrayList<>();
for (int i = 0; i < (BOTTOM_TIMELINE_COUNT - toRemove); i++) { for (int i = 0; i < (BOTTOM_TIMELINE_COUNT - toRemove); i++) {
activityMainBinding.tabLayout.addTab(activityMainBinding.tabLayout.newTab()); activityMainBinding.tabLayout.addTab(activityMainBinding.tabLayout.newTab());
tabTitle.add("");
((ViewGroup) activityMainBinding.tabLayout.getChildAt(0)).getChildAt(i).setVisibility(View.GONE); ((ViewGroup) activityMainBinding.tabLayout.getChildAt(0)).getChildAt(i).setVisibility(View.GONE);
} }
List<PinnedTimeline> pinnedTimelineVisibleList = new ArrayList<>(); List<PinnedTimeline> pinnedTimelineVisibleList = new ArrayList<>();
for (PinnedTimeline pinnedTimeline : pinned.pinnedTimelines) { for (PinnedTimeline pinnedTimeline : pinned.pinnedTimelines) {
if (pinnedTimeline.displayed) { if (pinnedTimeline.displayed) {
TabLayout.Tab tab = activityMainBinding.tabLayout.newTab(); 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); TextView tv = (TextView) LayoutInflater.from(activity).inflate(R.layout.custom_tab_instance, new LinearLayout(activity), false);
tv.setText(name); tv.setText(name);
tabTitle.add(name);
tab.setCustomView(tv); tab.setCustomView(tv);
activityMainBinding.tabLayout.addTab(tab); activityMainBinding.tabLayout.addTab(tab);
@ -205,16 +209,10 @@ public class PinnedTimelineHelper {
FedilabPageAdapter fedilabPageAdapter = new FedilabPageAdapter(activity, activity, pinned, bottomMenu); FedilabPageAdapter fedilabPageAdapter = new FedilabPageAdapter(activity, activity, pinned, bottomMenu);
activityMainBinding.viewPager.setAdapter(fedilabPageAdapter); activityMainBinding.viewPager.setAdapter(fedilabPageAdapter);
activityMainBinding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { 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 @Override
public void onPageSelected(int position) { public void onPageSelected(int position) {
super.onPageSelected(position);
if (position < BOTTOM_TIMELINE_COUNT - toRemove) { if (position < BOTTOM_TIMELINE_COUNT - toRemove) {
activityMainBinding.bottomNavView.getMenu().getItem(position).setChecked(true); activityMainBinding.bottomNavView.getMenu().getItem(position).setChecked(true);
} else { } else {
@ -225,18 +223,14 @@ public class PinnedTimelineHelper {
activityMainBinding.bottomNavView.getMenu().setGroupCheckable(0, true, true); 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() { activityMainBinding.tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override @Override
public void onTabSelected(TabLayout.Tab tab) { public void onTabSelected(TabLayout.Tab tab) {
activityMainBinding.viewPager.setCurrentItem(tab.getPosition());
} }
@Override @Override
@ -245,7 +239,7 @@ public class PinnedTimelineHelper {
@Override @Override
public void onTabReselected(TabLayout.Tab tab) { 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) { if (fragment instanceof FragmentMastodonTimeline) {
((FragmentMastodonTimeline) fragment).scrollToTop(); ((FragmentMastodonTimeline) fragment).scrollToTop();
} else if (fragment instanceof FragmentMastodonConversation) { } else if (fragment instanceof FragmentMastodonConversation) {
@ -319,7 +313,7 @@ public class PinnedTimelineHelper {
if (changes[0]) { if (changes[0]) {
FragmentMastodonTimeline fragmentMastodonTimeline; FragmentMastodonTimeline fragmentMastodonTimeline;
if (activityMainBinding.viewPager.getAdapter() != 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()) { if (fragment instanceof FragmentMastodonTimeline && fragment.isVisible()) {
fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment); fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment);
FragmentTransaction fragTransaction = activity.getSupportFragmentManager().beginTransaction(); FragmentTransaction fragTransaction = activity.getSupportFragmentManager().beginTransaction();
@ -376,7 +370,7 @@ public class PinnedTimelineHelper {
} }
} else if (itemId == R.id.action_any) { } else if (itemId == R.id.action_any) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(activity, Helper.dialogStyle()); 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); View dialogView = inflater.inflate(R.layout.tags_any, new LinearLayout(activity), false);
dialogBuilder.setView(dialogView); dialogBuilder.setView(dialogView);
final EditText editText = dialogView.findViewById(R.id.filter_any); final EditText editText = dialogView.findViewById(R.id.filter_any);
@ -405,7 +399,7 @@ public class PinnedTimelineHelper {
View dialogView; View dialogView;
AlertDialog alertDialog; AlertDialog alertDialog;
dialogBuilder = new AlertDialog.Builder(activity, Helper.dialogStyle()); 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); dialogView = inflater.inflate(R.layout.tags_all, new LinearLayout(activity), false);
dialogBuilder.setView(dialogView); dialogBuilder.setView(dialogView);
final EditText editTextAll = dialogView.findViewById(R.id.filter_all); final EditText editTextAll = dialogView.findViewById(R.id.filter_all);
@ -434,7 +428,7 @@ public class PinnedTimelineHelper {
View dialogView; View dialogView;
AlertDialog alertDialog; AlertDialog alertDialog;
dialogBuilder = new AlertDialog.Builder(activity, Helper.dialogStyle()); 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); dialogView = inflater.inflate(R.layout.tags_all, new LinearLayout(activity), false);
dialogBuilder.setView(dialogView); dialogBuilder.setView(dialogView);
final EditText editTextNone = dialogView.findViewById(R.id.filter_all); final EditText editTextNone = dialogView.findViewById(R.id.filter_all);
@ -463,7 +457,7 @@ public class PinnedTimelineHelper {
View dialogView; View dialogView;
AlertDialog alertDialog; AlertDialog alertDialog;
dialogBuilder = new AlertDialog.Builder(activity, Helper.dialogStyle()); 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); dialogView = inflater.inflate(R.layout.tags_name, new LinearLayout(activity), false);
dialogBuilder.setView(dialogView); dialogBuilder.setView(dialogView);
final EditText editTextName = dialogView.findViewById(R.id.column_name); final EditText editTextName = dialogView.findViewById(R.id.column_name);
@ -536,14 +530,14 @@ public class PinnedTimelineHelper {
changes[0] = true; changes[0] = true;
FragmentMastodonTimeline fragmentMastodonTimeline = null; FragmentMastodonTimeline fragmentMastodonTimeline = null;
if (activityMainBinding.viewPager.getAdapter() != 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()) { if (fragment instanceof FragmentMastodonTimeline && fragment.isVisible()) {
fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment); fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment);
} }
} }
if (fragmentMastodonTimeline == null) if (fragmentMastodonTimeline == null)
return false; return false;
FragmentTransaction fragTransaction1 = ((BaseMainActivity) activity).getSupportFragmentManager().beginTransaction(); FragmentTransaction fragTransaction1 = activity.getSupportFragmentManager().beginTransaction();
pinned.pinnedTimelines.get(offSetPosition).remoteInstance.filteredWith = null; pinned.pinnedTimelines.get(offSetPosition).remoteInstance.filteredWith = null;
remoteInstance.filteredWith = null; remoteInstance.filteredWith = null;
@ -561,7 +555,7 @@ public class PinnedTimelineHelper {
bundle.putString("timelineId", remoteInstance.id); bundle.putString("timelineId", remoteInstance.id);
bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.REMOTE); bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.REMOTE);
fragmentMastodonTimeline.setArguments(bundle); fragmentMastodonTimeline.setArguments(bundle);
FragmentTransaction fragTransaction2 = ((BaseMainActivity) activity).getSupportFragmentManager().beginTransaction(); FragmentTransaction fragTransaction2 = activity.getSupportFragmentManager().beginTransaction();
fragTransaction2.attach(fragmentMastodonTimeline); fragTransaction2.attach(fragmentMastodonTimeline);
fragTransaction2.commit(); fragTransaction2.commit();
popup.getMenu().close(); popup.getMenu().close();
@ -583,13 +577,13 @@ public class PinnedTimelineHelper {
item.setOnMenuItemClickListener(item1 -> { item.setOnMenuItemClickListener(item1 -> {
FragmentMastodonTimeline fragmentMastodonTimeline = null; FragmentMastodonTimeline fragmentMastodonTimeline = null;
if (activityMainBinding.viewPager.getAdapter() != 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()) { if (fragment instanceof FragmentMastodonTimeline && fragment.isVisible()) {
fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment); fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment);
fragmentMastodonTimeline.refreshAllAdapters(); fragmentMastodonTimeline.refreshAllAdapters();
} }
} }
FragmentTransaction fragTransaction1 = ((BaseMainActivity) activity).getSupportFragmentManager().beginTransaction(); FragmentTransaction fragTransaction1 = activity.getSupportFragmentManager().beginTransaction();
if (fragmentMastodonTimeline == null) if (fragmentMastodonTimeline == null)
return false; return false;
pinned.pinnedTimelines.get(offSetPosition).remoteInstance.filteredWith = tag; pinned.pinnedTimelines.get(offSetPosition).remoteInstance.filteredWith = tag;
@ -608,7 +602,7 @@ public class PinnedTimelineHelper {
bundle.putString("currentfilter", remoteInstance.filteredWith); bundle.putString("currentfilter", remoteInstance.filteredWith);
bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.REMOTE); bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.REMOTE);
fragmentMastodonTimeline.setArguments(bundle); fragmentMastodonTimeline.setArguments(bundle);
FragmentTransaction fragTransaction2 = ((BaseMainActivity) activity).getSupportFragmentManager().beginTransaction(); FragmentTransaction fragTransaction2 = activity.getSupportFragmentManager().beginTransaction();
fragTransaction2.attach(fragmentMastodonTimeline); fragTransaction2.attach(fragmentMastodonTimeline);
fragTransaction2.commit(); fragTransaction2.commit();
return false; return false;
@ -634,7 +628,7 @@ public class PinnedTimelineHelper {
}); });
changes[0] = true; changes[0] = true;
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(activity, Helper.dialogStyle()); 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); View dialogView = inflater.inflate(R.layout.tags_instance, new LinearLayout(activity), false);
dialogBuilder.setView(dialogView); dialogBuilder.setView(dialogView);
final EditText editText = dialogView.findViewById(R.id.filter_words); final EditText editText = dialogView.findViewById(R.id.filter_words);
@ -666,13 +660,13 @@ public class PinnedTimelineHelper {
if (changes[0]) { if (changes[0]) {
FragmentMastodonTimeline fragmentMastodonTimeline = null; FragmentMastodonTimeline fragmentMastodonTimeline = null;
if (activityMainBinding.viewPager.getAdapter() != 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()) { if (fragment instanceof FragmentMastodonTimeline && fragment.isVisible()) {
fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment); fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment);
fragmentMastodonTimeline.refreshAllAdapters(); fragmentMastodonTimeline.refreshAllAdapters();
} }
} }
FragmentTransaction fragTransaction1 = ((BaseMainActivity) activity).getSupportFragmentManager().beginTransaction(); FragmentTransaction fragTransaction1 = activity.getSupportFragmentManager().beginTransaction();
if (fragmentMastodonTimeline == null) if (fragmentMastodonTimeline == null)
return; return;
fragTransaction1.detach(fragmentMastodonTimeline).commit(); fragTransaction1.detach(fragmentMastodonTimeline).commit();
@ -685,7 +679,7 @@ public class PinnedTimelineHelper {
} }
bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.REMOTE); bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.REMOTE);
fragmentMastodonTimeline.setArguments(bundle); fragmentMastodonTimeline.setArguments(bundle);
FragmentTransaction fragTransaction2 = ((BaseMainActivity) activity).getSupportFragmentManager().beginTransaction(); FragmentTransaction fragTransaction2 = activity.getSupportFragmentManager().beginTransaction();
fragTransaction2.attach(fragmentMastodonTimeline); fragTransaction2.attach(fragmentMastodonTimeline);
fragTransaction2.commit(); fragTransaction2.commit();
} }

View File

@ -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);
}
}
}

View File

@ -177,7 +177,7 @@ public class FragmentAdminAccount extends Fragment {
* @param adminAccounts AdminAccounts * @param adminAccounts AdminAccounts
*/ */
private void dealWithPagination(AdminAccounts adminAccounts) { private void dealWithPagination(AdminAccounts adminAccounts) {
if (binding == null) { if (binding == null || !isAdded() || getActivity() == null) {
return; return;
} }
binding.loadingNextElements.setVisibility(View.GONE); binding.loadingNextElements.setVisibility(View.GONE);

View File

@ -98,7 +98,7 @@ public class FragmentAdminReport extends Fragment {
* @param adminReports {@link AdminReports} * @param adminReports {@link AdminReports}
*/ */
private void initializeStatusesCommonView(final AdminReports adminReports) { private void initializeStatusesCommonView(final AdminReports adminReports) {
if (binding == null) { if (binding == null || !isAdded() || getActivity() == null) {
return; return;
} }
binding.loader.setVisibility(View.GONE); binding.loader.setVisibility(View.GONE);
@ -180,7 +180,7 @@ public class FragmentAdminReport extends Fragment {
*/ */
private void dealWithPagination(AdminReports admReports) { private void dealWithPagination(AdminReports admReports) {
if (binding == null) { if (binding == null || !isAdded() || getActivity() == null) {
return; return;
} }
binding.loadingNextElements.setVisibility(View.GONE); binding.loadingNextElements.setVisibility(View.GONE);

View File

@ -172,7 +172,7 @@ public class FragmentMastodonAccount extends Fragment {
*/ */
private void initializeAccountCommonView(final Accounts accounts) { private void initializeAccountCommonView(final Accounts accounts) {
flagLoading = false; flagLoading = false;
if (binding == null) { if (binding == null || !isAdded() || getActivity() == null) {
return; return;
} }
binding.loader.setVisibility(View.GONE); binding.loader.setVisibility(View.GONE);
@ -242,7 +242,7 @@ public class FragmentMastodonAccount extends Fragment {
*/ */
private void dealWithPagination(Accounts fetched_accounts) { private void dealWithPagination(Accounts fetched_accounts) {
flagLoading = false; flagLoading = false;
if (binding == null) { if (binding == null || !isAdded() || getActivity() == null) {
return; return;
} }
binding.loadingNextElements.setVisibility(View.GONE); binding.loadingNextElements.setVisibility(View.GONE);

View File

@ -227,6 +227,9 @@ public class FragmentMastodonContext extends Fragment {
Helper.sendToastMessage(requireActivity(), Helper.RECEIVE_TOAST_TYPE_ERROR, getString(R.string.toast_error)); Helper.sendToastMessage(requireActivity(), Helper.RECEIVE_TOAST_TYPE_ERROR, getString(R.string.toast_error));
return; return;
} }
if (binding == null || !isAdded() || getActivity() == null) {
return;
}
if (pullToRefresh) { if (pullToRefresh) {
pullToRefresh = false; pullToRefresh = false;
int size = this.statuses.size(); int size = this.statuses.size();

View File

@ -192,7 +192,7 @@ public class FragmentMastodonNotification extends Fragment implements Notificati
*/ */
private void initializeNotificationView(final Notifications notifications) { private void initializeNotificationView(final Notifications notifications) {
flagLoading = false; flagLoading = false;
if (binding == null) { if (binding == null || !isAdded() || getActivity() == null) {
return; return;
} }
binding.loader.setVisibility(View.GONE); 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 * @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) { private void route(FragmentMastodonTimeline.DIRECTION direction, boolean fetchingMissing) {
if (binding == null || !isAdded() || getActivity() == null) {
return;
}
new Thread(() -> { new Thread(() -> {
if (binding == null) {
return;
}
QuickLoad quickLoad = new QuickLoad(requireActivity()).getSavedValue(MainActivity.currentUserID, MainActivity.currentInstance, notificationType); 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) { if (direction != FragmentMastodonTimeline.DIRECTION.REFRESH && !fetchingMissing && !binding.swipeContainer.isRefreshing() && direction == null && quickLoad != null && quickLoad.notifications != null && quickLoad.notifications.size() > 0) {
Notifications notifications = new Notifications(); Notifications notifications = new Notifications();
@ -365,10 +365,9 @@ public class FragmentMastodonNotification extends Fragment implements Notificati
* @param fetched_notifications Notifications * @param fetched_notifications Notifications
*/ */
private synchronized void dealWithPagination(Notifications fetched_notifications, FragmentMastodonTimeline.DIRECTION direction, boolean fetchingMissing) { private synchronized void dealWithPagination(Notifications fetched_notifications, FragmentMastodonTimeline.DIRECTION direction, boolean fetchingMissing) {
if (binding == null) { if (binding == null || !isAdded() || getActivity() == null) {
return; return;
} }
int currentPosition = mLayoutManager.findFirstVisibleItemPosition();
binding.swipeContainer.setRefreshing(false); binding.swipeContainer.setRefreshing(false);
binding.loadingNextElements.setVisibility(View.GONE); binding.loadingNextElements.setVisibility(View.GONE);
flagLoading = false; flagLoading = false;
@ -376,10 +375,7 @@ public class FragmentMastodonNotification extends Fragment implements Notificati
flagLoading = fetched_notifications.pagination.max_id == null; flagLoading = fetched_notifications.pagination.max_id == null;
binding.noAction.setVisibility(View.GONE); binding.noAction.setVisibility(View.GONE);
//Update the timeline with new statuses //Update the timeline with new statuses
int inserted = updateNotificationListWith(direction, fetched_notifications.notifications, fetchingMissing); updateNotificationListWith(direction, fetched_notifications.notifications, fetchingMissing);
if (fetchingMissing) {
// binding.recyclerView.scrollToPosition(currentPosition + inserted);
}
if (!fetchingMissing) { if (!fetchingMissing) {
if (fetched_notifications.pagination.max_id == null) { if (fetched_notifications.pagination.max_id == null) {
flagLoading = true; flagLoading = true;
@ -400,9 +396,8 @@ public class FragmentMastodonNotification extends Fragment implements Notificati
* *
* @param notificationsReceived - List<Notification> Notifications received * @param notificationsReceived - List<Notification> Notifications received
* @param fetchingMissing - boolean if the call concerns fetching messages (ie: refresh of from fetch more button) * @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<Notification> notificationsReceived, boolean fetchingMissing) { private void updateNotificationListWith(FragmentMastodonTimeline.DIRECTION direction, List<Notification> notificationsReceived, boolean fetchingMissing) {
int numberInserted = 0; int numberInserted = 0;
int lastInsertedPosition = 0; int lastInsertedPosition = 0;
int initialInsertedPosition = NOTIFICATION_PRESENT; int initialInsertedPosition = NOTIFICATION_PRESENT;
@ -438,7 +433,6 @@ public class FragmentMastodonNotification extends Fragment implements Notificati
notificationAdapter.notifyItemInserted(insertAt); notificationAdapter.notifyItemInserted(insertAt);
} }
} }
return numberInserted;
} }
/** /**

View File

@ -95,6 +95,9 @@ public class FragmentMastodonTag extends Fragment {
* @param tags List of {@link Tag} * @param tags List of {@link Tag}
*/ */
private void initializeTagCommonView(final List<Tag> tags) { private void initializeTagCommonView(final List<Tag> tags) {
if (binding == null || !isAdded() || getActivity() == null) {
return;
}
binding.loader.setVisibility(View.GONE); binding.loader.setVisibility(View.GONE);
binding.noAction.setVisibility(View.GONE); binding.noAction.setVisibility(View.GONE);
binding.swipeContainer.setRefreshing(false); binding.swipeContainer.setRefreshing(false);

View File

@ -260,7 +260,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
*/ */
private void initializeStatusesCommonView(final Statuses statuses, int position) { private void initializeStatusesCommonView(final Statuses statuses, int position) {
flagLoading = false; flagLoading = false;
if (binding == null) { if (binding == null || !isAdded() || getActivity() == null) {
return; return;
} }
binding.loader.setVisibility(View.GONE); binding.loader.setVisibility(View.GONE);
@ -376,7 +376,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
* @param fetched_statuses Statuses * @param fetched_statuses Statuses
*/ */
private synchronized void dealWithPagination(Statuses fetched_statuses, DIRECTION direction, boolean fetchingMissing) { private synchronized void dealWithPagination(Statuses fetched_statuses, DIRECTION direction, boolean fetchingMissing) {
if (binding == null) { if (binding == null || !isAdded() || getActivity() == null) {
return; return;
} }
binding.swipeContainer.setRefreshing(false); binding.swipeContainer.setRefreshing(false);

View File

@ -33,6 +33,7 @@ import androidx.preference.PreferenceManager;
import com.google.android.material.button.MaterialButton; import com.google.android.material.button.MaterialButton;
import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -60,19 +61,19 @@ public class FragmentNotificationContainer extends Fragment {
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity()); SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity());
boolean display_all_notification = sharedpreferences.getBoolean(getString(R.string.SET_DISPLAY_ALL_NOTIFICATIONS_TYPE) + BaseMainActivity.currentUserID + BaseMainActivity.currentInstance, false); boolean display_all_notification = sharedpreferences.getBoolean(getString(R.string.SET_DISPLAY_ALL_NOTIFICATIONS_TYPE) + BaseMainActivity.currentUserID + BaseMainActivity.currentInstance, false);
if (!display_all_notification) { if (!display_all_notification) {
binding.tabLayout.addTab(binding.tabLayout.newTab().setText(getString(R.string.all))); binding.tabLayout.addTab(binding.tabLayout.newTab());
binding.tabLayout.addTab(binding.tabLayout.newTab().setText(getString(R.string.mention))); binding.tabLayout.addTab(binding.tabLayout.newTab());
binding.tabLayout.setTabMode(TabLayout.MODE_FIXED); binding.tabLayout.setTabMode(TabLayout.MODE_FIXED);
binding.viewpager.setAdapter(new FedilabNotificationPageAdapter(requireActivity(), false)); binding.viewpager.setAdapter(new FedilabNotificationPageAdapter(requireActivity(), false));
} else { } else {
binding.tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE); binding.tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
binding.tabLayout.addTab(binding.tabLayout.newTab().setText(getString(R.string.all))); binding.tabLayout.addTab(binding.tabLayout.newTab());
binding.tabLayout.addTab(binding.tabLayout.newTab().setIcon(R.drawable.ic_baseline_reply_24)); binding.tabLayout.addTab(binding.tabLayout.newTab());
binding.tabLayout.addTab(binding.tabLayout.newTab().setIcon(R.drawable.ic_baseline_star_24)); binding.tabLayout.addTab(binding.tabLayout.newTab());
binding.tabLayout.addTab(binding.tabLayout.newTab().setIcon(R.drawable.ic_repeat)); binding.tabLayout.addTab(binding.tabLayout.newTab());
binding.tabLayout.addTab(binding.tabLayout.newTab().setIcon(R.drawable.ic_baseline_poll_24)); binding.tabLayout.addTab(binding.tabLayout.newTab());
binding.tabLayout.addTab(binding.tabLayout.newTab().setIcon(R.drawable.ic_baseline_home_24)); binding.tabLayout.addTab(binding.tabLayout.newTab());
binding.tabLayout.addTab(binding.tabLayout.newTab().setIcon(R.drawable.ic_baseline_person_add_alt_1_24)); binding.tabLayout.addTab(binding.tabLayout.newTab());
binding.viewpager.setAdapter(new FedilabNotificationPageAdapter(requireActivity(), true)); binding.viewpager.setAdapter(new FedilabNotificationPageAdapter(requireActivity(), true));
} }
AtomicBoolean changes = new AtomicBoolean(false); AtomicBoolean changes = new AtomicBoolean(false);
@ -187,7 +188,6 @@ public class FragmentNotificationContainer extends Fragment {
} }
}); });
dialogBuilder.setPositiveButton(R.string.close, (dialog, id) -> { dialogBuilder.setPositiveButton(R.string.close, (dialog, id) -> {
if (changes.get()) { if (changes.get()) {
SharedPreferences.Editor editor = sharedpreferences.edit(); SharedPreferences.Editor editor = sharedpreferences.edit();
if (excludedCategoriesList.size() > 0) { if (excludedCategoriesList.size() > 0) {
@ -202,7 +202,6 @@ public class FragmentNotificationContainer extends Fragment {
} else { } else {
editor.putString(getString(R.string.SET_EXCLUDED_NOTIFICATIONS_TYPE) + BaseMainActivity.currentUserID + BaseMainActivity.currentInstance, null); editor.putString(getString(R.string.SET_EXCLUDED_NOTIFICATIONS_TYPE) + BaseMainActivity.currentUserID + BaseMainActivity.currentInstance, null);
} }
editor.commit(); editor.commit();
((BaseMainActivity) requireActivity()).refreshFragment(); ((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.setTabTextColors(ThemeHelper.getAttColor(requireActivity(), R.attr.mTextColor), ContextCompat.getColor(requireActivity(), R.color.cyanea_accent_dark_reference));
binding.tabLayout.setTabIconTint(ThemeHelper.getColorStateList(requireActivity())); 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() { binding.tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override @Override
public void onTabSelected(TabLayout.Tab tab) { public void onTabSelected(TabLayout.Tab tab) {
@ -227,15 +267,11 @@ public class FragmentNotificationContainer extends Fragment {
@Override @Override
public void onTabReselected(TabLayout.Tab tab) { public void onTabReselected(TabLayout.Tab tab) {
Fragment fragment; Fragment fragment = requireActivity().getSupportFragmentManager().findFragmentByTag("f" + binding.viewpager.getCurrentItem());
if (binding.viewpager.getAdapter() != null) { if (fragment instanceof FragmentMastodonNotification) {
fragment = (Fragment) requireActivity().getSupportFragmentManager().findFragmentByTag("f" + binding.viewpager.getCurrentItem()); FragmentMastodonNotification fragmentMastodonNotification = ((FragmentMastodonNotification) fragment);
if (fragment instanceof FragmentMastodonNotification) { fragmentMastodonNotification.scrollToTop();
FragmentMastodonNotification fragmentMastodonNotification = ((FragmentMastodonNotification) fragment);
fragmentMastodonNotification.scrollToTop();
}
} }
} }
}); });
return binding.getRoot(); return binding.getRoot();
@ -244,9 +280,9 @@ public class FragmentNotificationContainer extends Fragment {
public void scrollToTop() { public void scrollToTop() {
if (binding != null) { if (binding != null) {
FragmentMastodonNotification fragmentMastodonNotification = (FragmentMastodonNotification) requireActivity().getSupportFragmentManager().findFragmentByTag("f" + binding.viewpager.getCurrentItem()); Fragment fragment = requireActivity().getSupportFragmentManager().findFragmentByTag("f" + binding.viewpager.getCurrentItem());
if (fragmentMastodonNotification != null) { if (fragment instanceof FragmentMastodonNotification) {
fragmentMastodonNotification.scrollToTop(); ((FragmentMastodonNotification) fragment).scrollToTop();
} }
} }
} }

View File

@ -532,6 +532,14 @@
</com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<com.google.android.material.tabs.TabLayout <com.google.android.material.tabs.TabLayout
android:id="@+id/account_tabLayout" android:id="@+id/account_tabLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -539,13 +547,11 @@
android:background="?backgroundColorLight" android:background="?backgroundColorLight"
app:tabGravity="fill" app:tabGravity="fill"
app:tabMode="fixed" /> app:tabMode="fixed" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/account_viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/account_viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -30,9 +30,15 @@
app:tabIndicatorColor="@color/cyanea_accent_dark_reference" app:tabIndicatorColor="@color/cyanea_accent_dark_reference"
app:tabMode="scrollable" /> app:tabMode="scrollable" />
<androidx.viewpager2.widget.ViewPager2 <app.fedilab.android.helper.NestedScrollableHost
android:id="@+id/search_viewpager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/search_viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</app.fedilab.android.helper.NestedScrollableHost>
>
</LinearLayout> </LinearLayout>