Ammar Githam
4 years ago
14 changed files with 513 additions and 34 deletions
-
6app/src/main/java/awais/instagrabber/MainHelper.java
-
2app/src/main/java/awais/instagrabber/activities/CommentsViewer.java
-
3app/src/main/java/awais/instagrabber/activities/MainActivity.java
-
2app/src/main/java/awais/instagrabber/activities/NotificationsViewer.java
-
4app/src/main/java/awais/instagrabber/activities/PostViewer.java
-
2app/src/main/java/awais/instagrabber/activities/ProfileViewer.java
-
14app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedItemViewHolder.java
-
2app/src/main/java/awais/instagrabber/customviews/RamboTextView.java
-
341app/src/main/java/awais/instagrabber/fragments/LocationFragment.java
-
2app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java
-
20app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java
-
5app/src/main/java/awais/instagrabber/interfaces/MentionClickListener.java
-
131app/src/main/res/layout/fragment_location.xml
-
13app/src/main/res/navigation/feed_nav_graph.xml
@ -0,0 +1,341 @@ |
|||||
|
package awais.instagrabber.fragments; |
||||
|
|
||||
|
import android.content.Intent; |
||||
|
import android.graphics.Typeface; |
||||
|
import android.net.Uri; |
||||
|
import android.os.AsyncTask; |
||||
|
import android.os.Bundle; |
||||
|
import android.text.SpannableStringBuilder; |
||||
|
import android.text.style.RelativeSizeSpan; |
||||
|
import android.text.style.StyleSpan; |
||||
|
import android.util.Log; |
||||
|
import android.view.ActionMode; |
||||
|
import android.view.LayoutInflater; |
||||
|
import android.view.MenuItem; |
||||
|
import android.view.View; |
||||
|
import android.view.ViewGroup; |
||||
|
import android.widget.TextView; |
||||
|
import android.widget.Toast; |
||||
|
|
||||
|
import androidx.activity.OnBackPressedCallback; |
||||
|
import androidx.activity.OnBackPressedDispatcher; |
||||
|
import androidx.annotation.NonNull; |
||||
|
import androidx.annotation.Nullable; |
||||
|
import androidx.appcompat.app.ActionBar; |
||||
|
import androidx.fragment.app.Fragment; |
||||
|
import androidx.lifecycle.ViewModelProvider; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.Arrays; |
||||
|
import java.util.Collections; |
||||
|
import java.util.List; |
||||
|
|
||||
|
import awais.instagrabber.R; |
||||
|
import awais.instagrabber.activities.MainActivity; |
||||
|
import awais.instagrabber.activities.PostViewer; |
||||
|
import awais.instagrabber.adapters.PostsAdapter; |
||||
|
import awais.instagrabber.asyncs.LocationFetcher; |
||||
|
import awais.instagrabber.asyncs.PostsFetcher; |
||||
|
import awais.instagrabber.asyncs.i.iStoryStatusFetcher; |
||||
|
import awais.instagrabber.customviews.PrimaryActionModeCallback; |
||||
|
import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager; |
||||
|
import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration; |
||||
|
import awais.instagrabber.customviews.helpers.NestedCoordinatorLayout; |
||||
|
import awais.instagrabber.customviews.helpers.RecyclerLazyLoader; |
||||
|
import awais.instagrabber.databinding.FragmentLocationBinding; |
||||
|
import awais.instagrabber.fragments.main.viewmodels.PostsViewModel; |
||||
|
import awais.instagrabber.interfaces.FetchListener; |
||||
|
import awais.instagrabber.models.LocationModel; |
||||
|
import awais.instagrabber.models.PostModel; |
||||
|
import awais.instagrabber.models.StoryModel; |
||||
|
import awais.instagrabber.models.enums.DownloadMethod; |
||||
|
import awais.instagrabber.models.enums.ItemGetType; |
||||
|
import awais.instagrabber.utils.Constants; |
||||
|
import awais.instagrabber.utils.Utils; |
||||
|
import awaisomereport.LogCollector; |
||||
|
|
||||
|
import static awais.instagrabber.utils.Utils.logCollector; |
||||
|
import static awais.instagrabber.utils.Utils.settingsHelper; |
||||
|
|
||||
|
public class LocationFragment extends Fragment { |
||||
|
private static final String TAG = "LocationFragment"; |
||||
|
|
||||
|
private MainActivity fragmentActivity; |
||||
|
private FragmentLocationBinding binding; |
||||
|
private NestedCoordinatorLayout root; |
||||
|
private boolean shouldRefresh = true; |
||||
|
private String location; |
||||
|
private LocationModel locationModel; |
||||
|
private PostsViewModel postsViewModel; |
||||
|
private PostsAdapter postsAdapter; |
||||
|
private ActionMode actionMode; |
||||
|
private boolean hasNextPage; |
||||
|
private String endCursor; |
||||
|
private AsyncTask<?, ?, ?> currentlyExecuting; |
||||
|
private boolean isLoggedIn; |
||||
|
private StoryModel[] storyModels; |
||||
|
|
||||
|
private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(false) { |
||||
|
@Override |
||||
|
public void handleOnBackPressed() { |
||||
|
if (postsAdapter == null) { |
||||
|
setEnabled(false); |
||||
|
remove(); |
||||
|
return; |
||||
|
} |
||||
|
postsAdapter.clearSelection(); |
||||
|
setEnabled(false); |
||||
|
remove(); |
||||
|
} |
||||
|
}; |
||||
|
private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback( |
||||
|
R.menu.multi_select_download_menu, |
||||
|
new PrimaryActionModeCallback.CallbacksHelper() { |
||||
|
@Override |
||||
|
public void onDestroy(final ActionMode mode) { |
||||
|
onBackPressedCallback.handleOnBackPressed(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) { |
||||
|
if (item.getItemId() == R.id.action_download) { |
||||
|
if (postsAdapter == null || location == null) { |
||||
|
return false; |
||||
|
} |
||||
|
Utils.batchDownload(requireContext(), |
||||
|
location, |
||||
|
DownloadMethod.DOWNLOAD_MAIN, |
||||
|
postsAdapter.getSelectedModels()); |
||||
|
checkAndResetAction(); |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
}); |
||||
|
private final FetchListener<PostModel[]> postsFetchListener = new FetchListener<PostModel[]>() { |
||||
|
@Override |
||||
|
public void onResult(final PostModel[] result) { |
||||
|
binding.swipeRefreshLayout.setRefreshing(false); |
||||
|
if (result == null) return; |
||||
|
binding.mainPosts.post(() -> binding.mainPosts.setVisibility(View.VISIBLE)); |
||||
|
final List<PostModel> postModels = postsViewModel.getList().getValue(); |
||||
|
final List<PostModel> finalList = postModels == null || postModels.isEmpty() ? new ArrayList<>() : new ArrayList<>(postModels); |
||||
|
finalList.addAll(Arrays.asList(result)); |
||||
|
postsViewModel.getList().postValue(finalList); |
||||
|
PostModel model = null; |
||||
|
if (result.length != 0) { |
||||
|
model = result[result.length - 1]; |
||||
|
} |
||||
|
if (model == null) return; |
||||
|
endCursor = model.getEndCursor(); |
||||
|
hasNextPage = model.hasNextPage(); |
||||
|
model.setPageCursor(false, null); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
@Override |
||||
|
public void onCreate(@Nullable final Bundle savedInstanceState) { |
||||
|
super.onCreate(savedInstanceState); |
||||
|
fragmentActivity = (MainActivity) requireActivity(); |
||||
|
} |
||||
|
|
||||
|
@Nullable |
||||
|
@Override |
||||
|
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) { |
||||
|
if (root != null) { |
||||
|
shouldRefresh = false; |
||||
|
return root; |
||||
|
} |
||||
|
binding = FragmentLocationBinding.inflate(inflater, container, false); |
||||
|
root = binding.getRoot(); |
||||
|
return root; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) { |
||||
|
if (!shouldRefresh) return; |
||||
|
init(); |
||||
|
shouldRefresh = false; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onDestroy() { |
||||
|
super.onDestroy(); |
||||
|
if (postsViewModel != null) { |
||||
|
postsViewModel.getList().postValue(Collections.emptyList()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void init() { |
||||
|
if (getArguments() == null) return; |
||||
|
final String cookie = settingsHelper.getString(Constants.COOKIE); |
||||
|
isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null; |
||||
|
final LocationFragmentArgs fragmentArgs = LocationFragmentArgs.fromBundle(getArguments()); |
||||
|
location = fragmentArgs.getLocation(); |
||||
|
setTitle(); |
||||
|
setupPosts(); |
||||
|
fetchLocationModel(); |
||||
|
} |
||||
|
|
||||
|
private void setupPosts() { |
||||
|
postsViewModel = new ViewModelProvider(this).get(PostsViewModel.class); |
||||
|
final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(requireContext(), Utils.convertDpToPx(110)); |
||||
|
binding.mainPosts.setLayoutManager(layoutManager); |
||||
|
binding.mainPosts.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4))); |
||||
|
postsAdapter = new PostsAdapter((postModel, position) -> { |
||||
|
if (postsAdapter.isSelecting()) { |
||||
|
if (actionMode == null) return; |
||||
|
final String title = getString(R.string.number_selected, postsAdapter.getSelectedModels().size()); |
||||
|
actionMode.setTitle(title); |
||||
|
return; |
||||
|
} |
||||
|
if (checkAndResetAction()) return; |
||||
|
startActivity(new Intent(requireContext(), PostViewer.class) |
||||
|
.putExtra(Constants.EXTRAS_INDEX, position) |
||||
|
.putExtra(Constants.EXTRAS_POST, postModel) |
||||
|
.putExtra(Constants.EXTRAS_USER, location) |
||||
|
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.MAIN_ITEMS)); |
||||
|
|
||||
|
}, (model, position) -> { |
||||
|
if (!postsAdapter.isSelecting()) { |
||||
|
checkAndResetAction(); |
||||
|
return true; |
||||
|
} |
||||
|
if (onBackPressedCallback.isEnabled()) { |
||||
|
return true; |
||||
|
} |
||||
|
final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity.getOnBackPressedDispatcher(); |
||||
|
onBackPressedCallback.setEnabled(true); |
||||
|
actionMode = fragmentActivity.startActionMode(multiSelectAction); |
||||
|
final String title = getString(R.string.number_selected, 1); |
||||
|
actionMode.setTitle(title); |
||||
|
onBackPressedDispatcher.addCallback(getViewLifecycleOwner(), onBackPressedCallback); |
||||
|
return true; |
||||
|
}); |
||||
|
postsViewModel.getList().observe(fragmentActivity, postsAdapter::submitList); |
||||
|
binding.mainPosts.setAdapter(postsAdapter); |
||||
|
final RecyclerLazyLoader lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> { |
||||
|
if (!hasNextPage) return; |
||||
|
binding.swipeRefreshLayout.setRefreshing(true); |
||||
|
fetchPosts(); |
||||
|
endCursor = null; |
||||
|
}); |
||||
|
binding.mainPosts.addOnScrollListener(lazyLoader); |
||||
|
} |
||||
|
|
||||
|
private void fetchLocationModel() { |
||||
|
stopCurrentExecutor(); |
||||
|
binding.swipeRefreshLayout.setRefreshing(true); |
||||
|
currentlyExecuting = new LocationFetcher(location.split("/")[0], result -> { |
||||
|
locationModel = result; |
||||
|
binding.swipeRefreshLayout.setRefreshing(false); |
||||
|
if (locationModel == null) { |
||||
|
Toast.makeText(requireContext(), R.string.error_loading_profile, Toast.LENGTH_SHORT).show(); |
||||
|
return; |
||||
|
} |
||||
|
setTitle(); |
||||
|
setupLocationDetails(); |
||||
|
fetchPosts(); |
||||
|
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
||||
|
} |
||||
|
|
||||
|
private void setupLocationDetails() { |
||||
|
final String locationId = locationModel.getId(); |
||||
|
binding.swipeRefreshLayout.setRefreshing(true); |
||||
|
if (isLoggedIn) { |
||||
|
new iStoryStatusFetcher(locationId.split("/")[0], null, true, false, false, false, stories -> { |
||||
|
storyModels = stories; |
||||
|
if (stories != null && stories.length > 0) { |
||||
|
binding.mainLocationImage.setStoriesBorder(); |
||||
|
} |
||||
|
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
||||
|
} |
||||
|
binding.mainLocationImage.setImageURI(locationModel.getSdProfilePic()); |
||||
|
final String postCount = String.valueOf(locationModel.getPostCount()); |
||||
|
final SpannableStringBuilder span = new SpannableStringBuilder(getString(R.string.main_posts_count, postCount)); |
||||
|
span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0); |
||||
|
span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0); |
||||
|
binding.mainLocPostCount.setText(span); |
||||
|
binding.mainLocPostCount.setVisibility(View.VISIBLE); |
||||
|
binding.locationFullName.setText(locationModel.getName()); |
||||
|
CharSequence biography = locationModel.getBio(); |
||||
|
binding.locationBiography.setCaptionIsExpandable(true); |
||||
|
binding.locationBiography.setCaptionIsExpanded(true); |
||||
|
|
||||
|
if (Utils.isEmpty(biography)) { |
||||
|
binding.locationBiography.setVisibility(View.GONE); |
||||
|
} else if (Utils.hasMentions(biography)) { |
||||
|
binding.locationBiography.setVisibility(View.VISIBLE); |
||||
|
biography = Utils.getMentionText(biography); |
||||
|
binding.locationBiography.setText(biography, TextView.BufferType.SPANNABLE); |
||||
|
// binding.locationBiography.setMentionClickListener(mentionClickListener); |
||||
|
} else { |
||||
|
binding.locationBiography.setVisibility(View.VISIBLE); |
||||
|
binding.locationBiography.setText(biography); |
||||
|
binding.locationBiography.setMentionClickListener(null); |
||||
|
} |
||||
|
|
||||
|
if (!locationModel.getGeo().startsWith("geo:0.0,0.0?z=17")) { |
||||
|
binding.btnMap.setVisibility(View.VISIBLE); |
||||
|
binding.btnMap.setOnClickListener(v -> { |
||||
|
final Intent intent = new Intent(Intent.ACTION_VIEW); |
||||
|
intent.setData(Uri.parse(locationModel.getGeo())); |
||||
|
startActivity(intent); |
||||
|
}); |
||||
|
} else { |
||||
|
binding.btnMap.setVisibility(View.GONE); |
||||
|
binding.btnMap.setOnClickListener(null); |
||||
|
} |
||||
|
|
||||
|
final String url = locationModel.getUrl(); |
||||
|
if (Utils.isEmpty(url)) { |
||||
|
binding.locationUrl.setVisibility(View.GONE); |
||||
|
} else if (!url.startsWith("http")) { |
||||
|
binding.locationUrl.setVisibility(View.VISIBLE); |
||||
|
binding.locationUrl.setText(Utils.getSpannableUrl("http://" + url)); |
||||
|
} else { |
||||
|
binding.locationUrl.setVisibility(View.VISIBLE); |
||||
|
binding.locationUrl.setText(Utils.getSpannableUrl(url)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void fetchPosts() { |
||||
|
stopCurrentExecutor(); |
||||
|
currentlyExecuting = new PostsFetcher(locationModel.getId(), endCursor, postsFetchListener) |
||||
|
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
||||
|
} |
||||
|
|
||||
|
public void stopCurrentExecutor() { |
||||
|
if (currentlyExecuting != null) { |
||||
|
try { |
||||
|
currentlyExecuting.cancel(true); |
||||
|
} catch (final Exception e) { |
||||
|
if (logCollector != null) |
||||
|
logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor"); |
||||
|
Log.e(TAG, "", e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void setTitle() { |
||||
|
final ActionBar actionBar = fragmentActivity.getSupportActionBar(); |
||||
|
if (actionBar != null && locationModel != null) { |
||||
|
actionBar.setTitle(locationModel.getName()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private boolean checkAndResetAction() { |
||||
|
if (!onBackPressedCallback.isEnabled() && actionMode == null) { |
||||
|
return false; |
||||
|
} |
||||
|
if (onBackPressedCallback.isEnabled()) { |
||||
|
onBackPressedCallback.setEnabled(false); |
||||
|
onBackPressedCallback.remove(); |
||||
|
} |
||||
|
if (actionMode != null) { |
||||
|
actionMode.finish(); |
||||
|
actionMode = null; |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
} |
@ -0,0 +1,131 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<awais.instagrabber.customviews.helpers.NestedCoordinatorLayout 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/colorOnPrimarySurface"> |
||||
|
|
||||
|
<com.google.android.material.appbar.AppBarLayout |
||||
|
android:id="@+id/appBarLayout" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="wrap_content" |
||||
|
android:background="?attr/colorOnPrimarySurface"> |
||||
|
|
||||
|
<com.google.android.material.appbar.CollapsingToolbarLayout |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="wrap_content" |
||||
|
app:layout_scrollFlags="scroll|exitUntilCollapsed"> |
||||
|
|
||||
|
<RelativeLayout |
||||
|
android:id="@+id/locInfoContainer" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="wrap_content" |
||||
|
android:animateLayoutChanges="true" |
||||
|
android:background="@null" |
||||
|
android:orientation="vertical" |
||||
|
android:paddingBottom="5dp"> |
||||
|
|
||||
|
<LinearLayout |
||||
|
android:id="@+id/locInfo" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="wrap_content" |
||||
|
android:orientation="horizontal" |
||||
|
android:padding="@dimen/profile_info_container_bottom_space"> |
||||
|
|
||||
|
<awais.instagrabber.customviews.CircularImageView |
||||
|
android:id="@+id/mainLocationImage" |
||||
|
android:layout_width="@dimen/profile_picture_size" |
||||
|
android:layout_height="@dimen/profile_picture_size" |
||||
|
android:background="?selectableItemBackgroundBorderless" |
||||
|
app:actualImageScaleType="fitCenter" /> |
||||
|
|
||||
|
<androidx.appcompat.widget.AppCompatTextView |
||||
|
android:id="@+id/mainLocPostCount" |
||||
|
android:layout_width="0dp" |
||||
|
android:layout_height="match_parent" |
||||
|
android:layout_marginStart="12dp" |
||||
|
android:layout_marginLeft="12dp" |
||||
|
android:layout_marginEnd="12dp" |
||||
|
android:layout_marginRight="12dp" |
||||
|
android:layout_weight="1" |
||||
|
android:gravity="center" |
||||
|
android:textAppearance="@style/TextAppearance.AppCompat" |
||||
|
android:textSize="15sp" |
||||
|
tools:text="35\nPosts" /> |
||||
|
|
||||
|
<androidx.appcompat.widget.AppCompatButton |
||||
|
android:id="@+id/btnMap" |
||||
|
android:layout_width="0dp" |
||||
|
android:layout_height="wrap_content" |
||||
|
android:layout_gravity="center_vertical" |
||||
|
android:layout_weight="2" |
||||
|
android:text="@string/map" |
||||
|
android:textColor="@color/btn_green_text_color" |
||||
|
android:textSize="20sp" |
||||
|
android:visibility="gone" |
||||
|
app:backgroundTint="@color/btn_green_background" /> |
||||
|
</LinearLayout> |
||||
|
|
||||
|
<androidx.appcompat.widget.AppCompatTextView |
||||
|
android:id="@+id/locationFullName" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="wrap_content" |
||||
|
android:layout_below="@id/locInfo" |
||||
|
android:ellipsize="marquee" |
||||
|
android:paddingStart="10dp" |
||||
|
android:paddingLeft="10dp" |
||||
|
android:paddingEnd="10dp" |
||||
|
android:paddingRight="10dp" |
||||
|
android:singleLine="true" |
||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body2" |
||||
|
android:textSize="16sp" |
||||
|
tools:text="OUR HOUSE" /> |
||||
|
|
||||
|
<awais.instagrabber.customviews.RamboTextView |
||||
|
android:id="@+id/locationBiography" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="wrap_content" |
||||
|
android:layout_below="@id/locationFullName" |
||||
|
android:background="?android:selectableItemBackground" |
||||
|
android:paddingStart="10dp" |
||||
|
android:paddingLeft="10dp" |
||||
|
android:paddingEnd="10dp" |
||||
|
android:paddingRight="10dp" |
||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1" |
||||
|
android:textSize="16sp" |
||||
|
android:visibility="gone" |
||||
|
tools:text="IN THE MIDDLE OF OUR STREET" /> |
||||
|
|
||||
|
<awais.instagrabber.customviews.RamboTextView |
||||
|
android:id="@+id/locationUrl" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="wrap_content" |
||||
|
android:layout_below="@id/locationBiography" |
||||
|
android:ellipsize="marquee" |
||||
|
android:paddingStart="10dp" |
||||
|
android:paddingLeft="10dp" |
||||
|
android:paddingEnd="10dp" |
||||
|
android:paddingRight="10dp" |
||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1" |
||||
|
android:textSize="16sp" |
||||
|
android:visibility="gone" |
||||
|
tools:text="https://austinhuang.me/" /> |
||||
|
</RelativeLayout> |
||||
|
</com.google.android.material.appbar.CollapsingToolbarLayout> |
||||
|
</com.google.android.material.appbar.AppBarLayout> |
||||
|
|
||||
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout |
||||
|
android:id="@+id/swipeRefreshLayout" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="match_parent" |
||||
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"> |
||||
|
|
||||
|
<androidx.recyclerview.widget.RecyclerView |
||||
|
android:id="@+id/mainPosts" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="match_parent" |
||||
|
android:clipToPadding="false" |
||||
|
tools:listitem="@layout/item_post" /> |
||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> |
||||
|
</awais.instagrabber.customviews.helpers.NestedCoordinatorLayout> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue