Recyclerview Not Scrolling Inside ViewPager - android

I have ViewPager2 with 3 Fragments and all has recyclerview but in Middle fragment recyclerview not scrolling if i try to touch recyclerview Items but it scroll smoothly if i touch right or left side of recycler as you can see in image.
View Pager Layout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabItemes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="center"
android:clipToPadding="true"
app:tabPaddingBottom="0dp"
app:tabPaddingEnd="0dp"
app:tabPaddingStart="0dp"
app:tabPaddingTop="0dp"
app:tabIndicatorHeight="0dp"
app:tabMode="fixed"
app:tabTextColor="#color/black"
app:tabSelectedTextColor="#color/primary"
app:tabIndicatorColor="#color/primary_light">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="About" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Media" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Connections" />
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/profileViewPager"
android:orientation="horizontal"
android:nestedScrollingEnabled="true"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
ViewPager2 Setup
userInfo_ViewPager = view.findViewById(R.id.profileViewPager);
userInfo_ViewPager.setOffscreenPageLimit(1);
userProfile_tabAdapter = new UserProfile_TabAdapter(getChildFragmentManager(), getLifecycle());
TabLayout tabLayout = view.findViewById(R.id.tabItemes);
Media Fragment Layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:isScrollContainer="true"
android:nestedScrollingEnabled="true"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<TextView
android:id="#+id/seeAllPhotos"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:textSize="12sp"
android:textStyle="bold"
android:text="See All"
/>
<com.elaxer.CustomClass.RotateLoading
android:id="#+id/rotateloading"
android:layout_width="80dp"
android:layout_height="80dp"
app:loading_color="#color/greenElaxer"
android:layout_gravity="center_horizontal|center_vertical"
app:loading_speed="11"
app:loading_width="5dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/userPhotos_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingEnd="10dp"
android:paddingStart="10dp"
tools:listitem="#layout/recycler_view_item_8"
tools:spanCount="5"
tools:layoutManager="GridLayoutManager" />
</LinearLayout>
Media Fragment
public class UserPhoto_fragment extends Fragment {
RecyclerView photosRecycler;
StaggeredGridLayoutManager layoutManager;
List<UserGrid> ImageList;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.userprofile_photos,container,false);
photosRecycler=view.findViewById(R.id.userPhotos_recycler);
seeAllPhotos = view.findViewById(R.id.seeAllPhotos);
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
ImageList=new ArrayList<>();
photosRecycler.addItemDecoration(new SpacesItemDecoration(16));
photosRecycler.setLayoutManager(layoutManager);
photosRecycler.setHasFixedSize(true);
adapter=new fetchPhoto_Adapter();
photosRecycler.setAdapter(adapter);
return view;
}
public class fetchPhoto_Adapter extends RecyclerView.Adapter<fetchPhoto_Adapter.ViewHolder>{
#NonNull
#Override
public fetchPhoto_Adapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
LayoutInflater inflater= (LayoutInflater) viewGroup.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.userprofile_photogallery,viewGroup,false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(fetchPhoto_Adapter.ViewHolder viewHolder, int i) {
UserGrid userImages = ImageList.get(i);
Glide.with(getActivity()).load(userImages.getWeb_URL()).into(viewHolder.image);
}
#Override
public int getItemCount() {
if (ImageList!=null && ImageList.size()>0){
return ImageList.size();
}else {
return 0;
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView image;
public ViewHolder(View itemView) {
super(itemView);
image = itemView.findViewById(R.id.UserProfile_photoThumb);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
image.setClipToOutline(true);
}
}
}
}
private final RecyclerView.OnItemTouchListener itemTouchListener = new RecyclerView.OnItemTouchListener() {
#Override
public boolean onInterceptTouchEvent(#NonNull RecyclerView rv, #NonNull MotionEvent e) {
int action = e.getAction();
Log.d(TAG, "onInterceptTouchEvent: "+action);
if (photosRecycler.canScrollVertically(1)){
if (action == MotionEvent.ACTION_MOVE){
photosRecycler.requestDisallowInterceptTouchEvent(true);
}
return false;
}else {
if (action == MotionEvent.ACTION_MOVE){
photosRecycler.requestDisallowInterceptTouchEvent(false);
photosRecycler.removeOnItemTouchListener(this);
}
return true;
}
}
#Override
public void onTouchEvent(#NonNull RecyclerView rv, #NonNull MotionEvent e) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
};
}
What i have already tried:
Nested ScrollView Enable/Disable in Recyclerview and Viewpager
RecyclerView.OnItemTouchListener Implementation to get recyclerview focus
Changed Fragment layout to constraintlayout.
I am running out of ideas and google search for solution. Can you suggest why my recyclerview is not working when i am trying to scroll by touching item and why its only working by both sides.
If i miss anything to post please let me know.

You need to remove these lines from Media Fragment Layout. I dont see any purpose for these.
android:isScrollContainer="true"
android:nestedScrollingEnabled="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"

Related

How do I set the click method on CARD VIEW in VIEW PAGER that using ArrayList<> to add the object?

I want to make clicklistener on cardview in my viewpager to startActivity(Intent)
i've tried to make clicklistener with position in setOnPageChangeListener method, but it does not work for me. Please help.
I want to set Intent on cardview.clicklistener, but i don't understand how to set by position, wheter using swith or if method
HERE MY ACTIVITY CODE :
public class Activity extends AppCompatActivity {
ViewPager viewPager;
Adapter adapter;
List<Model> models;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
CardView cardView = findViewById(R.id.cardViewLogin);
//ImageViewPager
models = new ArrayList<>();
models.add(new Model(R.drawable.m,"title", "desc"));
models.add(new Model(R.drawable.d,"title", "desc"));
models.add(new Model(R.drawable.a,"title", "desc"));
adapter = new Adapter(models,this);
viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(adapter);
viewPager.setPadding(130,0,130,0);
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(final int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(final int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
HERE MY ADAPTER CODE :
public class Adapter extends PagerAdapter {
private List<Model> models;
private LayoutInflater layoutInflater;
private Context context;
public Adapter(List<Model> models, Context context) {
this.models = models;
this.context = context;
}
#Override
public int getCount() {
return models.size();
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return view.equals(object);
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position)
{
layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.item,container,false);
ImageView imageView;
TextView title, desc;
imageView = view.findViewById(R.id.image);
title = view.findViewById(R.id.title);
desc = view.findViewById(R.id.desc);
imageView.setImageResource(models.get(position).getImage());
title.setText(models.get(position).getTitle());
desc.setText(models.get(position).getDesc());
container.addView(view,0);
return view;
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position,
#NonNull Object object) {
container.removeView((View)object);
}
HERE IS MY item.xml CODE :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical">
<androidx.cardview.widget.CardView
android:id="#+id/cardViewLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="20dp"
android:layout_margin="8dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="400dp">
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:src="#drawable/hourglass"
android:layout_height="200dp"
android:scaleType="centerInside"
android:layout_margin="10dp"/>
<TextView
android:id="#+id/title"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/image"
android:layout_marginTop="10dp"
android:layout_marginStart="16dp"
android:text="Title"
android:textSize="16sp"/>
<View
android:id="#+id/separator"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/cardview_shadow_start_color"
android:layout_margin="10dp"
android:layout_below="#+id/title"/>
<TextView
android:id="#+id/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/separator"
android:layout_marginTop="3dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="20dp"
android:maxLines="3"
android:drawablePadding="10dp"
android:ellipsize="end"
android:text="Description"
android:textSize="16sp"/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
HERE IS MY XML ACTIVITY LAYOUT CODE :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".UserLoginActivity">
<androidx.viewpager.widget.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:foregroundGravity="center"
android:layout_gravity="center"
android:overScrollMode="never"
android:clipToPadding="false">
</androidx.viewpager.widget.ViewPager>
</RelativeLayout>
onClick listener of cardView
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int pos=viewPager.getCurrentItem();
//used switch case
switch (pos) {
case 0:
//Do whatever you want
break;
case 1:
//Do whatever you want
break;
}
});

RecyclerView with StaggeredGridLayoutManager : variable number of columns and vertically scrollable

I want to show a list of strings, this list has to be vertically scrollable, and for each row a variable number of columns, this column with will depend on the string with. So it will be a grid vertically scrollable.
So Graphically I want to achieve this :
What I'm getting as a result is a horizontally scrollable list, with 3 rows and many columns, and what I want is the other way around : NOT horizontally scrollable (many columns, depending on the team name) but vertically scrollable.
In order to get this I've added a StaggeredGridLayoutManager to the recycler view with 3 span count (this might be wrong) and StaggeredGridLayoutManager.GAP_HANDLING_NONE to have as many columns as I can.
First question would be is it possible to achieve this with StaggeredGridLayoutManager? If yes how can I fix my problem? Any suggestion or idea is welcome.
Note that the item in the xml has a max width and then it ellipsizes
What I have is the following :
item_team.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="title"
type="String" />
</data>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/margin_small"
android:background="#drawable/club_background"
android:padding="#dimen/margin_general">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:ellipsize="end"
android:maxWidth="184dp"
android:gravity="center"
android:lines="1"
android:text="#{title}"
tools:text="Arsenal" />
</RelativeLayout>
TeamAdapter.java :
public class TeamAdapter extends ListAdapter<TeamItem, RecyclerView.ViewHolder> {
private LayoutInflater inflater;
private List<TeamItem> items = new ArrayList<>();
private static final DiffUtil.ItemCallback<TeamItem> ITEM_CALLBACK = new DiffUtil.ItemCallback<TeamItem>() {
#Override
public boolean areItemsTheSame(#NonNull TeamItem item1, #NonNull TeamItem item2) {
return item1.hashCode() == item2.hashCode();
}
#Override
public boolean areContentsTheSame(#NonNull TeamItem item1, #NonNull TeamItem item2) {
return item1.id.equalsIgnoreCase(item2.id);
}
};
private static final int VIEW_TYPE_TEAM = 0;
public TeamAdapter(Context context) {
super(ITEM_CALLBACK);
inflater = LayoutInflater.from(context);
}
public void setTeams(List<TeamItem> teams) {
items = teams;
notifyDataSetChanged();
}
public class TeamViewHolder extends RecyclerView.ViewHolder {
private final ItemTeamBinding binding;
TeamViewHolder(ItemTeamBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
public void bind(TeamItem team) {
binding.setTitle(team.name);
binding.executePendingBindings();
}
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
switch (viewType) {
case VIEW_TYPE_TEAM:
ItemTeamBinding itemTeamBinding = DataBindingUtil.inflate(inflater, R.layout.item_team, parent, false);
return new TeamItemViewHolder(itemTeamBinding);
}
throw new RuntimeException("There are invalid view types in TeamAdapter!");
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder viewHolder, final int position) {
switch (viewHolder.getItemViewType()) {
case VIEW_TYPE_TEAM:
((TeamItemViewHolder) viewHolder).bind(items.get(position));
break;
}
}
#Override
public int getItemCount() {
if (items != null && !items.isEmpty()) {
return items.size();
}
return super.getItemCount();
}
#Override
public int getItemViewType(int position) {
if (items != null && !items.isEmpty()) {
return VIEW_TYPE_TEAM;
}
return super.getItemViewType(position);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="activity"
type="com.ziniestro.base.activity.MainActivity" />
</data>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="#+id/tlbMain"
android:layout_width="match_parent"
android:layout_height="?android:actionBarSize"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:navigationIcon="#null">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/margin_large"
android:paddingTop="#dimen/margin_large"
android:paddingBottom="#dimen/margin_large"
android:text="#string/main_title" />
</androidx.appcompat.widget.Toolbar>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/margin_medium"
android:layout_marginTop="#dimen/margin_small"
android:layout_marginEnd="#dimen/margin_medium"
android:layout_marginBottom="#dimen/margin_xlarge"
android:background="#drawable/round_border_station_preference"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/imgMain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="#dimen/margin_medium"
android:layout_marginTop="#dimen/margin_medium"
android:layout_marginBottom="#dimen/margin_xlarge"
android:src="#drawable/ic_title" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginStart="#dimen/margin_large"
android:layout_marginTop="#dimen/margin_xlarge"
android:layout_toEndOf="#+id/imgMain"
android:gravity="center|start"
android:text="#string/main_title" />
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rcyMain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layoutAnimation="#anim/layout_anim_scale"
tools:listitem="#layout/item_team" />
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
public TeamAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setActivity(this);
binding.tlbMain.setTitle(Constants.EMPTY_STRING);
final Drawable backIcon = ContextCompat.getDrawable(this, R.drawable.ic_arrow_back);
backIcon.setColorFilter(ContextCompat.getColor(this, R.color.secondary) + 0xFF000000, PorterDuff.Mode.SRC_ATOP);
binding.tlbMain.setNavigationIcon(backIcon);
setSupportActionBar(binding.tlbMain);
adapter = new TeamAdapter(this);
if(MainApplication.getInstance().teamFeed.items !=null && !MainApplication.getInstance().teamFeed.items.isEmpty()) {
adapter.setTeams(MainApplication.getInstance().teamFeed.items);
StaggeredGridLayoutManager gridLayoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.GAP_HANDLING_NONE);
binding.rcyMain.setLayoutManager(gridLayoutManager);
binding.rcyMain.setHasFixedSize(true);
binding.rcyMain.setAdapter(adapter);
binding.rcyMain.setNestedScrollingEnabled(false);
}
}
}
I think that you want is the FlexboxLayoutManager https://github.com/google/flexbox-layout#flexboxlayoutmanager-within-recyclerview With the Wrap option in a Vertical Recyclerview.
The "Cells" that contain the Strings you want can vary in size and if it cannot fit a Cell on to the line it wraps it to the next line.

Fragment with multiple Recycler Views freezes UI

I am creating a Fragment that has 5 horizontal recycler views under a vertical Scroll View but each time this fragment needs to be loaded, the UI freezes for about a second.
I have created an Adapter that sets the Data from 2 different POJOs into the different Recycler Views. I have found out that the line from my code which seems to be causing the issue is the setLayoutManager() because once commented, the fragment loading does not freeze the UI. Apart from that I haven't been able to find out why is that happening when assigning the LayoutManger to the recycler view and what could I do to improve the fragment's performance.
Here is the fragment_home.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.entertainment.logicaldays.planetmovie.views.fragments.HomeFragment"
android:id="#+id/layout"
android:background="#color/colorPrimary">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scroll_view">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="200dp"
android:id="#+id/view_pager"
android:layout_marginBottom="5dp">
</android.support.v4.view.ViewPager>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recycler_popular_movies"
android:orientation="horizontal">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recycler_upcoming_movies"
android:orientation="horizontal">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recycler_top_rated_movies"
android:orientation="horizontal">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recycler_popular_tv_shows"
android:orientation="horizontal">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recycler_top_rated_tv_shows"
android:orientation="horizontal">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</ScrollView>
</FrameLayout>
Then I have the recycler_item.xml to bind to the Recycler Views:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/hover_values">
<ImageView
android:layout_width="wrap_content"
android:layout_height="150dp"
android:src="#drawable/ic_launcher_background"
android:layout_gravity="center|top"
android:id="#+id/recycler_image" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentTop="true"
android:layout_marginTop="20dp"
android:alpha="0"
android:id="#+id/poster_hover_image"
android:layout_centerHorizontal="true"
android:src="#drawable/star"/>
<TextView
android:layout_marginTop="5dp"
android:alpha="0"
android:id="#+id/poster_hover_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/poster_hover_image"
android:fontFamily="#font/theboldfont"
android:layout_centerHorizontal="true" />
</RelativeLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:scrollHorizontally="true"
android:minLines="2"
android:maxLines="2"
android:ellipsize="end"
android:id="#+id/recycler_title"/>
</LinearLayout>
</LinearLayout>
The Adapter which can bind 2 different POJOs into the Recycler Views:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{
public Object pojo;
public Context context;
public RecyclerViewAdapter(Context ctx, Object movies) {
this.pojo = movies;
this.context = ctx;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false);
final ValueAnimator animatorPosterTint = ValueAnimator.ofInt(0, 180);
final ValueAnimator animatorHoverOpacity = ValueAnimator.ofFloat(0, 1);
//When long-pressing the Movie
view.setOnLongClickListener(new LongClickOnPosterItemListerner(view, animatorPosterTint, animatorHoverOpacity));
//When releasing the touch on the movie
view.setOnTouchListener(new ReleasePosterItemListener(view, animatorPosterTint, animatorHoverOpacity));
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
if(pojo instanceof MovieList) {
holder.title.setText(((MovieList)pojo).results.get(position).title);
Glide.with(context)
.asBitmap()
.load(Utils.BASE_TMDB_POSTER_URL + ((MovieList)pojo).results.get(position).posterPath)
.into(holder.image);
holder.rating.setText(Float.toString(((MovieList)pojo).results.get(position).voteAverage));
}
else{
holder.title.setText(((TVList)pojo).results.get(position).name);
Glide.with(context)
.asBitmap()
.load(Utils.BASE_TMDB_POSTER_URL + ((TVList)pojo).results.get(position).posterPath)
.into(holder.image);
holder.rating.setText(Float.toString(((TVList)pojo).results.get(position).voteAverage));
}
}
#Override
public int getItemCount() {
int count = 0;
if(pojo instanceof MovieList && ((MovieList)pojo).results != null) {
if (((MovieList)pojo).results != null) {
count = ((MovieList)pojo).results.size();
}
}
else{
if (((TVList)pojo).results != null) {
count = ((TVList)pojo).results.size();
}
}
return count;
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView image;
TextView title;
TextView rating;
public ViewHolder(View itemView) {
super(itemView);
image = itemView.findViewById(R.id.recycler_image);
title = itemView.findViewById(R.id.recycler_title);
rating = itemView.findViewById(R.id.poster_hover_text);
}
}
}
And finally we have the HomeFragment.java
public class HomeFragment extends Fragment {
public MainActivity mainActivity;
#BindView(R.id.recycler_popular_movies)
RecyclerView recyclerPopularMovies;
#BindView(R.id.recycler_upcoming_movies)
RecyclerView recyclerUpcomingMovies;
#BindView(R.id.recycler_top_rated_movies)
RecyclerView recyclerTopRatedMovies;
#BindView(R.id.recycler_popular_tv_shows)
RecyclerView recyclerPopularTVShows;
#BindView(R.id.recycler_top_rated_tv_shows)
RecyclerView recyclerTopRatedTVShows;
#BindView(R.id.view_pager)
ViewPager viewPager;
LinkedHashMap<Utils.RequestsToLoad, Boolean> requestsToLoad;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mainActivity = (MainActivity) getActivity();
// Inflate the layout into the Fragment
View v = inflater.inflate(R.layout.fragment_home, container, false);
ButterKnife.bind(this, v);
startViewPager();
startRecyclerViews();
return v;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
private void startRecyclerViews(){
displayRecyclerView(recyclerPopularMovies, mainActivity.popularMovies);
displayRecyclerView(recyclerTopRatedMovies, mainActivity.upcomingMovies);
displayRecyclerView(recyclerUpcomingMovies, mainActivity.topRatedMovies);
displayRecyclerView(recyclerPopularTVShows, mainActivity.popularTVShow);
displayRecyclerView(recyclerTopRatedTVShows, mainActivity.topRatedTVShow);
}
private void displayRecyclerView(RecyclerView recyclerView, Object object){
LinearLayoutManager layoutManager = new LinearLayoutManager(mainActivity, LinearLayoutManager.HORIZONTAL, false);
final RecyclerViewAdapter adapter = new RecyclerViewAdapter(getActivity(), object);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(layoutManager);
}
private void startViewPager(){
SwipeAdapter swipeAdapter = new SwipeAdapter(getActivity(), mainActivity.upcomingMovies);
viewPager.setAdapter(swipeAdapter);
}
}
As said before, is there anything that could be causing that delay to load the fragment so that I can improve it?
Thanks in advance

