Fix scrolling issues

This commit is contained in:
Ammar Githam 2021-07-11 20:24:04 +09:00
parent 08ed3cd4d1
commit efd3f8cff0
15 changed files with 271 additions and 273 deletions

View File

@ -24,6 +24,7 @@ import androidx.core.view.WindowInsetsCompat
import androidx.emoji.text.EmojiCompat
import androidx.emoji.text.EmojiCompat.InitCallback
import androidx.emoji.text.FontRequestEmojiCompatConfig
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavController
import androidx.navigation.NavDestination
@ -75,8 +76,11 @@ class MainActivity : BaseLanguageActivity() {
private var deviceUuid: String? = null
private var csrfToken: String? = null
private var userId: Long = 0
private var toolbarOwner: Fragment? = null
lateinit var toolbar: Toolbar
private set
// private var behavior: HideBottomViewOnScrollBehavior<BottomNavigationView>? = null
var currentTabs: List<Tab> = emptyList()
private set
private var showBottomViewDestinations: List<Int> = emptyList()
@ -102,7 +106,9 @@ class MainActivity : BaseLanguageActivity() {
} catch (e: ReselectDocumentTreeException) {
super.onCreate(savedInstanceState)
val intent = Intent(this, DirectorySelectActivity::class.java)
intent.putExtra(EXTRA_INITIAL_URI, e.initialUri)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
intent.putExtra(EXTRA_INITIAL_URI, e.initialUri)
}
startActivity(intent)
finish()
return
@ -110,6 +116,7 @@ class MainActivity : BaseLanguageActivity() {
super.onCreate(savedInstanceState)
instance = this
binding = ActivityMainBinding.inflate(layoutInflater)
toolbar = binding.toolbar
setupCookie()
if (Utils.settingsHelper.getBoolean(PreferenceKeys.FLAG_SECURE)) {
window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
@ -118,13 +125,6 @@ class MainActivity : BaseLanguageActivity() {
setSupportActionBar(binding.toolbar)
setupInsetsCallback()
createNotificationChannels()
// try {
// val layoutParams = binding.bottomNavView.layoutParams as CoordinatorLayout.LayoutParams
// @Suppress("UNCHECKED_CAST")
// behavior = layoutParams.behavior as HideBottomViewOnScrollBehavior<BottomNavigationView>
// } catch (e: Exception) {
// Log.e(TAG, "onCreate: ", e)
// }
val navHostFragment = supportFragmentManager.findFragmentById(R.id.main_nav_host) as NavHostFragment
navController = navHostFragment.navController
if (savedInstanceState == null) {
@ -610,11 +610,14 @@ class MainActivity : BaseLanguageActivity() {
// }
// }
fun resetToolbar() {
@Synchronized
fun resetToolbar(owner: Fragment) {
if (owner != toolbarOwner) return
binding.appBarLayout.visibility = View.VISIBLE
setScrollingBehaviour()
setSupportActionBar(binding.toolbar)
setupActionBarWithNavController(navController, appBarConfiguration)
toolbarOwner = null
}
val collapsingToolbarView: CollapsingToolbarLayout
@ -652,17 +655,19 @@ class MainActivity : BaseLanguageActivity() {
EmojiCompat.init(config)
}
var toolbar: Toolbar
get() = binding.toolbar
set(toolbar) {
binding.appBarLayout.visibility = View.GONE
removeScrollingBehaviour()
setSupportActionBar(toolbar)
NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration)
}
val rootView: View
get() = binding.root
@Synchronized
fun setToolbar(toolbar: Toolbar, owner: Fragment) {
toolbarOwner = owner
binding.appBarLayout.visibility = View.GONE
removeScrollingBehaviour()
setSupportActionBar(toolbar)
this.toolbar = toolbar
NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration)
}
private fun setNavBarDMUnreadCountBadge(unseenCount: Int) {
val badge = binding.bottomNavView.getOrCreateBadge(R.id.direct_messages_nav_graph)
if (unseenCount == 0) {

View File

@ -171,7 +171,7 @@ public class PostsRecyclerView extends RecyclerView {
final LiveData<List<Media>> mediaListLiveData = mediaViewModel.getList();
mediaListLiveData.observe(lifeCycleOwner, list -> feedAdapter.submitList(list, () -> {
dispatchFetchStatus();
// postDelayed(this::fetchMoreIfPossible, 1000);
postDelayed(this::fetchMoreIfPossible, 1000);
if (!shouldScrollToTop) return;
shouldScrollToTop = false;
post(() -> smoothScrollToPosition(0));

View File

@ -355,7 +355,7 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay
@Override
public void onResume() {
super.onResume();
fragmentActivity.setToolbar(binding.toolbar);
fragmentActivity.setToolbar(binding.toolbar, this);
}
@Override
@ -376,7 +376,7 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay
}
private void resetToolbar() {
fragmentActivity.resetToolbar();
fragmentActivity.resetToolbar(this);
}
private void init() {
@ -392,7 +392,7 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay
return;
}
binding.cover.setTransitionName("collection-" + savedCollection.getCollectionId());
fragmentActivity.setToolbar(binding.toolbar);
fragmentActivity.setToolbar(binding.toolbar, this);
binding.collapsingToolbarLayout.setTitle(savedCollection.getCollectionName());
final int collapsedTitleTextColor = ColorUtils.setAlphaComponent(titleColor, 0xFF);
final int expandedTitleTextColor = ColorUtils.setAlphaComponent(titleColor, 0x99);

View File

@ -23,12 +23,10 @@ import androidx.activity.OnBackPressedDispatcher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.constraintlayout.motion.widget.MotionLayout;
import androidx.constraintlayout.motion.widget.MotionScene;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.snackbar.BaseTransientBottomBar;
@ -51,7 +49,6 @@ import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment;
import awais.instagrabber.models.PostsLayoutPreferences;
import awais.instagrabber.models.enums.FavoriteType;
import awais.instagrabber.models.enums.FollowingType;
//import awais.instagrabber.repositories.requests.StoryViewerOptions;
import awais.instagrabber.repositories.responses.Hashtag;
import awais.instagrabber.repositories.responses.Location;
import awais.instagrabber.repositories.responses.Media;
@ -65,7 +62,6 @@ import awais.instagrabber.utils.TextUtils;
import awais.instagrabber.utils.Utils;
import awais.instagrabber.webservices.GraphQLRepository;
import awais.instagrabber.webservices.ServiceCallback;
//import awais.instagrabber.webservices.StoriesRepository;
import awais.instagrabber.webservices.TagsService;
import kotlinx.coroutines.Dispatchers;
@ -76,17 +72,17 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
private MainActivity fragmentActivity;
private FragmentHashtagBinding binding;
private MotionLayout root;
private CoordinatorLayout root;
private boolean shouldRefresh = true;
private boolean opening = false;
private String hashtag;
private Hashtag hashtagModel = null;
private ActionMode actionMode;
// private StoriesRepository storiesRepository;
// private StoriesRepository storiesRepository;
private boolean isLoggedIn;
private TagsService tagsService;
private GraphQLRepository graphQLRepository;
// private boolean storiesFetching;
// private boolean storiesFetching;
private Set<Media> selectedFeedModels;
private PostsLayoutPreferences layoutPreferences = Utils.getPostsLayoutPreferences(Constants.PREF_HASHTAG_POSTS_LAYOUT);
private LayoutHashtagDetailsBinding hashtagDetailsBinding;
@ -289,7 +285,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
final String cookie = settingsHelper.getString(Constants.COOKIE);
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
tagsService = isLoggedIn ? TagsService.getInstance() : null;
// storiesRepository = isLoggedIn ? StoriesRepository.Companion.getInstance() : null;
// storiesRepository = isLoggedIn ? StoriesRepository.Companion.getInstance() : null;
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
setHasOptionsMenu(true);
}
@ -309,6 +305,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
@Override
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
fragmentActivity.setToolbar(binding.toolbar, this);
if (!shouldRefresh) return;
binding.swipeRefreshLayout.setOnRefreshListener(this);
init();
@ -341,6 +338,12 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
return super.onOptionsItemSelected(item);
}
@Override
public void onDestroyView() {
super.onDestroyView();
fragmentActivity.resetToolbar(this);
}
private void init() {
if (getArguments() == null) return;
final HashTagFragmentArgs fragmentArgs = HashTagFragmentArgs.fromBundle(getArguments());
@ -370,17 +373,17 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
.setFeedItemCallback(feedItemCallback)
.setSelectionModeCallback(selectionModeCallback)
.init();
binding.posts.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) {
super.onScrolled(recyclerView, dx, dy);
final boolean canScrollVertically = recyclerView.canScrollVertically(-1);
final MotionScene.Transition transition = root.getTransition(R.id.transition);
if (transition != null) {
transition.setEnable(!canScrollVertically);
}
}
});
// binding.posts.addOnScrollListener(new RecyclerView.OnScrollListener() {
// @Override
// public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) {
// super.onScrolled(recyclerView, dx, dy);
// final boolean canScrollVertically = recyclerView.canScrollVertically(-1);
// final MotionScene.Transition transition = root.getTransition(R.id.transition);
// if (transition != null) {
// transition.setEnable(!canScrollVertically);
// }
// }
// });
}
private void setHashtagDetails() {
@ -562,7 +565,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
private void updateSwipeRefreshState() {
AppExecutors.INSTANCE.getMainThread().execute(() ->
binding.swipeRefreshLayout.setRefreshing(binding.posts.isFetching())
binding.swipeRefreshLayout.setRefreshing(binding.posts.isFetching())
);
}

View File

@ -1,5 +1,6 @@
package awais.instagrabber.fragments;
import android.annotation.SuppressLint;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
@ -21,12 +22,10 @@ import androidx.activity.OnBackPressedDispatcher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.constraintlayout.motion.widget.MotionLayout;
import androidx.constraintlayout.motion.widget.MotionScene;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.snackbar.BaseTransientBottomBar;
@ -48,7 +47,6 @@ import awais.instagrabber.db.repositories.FavoriteRepository;
import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment;
import awais.instagrabber.models.PostsLayoutPreferences;
import awais.instagrabber.models.enums.FavoriteType;
//import awais.instagrabber.repositories.requests.StoryViewerOptions;
import awais.instagrabber.repositories.responses.Location;
import awais.instagrabber.repositories.responses.Media;
import awais.instagrabber.repositories.responses.User;
@ -71,18 +69,15 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
private MainActivity fragmentActivity;
private FragmentLocationBinding binding;
private MotionLayout root;
private CoordinatorLayout root;
private boolean shouldRefresh = true;
// private boolean hasStories = false;
private boolean opening = false;
private long locationId;
private Location locationModel;
private ActionMode actionMode;
// private StoriesRepository storiesRepository;
private GraphQLRepository graphQLRepository;
private LocationService locationService;
private boolean isLoggedIn;
// private boolean storiesFetching;
private Set<Media> selectedFeedModels;
private PostsLayoutPreferences layoutPreferences = Utils.getPostsLayoutPreferences(Constants.PREF_LOCATION_POSTS_LAYOUT);
private LayoutLocationDetailsBinding locationDetailsBinding;
@ -173,12 +168,16 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
@Override
public void onNameClick(final Media feedModel) {
navigateToProfile("@" + feedModel.getUser().getUsername());
final User user = feedModel.getUser();
if (user == null) return;
navigateToProfile("@" + user.getUsername());
}
@Override
public void onProfilePicClick(final Media feedModel) {
navigateToProfile("@" + feedModel.getUser().getUsername());
final User user = feedModel.getUser();
if (user == null) return;
navigateToProfile("@" + user.getUsername());
}
@Override
@ -197,8 +196,10 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
if (user == null) return;
if (TextUtils.isEmpty(user.getUsername())) {
opening = true;
final String code = feedModel.getCode();
if (code == null) return;
graphQLRepository.fetchPost(
feedModel.getCode(),
code,
CoroutineUtilsKt.getContinuation((media, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
opening = false;
if (throwable != null) {
@ -277,7 +278,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
final String cookie = settingsHelper.getString(Constants.COOKIE);
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
locationService = isLoggedIn ? LocationService.getInstance() : null;
// storiesRepository = StoriesRepository.Companion.getInstance();
// storiesRepository = StoriesRepository.Companion.getInstance();
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
setHasOptionsMenu(true);
}
@ -299,6 +300,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
@Override
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
fragmentActivity.setToolbar(binding.toolbar, this);
if (!shouldRefresh) return;
binding.swipeRefreshLayout.setOnRefreshListener(this);
init();
@ -308,7 +310,6 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
@Override
public void onRefresh() {
binding.posts.refresh();
// fetchStories();
}
@Override
@ -331,6 +332,12 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
return super.onOptionsItemSelected(item);
}
@Override
public void onDestroyView() {
super.onDestroyView();
fragmentActivity.resetToolbar(this);
}
private void init() {
if (getArguments() == null) return;
final LocationFragmentArgs fragmentArgs = LocationFragmentArgs.fromBundle(getArguments());
@ -350,17 +357,17 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
.setFeedItemCallback(feedItemCallback)
.setSelectionModeCallback(selectionModeCallback)
.init();
binding.posts.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) {
super.onScrolled(recyclerView, dx, dy);
final boolean canScrollVertically = recyclerView.canScrollVertically(-1);
final MotionScene.Transition transition = root.getTransition(R.id.transition);
if (transition != null) {
transition.setEnable(!canScrollVertically);
}
}
});
// binding.posts.addOnScrollListener(new RecyclerView.OnScrollListener() {
// @Override
// public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) {
// super.onScrolled(recyclerView, dx, dy);
// final boolean canScrollVertically = recyclerView.canScrollVertically(-1);
// final MotionScene.Transition transition = root.getTransition(R.id.transition);
// if (transition != null) {
// transition.setEnable(!canScrollVertically);
// }
// }
// });
}
private void fetchLocationModel() {
@ -533,45 +540,16 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
);
}), Dispatchers.getIO())
));
// locationDetailsBinding.mainLocationImage.setOnClickListener(v -> {
// if (hasStories) {
// // show stories
// final NavDirections action = LocationFragmentDirections
// .actionLocationFragmentToStoryViewerFragment(StoryViewerOptions.forLocation(locationId, locationModel.getName()));
// NavHostFragment.findNavController(this).navigate(action);
// }
// });
}
private void showSnackbar(final String message) {
final Snackbar snackbar = Snackbar.make(root, message, BaseTransientBottomBar.LENGTH_LONG);
@SuppressLint("ShowToast") final Snackbar snackbar = Snackbar.make(root, message, BaseTransientBottomBar.LENGTH_LONG);
snackbar.setAction(R.string.ok, v1 -> snackbar.dismiss())
.setAnimationMode(BaseTransientBottomBar.ANIMATION_MODE_SLIDE)
.setAnchorView(fragmentActivity.getBottomNavView())
.show();
}
// private void fetchStories() {
// if (isLoggedIn) {
// storiesFetching = true;
// storiesRepository.getStories(
// StoryViewerOptions.forLocation(locationId, locationModel.getName()),
// CoroutineUtilsKt.getContinuation((storyModels, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
// if (throwable != null) {
// Log.e(TAG, "Error", throwable);
// storiesFetching = false;
// return;
// }
// if (storyModels != null && !storyModels.isEmpty()) {
// locationDetailsBinding.mainLocationImage.setStoriesBorder(1);
// hasStories = true;
// }
// storiesFetching = false;
// }), Dispatchers.getIO())
// );
// }
// }
private void setTitle() {
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
if (actionBar != null && locationModel != null) {
@ -580,9 +558,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
}
private void updateSwipeRefreshState() {
AppExecutors.INSTANCE.getMainThread().execute(() ->
binding.swipeRefreshLayout.setRefreshing(binding.posts.isFetching())
);
AppExecutors.INSTANCE.getMainThread().execute(() -> binding.swipeRefreshLayout.setRefreshing(binding.posts.isFetching()));
}
private void navigateToProfile(final String username) {

View File

@ -269,7 +269,7 @@ public class TopicPostsFragment extends Fragment implements SwipeRefreshLayout.O
@Override
public void onResume() {
super.onResume();
fragmentActivity.setToolbar(binding.toolbar);
fragmentActivity.setToolbar(binding.toolbar, this);
}
@Override
@ -290,7 +290,7 @@ public class TopicPostsFragment extends Fragment implements SwipeRefreshLayout.O
}
private void resetToolbar() {
fragmentActivity.resetToolbar();
fragmentActivity.resetToolbar(this);
}
private void init() {
@ -306,7 +306,7 @@ public class TopicPostsFragment extends Fragment implements SwipeRefreshLayout.O
return;
}
binding.cover.setTransitionName("cover-" + topicCluster.getId());
fragmentActivity.setToolbar(binding.toolbar);
fragmentActivity.setToolbar(binding.toolbar, this);
binding.collapsingToolbarLayout.setTitle(topicCluster.getTitle());
final int collapsedTitleTextColor = ColorUtils.setAlphaComponent(titleColor, 0xFF);
final int expandedTitleTextColor = ColorUtils.setAlphaComponent(titleColor, 0x99);

View File

@ -16,8 +16,7 @@ import androidx.activity.OnBackPressedCallback;
import androidx.activity.OnBackPressedDispatcher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.motion.widget.MotionLayout;
import androidx.constraintlayout.motion.widget.MotionScene;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavController;
@ -59,7 +58,7 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
private static final String TAG = "FeedFragment";
private MainActivity fragmentActivity;
private MotionLayout root;
private CoordinatorLayout root;
private FragmentFeedBinding binding;
private StoriesRepository storiesRepository;
private boolean shouldRefresh = true;
@ -68,7 +67,6 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
private ActionMode actionMode;
private Set<Media> selectedFeedModels;
private PostsLayoutPreferences layoutPreferences = Utils.getPostsLayoutPreferences(Constants.PREF_POSTS_LAYOUT);
private RecyclerView storiesRecyclerView;
private MenuItem storyListMenu;
private final FeedStoriesAdapter feedStoriesAdapter = new FeedStoriesAdapter(
@ -282,6 +280,7 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
@Override
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
fragmentActivity.setToolbar(binding.toolbar, this);
if (!shouldRefresh) return;
binding.feedSwipeRefreshLayout.setOnRefreshListener(this);
/*
@ -336,6 +335,12 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
fetchStories();
}
@Override
public void onDestroyView() {
fragmentActivity.resetToolbar(this);
super.onDestroyView();
}
private void setupFeed() {
binding.feedRecyclerView.setViewModelStoreOwner(this)
.setLifeCycleOwner(this)
@ -345,17 +350,17 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
.setFeedItemCallback(feedItemCallback)
.setSelectionModeCallback(selectionModeCallback)
.init();
binding.feedRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) {
super.onScrolled(recyclerView, dx, dy);
final boolean canScrollVertically = recyclerView.canScrollVertically(-1);
final MotionScene.Transition transition = root.getTransition(R.id.transition);
if (transition != null) {
transition.setEnable(!canScrollVertically);
}
}
});
// binding.feedRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
// @Override
// public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) {
// super.onScrolled(recyclerView, dx, dy);
// final boolean canScrollVertically = recyclerView.canScrollVertically(-1);
// final MotionScene.Transition transition = root.getTransition(R.id.transition);
// if (transition != null) {
// transition.setEnable(!canScrollVertically);
// }
// }
// });
// if (shouldAutoPlay) {
// videoAwareRecyclerScroller = new VideoAwareRecyclerScroller();
// binding.feedRecyclerView.addOnScrollListener(videoAwareRecyclerScroller);
@ -363,8 +368,8 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
}
private void updateSwipeRefreshState() {
AppExecutors.INSTANCE.getMainThread().execute(() ->
binding.feedSwipeRefreshLayout.setRefreshing(binding.feedRecyclerView.isFetching() || storiesFetching)
AppExecutors.INSTANCE.getMainThread().execute(() -> binding.feedSwipeRefreshLayout
.setRefreshing(binding.feedRecyclerView.isFetching() || storiesFetching)
);
}
@ -373,7 +378,7 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
feedStoriesViewModel = new ViewModelProvider(fragmentActivity).get(FeedStoriesViewModel.class);
final Context context = getContext();
if (context == null) return;
storiesRecyclerView = binding.header;
final RecyclerView storiesRecyclerView = binding.header;
storiesRecyclerView.setLayoutManager(new LinearLayoutManager(context, RecyclerView.HORIZONTAL, false));
storiesRecyclerView.setAdapter(feedStoriesAdapter);
feedStoriesViewModel.getList().observe(fragmentActivity, feedStoriesAdapter::submitList);

View File

@ -60,6 +60,7 @@ import awais.instagrabber.viewmodels.ProfileFragmentViewModel.ProfileEvent.*
import awais.instagrabber.viewmodels.ProfileFragmentViewModelFactory
import awais.instagrabber.webservices.*
class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCallback, MultiOptionDialogSingleCallback<String> {
private var backStackSavedStateResultLiveData: MutableLiveData<Any?>? = null
private var shareDmMenuItem: MenuItem? = null
@ -100,15 +101,15 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall
private val translationDialogRequestCode = 103
private val feedItemCallback: FeedAdapterV2.FeedItemCallback = object : FeedAdapterV2.FeedItemCallback {
override fun onPostClick(media: Media) {
openPostDialog(media ?: return, -1)
openPostDialog(media, -1)
}
override fun onProfilePicClick(media: Media) {
navigateToProfile(media?.user?.username)
navigateToProfile(media.user?.username)
}
override fun onNameClick(media: Media) {
navigateToProfile(media?.user?.username)
navigateToProfile(media.user?.username)
}
override fun onLocationClick(media: Media?) {
@ -390,6 +391,7 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall
}
override fun onDestroyView() {
mainActivity.resetToolbar(this)
super.onDestroyView()
setupPostsDone = false
}
@ -432,6 +434,7 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall
}
private fun init() {
mainActivity.setToolbar(binding.toolbar, this)
binding.swipeRefreshLayout.setOnRefreshListener(this)
disableDm = !isNavRootInCurrentTabs("direct_messages_nav_graph")
setupHighlights()
@ -468,7 +471,6 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall
context?.let { ctx -> Toast.makeText(ctx, R.string.error_loading_profile, Toast.LENGTH_LONG).show() }
return@observe
}
binding.root.loadLayoutDescription(R.xml.header_list_scene)
setupFavChip(profile, currentUser)
setupFavButton(currentUser, profile)
setupSavedButton(currentUser, profile)
@ -541,6 +543,8 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall
private fun showPrivateAccountMessage() {
binding.header.mainFollowers.isClickable = false
binding.header.mainFollowing.isClickable = false
binding.privatePage.visibility = VISIBLE
binding.privatePage.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
binding.privatePage1.setImageResource(R.drawable.lock)
binding.privatePage2.setText(R.string.priv_acc)
binding.privatePage.visibility = VISIBLE
@ -548,7 +552,6 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall
binding.privatePage2.visibility = VISIBLE
binding.postsRecyclerView.visibility = GONE
binding.swipeRefreshLayout.isRefreshing = false
binding.root.getTransition(R.id.transition)?.setEnable(false)
}
private fun setupProfileContext(contextPair: Pair<String?, List<UserProfileContextLink>?>) {
@ -852,9 +855,11 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall
}
private fun showDefaultMessage() {
binding.root.loadLayoutDescription(R.xml.profile_fragment_no_acc_layout)
binding.privatePage1.visibility = View.VISIBLE
binding.privatePage2.visibility = View.VISIBLE
binding.header.root.visibility = GONE
binding.swipeRefreshLayout.visibility = GONE
binding.privatePage.visibility = VISIBLE
binding.privatePage1.visibility = VISIBLE
binding.privatePage2.visibility = VISIBLE
binding.privatePage1.setImageResource(R.drawable.ic_outline_info_24)
binding.privatePage2.setText(R.string.no_acc)
}
@ -883,13 +888,15 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall
.setFeedItemCallback(feedItemCallback)
.setSelectionModeCallback(selectionModeCallback)
.init()
binding.postsRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val canScrollVertically = recyclerView.canScrollVertically(-1)
binding.root.getTransition(R.id.transition)?.setEnable(!canScrollVertically)
}
})
// binding.postsRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
// override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
// super.onScrolled(recyclerView, dx, dy)
// val canScrollVertically = recyclerView.canScrollVertically(-1)
// if (!canScrollVertically) {
// (binding.collapsingToolbarLayout.layoutParams as AppBarLayout.LayoutParams).scrollFlags = 0
// }
// }
// })
setupPostsDone = true
}

View File

@ -1,33 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
app:layoutDescription="@xml/header_list_scene">
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/header"
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/toolbarColor"
android:clipToPadding="false"
android:orientation="horizontal"
app:layout_constraintBottom_toTopOf="@id/feed_swipe_refresh_layout"
app:layout_constraintTop_toTopOf="parent"
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_highlight" />
android:layout_height="wrap_content">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:titleEnabled="false">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize"
android:background="?attr/toolbarColor"
android:clipToPadding="false"
android:orientation="horizontal"
app:layout_constraintBottom_toTopOf="@id/feed_swipe_refresh_layout"
app:layout_constraintTop_toTopOf="parent"
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_highlight" />
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/toolbarColor"
app:layout_collapseMode="pin"
app:title="@string/feed" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/feed_swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="?attr/actionBarSize"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/header">
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<awais.instagrabber.customviews.PostsRecyclerView
android:id="@+id/feed_recycler_view"
@ -36,4 +55,4 @@
android:clipToPadding="false"
tools:listitem="@layout/item_feed_grid" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.motion.widget.MotionLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,27 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
app:layoutDescription="@xml/header_list_scene">
android:layout_height="match_parent">
<include
android:id="@+id/header"
layout="@layout/layout_hashtag_details"
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/swipe_refresh_layout"
app:layout_constraintTop_toTopOf="parent" />
android:layout_height="wrap_content">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:titleEnabled="false">
<include
android:id="@+id/header"
layout="@layout/layout_hashtag_details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize" />
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/toolbarColor"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/header">
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<awais.instagrabber.customviews.PostsRecyclerView
android:id="@+id/posts"
@ -29,4 +45,4 @@
android:layout_height="match_parent"
android:clipToPadding="false" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.motion.widget.MotionLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,27 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
app:layoutDescription="@xml/header_list_scene">
android:background="?attr/colorSurface">
<include
android:id="@+id/header"
layout="@layout/layout_location_details"
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/swipe_refresh_layout"
app:layout_constraintTop_toTopOf="parent" />
android:layout_height="wrap_content">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:titleEnabled="false">
<include
android:id="@+id/header"
layout="@layout/layout_location_details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize" />
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/toolbarColor"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/header">
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<awais.instagrabber.customviews.PostsRecyclerView
android:id="@+id/posts"
@ -29,4 +46,4 @@
android:layout_height="match_parent"
android:clipToPadding="false" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.motion.widget.MotionLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,30 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
app:layoutDescription="@xml/header_list_scene"
tools:layoutDescription="@xml/profile_fragment_no_acc_layout">
android:background="?attr/colorSurface">
<include
android:id="@+id/header"
layout="@layout/layout_profile_details"
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/swipe_refresh_layout"
app:layout_constraintTop_toTopOf="parent" />
android:layout_height="wrap_content">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:titleEnabled="false">
<include
android:id="@+id/header"
layout="@layout/layout_profile_details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize" />
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/toolbarColor"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="?attr/actionBarSize"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/header">
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<awais.instagrabber.customviews.PostsRecyclerView
android:id="@+id/posts_recycler_view"
@ -37,11 +53,12 @@
<LinearLayout
android:id="@+id/privatePage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="top"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:visibility="visible">
<androidx.appcompat.widget.AppCompatImageView
@ -49,17 +66,17 @@
android:layout_width="@dimen/private_page_size"
android:layout_height="@dimen/private_page_size"
android:visibility="gone"
tools:visibility="visible"
app:srcCompat="@drawable/lock" />
app:srcCompat="@drawable/lock"
tools:visibility="visible" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/privatePage2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:visibility="gone"
tools:visibility="visible"
android:text="@string/priv_acc"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:visibility="gone"
tools:visibility="visible" />
</LinearLayout>
</androidx.constraintlayout.motion.widget.MotionLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?toolbarColor">
android:background="?colorSurface">
<awais.instagrabber.customviews.CircularImageView
android:id="@+id/mainProfileImage"

View File

@ -1,39 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/header"
android:layout_width="0dp"
android:layout_height="wrap_content"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/privatePage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/private_page_margins"
android:visibility="visible"
motion:layout_constraintTop_toBottomOf="@+id/header" />
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/header"
android:layout_width="0dp"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toTopOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent" />
</ConstraintSet>
<Transition
android:id="@+id/transition"
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start">
<OnSwipe
motion:dragDirection="dragUp"
motion:onTouchUp="stop"
motion:touchAnchorId="@+id/header"
motion:touchAnchorSide="bottom" />
</Transition>
</MotionScene>

View File

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/header"
android:visibility="gone" />
<Constraint
android:id="@+id/privatePage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible" />
<Constraint
android:id="@+id/swipe_refresh_layout"
android:visibility="gone" />
</ConstraintSet>
<ConstraintSet
android:id="@+id/end"
motion:deriveConstraintsFrom="@id/start">
<Constraint android:id="@+id/header" />
<Constraint android:id="@+id/privatePage" />
<Constraint android:id="@+id/swipe_refresh_layout" />
</ConstraintSet>
<Transition
android:id="@+id/transition"
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start" />
</MotionScene>