How to scroll view pager content

I have a view pager with tab layout inside Collapsing Toolbar Layout. Each tab contains another view pager. My problem is when I scroll view pager's content, It does not. Its parent Collapsing Toolbar Layout scrolls when I try to scroll view pager's content. My activity's layout
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
android:background="#color/colorBackground"
android:id="#+id/layout_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="#style/MyTheme">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapse_toolbar"
android:layout_width="match_parent"
app:titleEnabled="false"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<!--android:layout_height="520dp"-->
<LinearLayout
android:id="#+id/ll_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:paddingTop="50dp"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/tabs_upper"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:tabIndicatorColor="#android:color/white"
android:background="#color/colorPrimary" />
<com.example.custom_view.custom_view_pager.MyWrapContentViewPager
android:id="#+id/pager_upper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="10dp"
android:scrollbars="vertical"/>
<!--android:layout_height="330dp"-->
<TextView
android:id="#+id/text_m"
android:layout_width="100dp"
android:layout_height="30dp"
android:text="More"
android:textColor="#color/color_red"
android:layout_marginTop="10dp"
android:layout_marginBottom="20dp"
android:layout_marginLeft="50dp"/>
</LinearLayout>
<include
android:id="#+id/toolbar"
layout="#layout/toolbar" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:tabIndicatorColor="#android:color/white"
android:background="#drawable/tab_bar_bg"
android:layout_gravity="bottom"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
android:layout_marginRight="#dimen/activity_horizontal_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
one of my fragments used in tab element:
public class TestFragment extends Fragment{
private ViewPager pagerSummary ;
private ArrayList<String> slider_image_list;
private TextViewPagerAdapter adapter;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_whole_book_new, null);
setUpSlideView(root);
return root;
}
private void setUpSlideView(ViewGroup view){
// method for initialisation
initSlider(view);
}
private void initSlider(ViewGroup view) {
pagerSummary = view.findViewById(R.id.pager_whole_book)
slider_image_list = new ArrayList<>();
slider_image_list.add(getActivity().getResources().getString(R.string.law_one));
slider_image_list.add(getActivity().getResources().getString(R.string.law_two);
adapter = new TextViewPagerAdapter(slider_image_list);
pagerSummary.setAdapter(adapter);
pagerSummary.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//Toast.makeText(getActivity(), "wholebook onPageScrolled", Toast.LENGTH_SHORT).show();
}
#Override
public void onPageSelected(int position) {
addBottomDots(position);
//Toast.makeText(getActivity(), "wholebook onPageSelected", Toast.LENGTH_SHORT).show();
}
#Override
public void onPageScrollStateChanged(int state) {
//Toast.makeText(getActivity(), "wholebook onPageScrollStateChanged", Toast.LENGTH_SHORT).show();
}
});
}
public class TextViewPagerAdapter extends ObjectAtPositionPagerAdapter {
private final ArrayList<String> strings;
TextView textView1 ;
public TextViewPagerAdapter(ArrayList<String> strings) {
super();
this.strings = strings;
}
#Override
public int getCount() {
return strings.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
#Override
public Object instantiateItemObject(ViewGroup container, int position) {
View view = View.inflate(container.getContext(), R.layout.test_item, null);
textView1 = view.findViewById(R.id.text_test);
textView1.setText(getActivity().getResources().getString(R.string.law_one)+
getActivity().getResources().getString(R.string.law_one)+
getActivity().getResources().getString(R.string.law_one)+
getActivity().getResources().getString(R.string.law_one)+
getActivity().getResources().getString(R.string.law_one));
container.addView(view);
return view;
}
#Override
public void destroyItemObject(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public CharSequence getPageTitle(int position) {
return "View" + position;
}
}
}
my fragment layout
<LinearLayout
android:id="#+id/ll_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.example.custom_view.custom_view_pager.WrapContentViewPager
android:id="#+id/pager_whole_book"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
also test_item.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scroll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:scrollbars="vertical">
<TextView
android:id="#+id/text_test"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /></ScrollView>
Take a look at NestedScrollView. Simply wrap content you want to be scrolled inside it.

How to add swipe functionality on Android CardView?

I have a single CardView that contains two TextViews and two ImageViews. I want to be able to swipe left and right to "dismiss". I actually want swipe right to send an Intent but that can be done later. For now, I want to be able to dismiss the CardView by swiping left or right. I also want the animation of swiping.
I tried using romannurik's SwipeDismissTouchListener but the CardView does not respond to swiping.
If anyone has a better solution than romannurik's custom listener, please share.
Here's my CardView layout:
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/generate"
map:cardCornerRadius="#dimen/_3sdp"
map:cardElevation="#dimen/_8sdp"
android:id="#+id/restaurantContainer">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/thumbnail"
android:layout_width="#dimen/_75sdp"
android:layout_height="#dimen/_75sdp"
android:layout_margin="#dimen/_5sdp" />
<ImageView
android:id="#+id/rating"
android:layout_width="#dimen/_75sdp"
android:layout_height="#dimen/_15sdp"
android:layout_margin="#dimen/_5sdp" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:id="#+id/name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/_5sdp"
android:gravity="top"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/categories"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="#dimen/_5sdp"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.google.android.gms.maps.MapView
android:id="#+id/mapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
map:cameraZoom="14"
map:liteMode="true"
map:mapType="normal" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
How I setup the SwipeDismissTouchListener:
RelativeLayout rootLayout;
CardView restaurantCardView;
...
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootLayout = (RelativeLayout) inflater.inflate(R.layout.fragment_main, container, false);
restaurantCardView = (CardView) rootLayout.findViewById(R.id.restaurantContainer);
restaurantCardView.setOnTouchListener(new SwipeDismissTouchListener(restaurantCardView, null, new SwipeDismissTouchListener.DismissCallbacks() {
#Override
public boolean canDismiss(Object token) {
Log.d("Chris", "canDismiss() called with: " + "token = [" + token + "]");
return true;
}
#Override
public void onDismiss(View view, Object token) {
Log.d("Chris", "onDismiss() called with: " + "view = [" + view + "], token = [" + token + "]");
}
}));
....
return rootLayout;
I am able to see the log from canDismiss(...) but not from onDismiss(...).
You'll have to put it inside RecyclerView (and your CardView as the only item there)
Then, use ItemTouchHelper.SimpleCallback to itemTouchHelper.attachToRecyclerView(recyclerView);
It will give you animations and in
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
}
you can specify particular action based on the swipe direction.
See full instruction here: Swipe to Dismiss for RecyclerView
Also, you'll have to disable vertical scroll in RecyclerView:
public class UnscrollableLinearLayoutManager extends LinearLayoutManager {
public UnscrollableLinearLayoutManager(Context context) {
super(context);
}
#Override
public boolean canScrollVertically() {
return false;
}
}
.....
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new UnscrollableLinearLayoutManager(this));
recyclerView.setAdapter(new RestaurantCardAdapter());
Otherwise - once you'll try to scroll up or down - you'd see RecyclerView's end-of-list animations.
Upd:
Here's RecyclerView.Adapter I used for test:
private class RestaurantCardAdapter extends RecyclerView.Adapter {
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new RestaurantViewHolder(new RestaurantCard(parent.getContext()));
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {}
#Override
public int getItemCount() {
return 1;
}
private class RestaurantViewHolder extends RecyclerView.ViewHolder {
public RestaurantViewHolder(View itemView) {
super(itemView);
}
}
}
RestaurantCard - is just a custom View (extends CardView in our case):
public class RestaurantCard extends CardView {
public RestaurantCard(Context context) {
super(context);
initialize(context);
}
public RestaurantCard(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(context);
}
private void initialize(Context context){
LayoutInflater.from(context).inflate(R.layout.card, this);
// ImageView imageView = (ImageView)getView.findViewById(...);
}
}

Categories

Resources