Is there any way to get a RecyclerView with different spanCount for every row depends on how many items can fit in a row ? Meaning when there is no more width to fit new item, it will break into a new row.
I've attached a photo so you can see what I need.
If can't be done with RecyclerView, can it be done with TableLayout ? or a listView ?
You can do this with a Recycler View and a custom Layout Manager
This article might help
http://wiresareobsolete.com/2014/09/building-a-recyclerview-layoutmanager-part-1/
(sorry I don't have code to share. ive never done this, but i think its possible to do accomplish it this way)
The solution is FlexLayoutManager:
https://github.com/google/flexbox-layout
All you need to do is to add it in Gradle (1.1.0 for project using AndroidX artifacts, 1.0.0 other way):
implementation("com.google.android:flexbox:1.1.0")
And create it like this:
recycler.layoutManager = FlexboxLayoutManager(context, FlexDirection.ROW)
You can use ChipsLayoutManager also. https://github.com/BelooS/ChipsLayoutManager
implementation'com.beloo.widget:ChipsLayoutManager:0.3.7#aar'
allprojects {
repositories {
jcenter()
}
}
Related
I would like to make a horizontal RecyclerView like this: (ignore white circle in the centre)
Here the major things are scaling the center item and scaling the outgoing item as well. Can I have some reference point as how can I achieve such a view?
You can use below library for this I have already use this library for same
https://github.com/Azoft/CarouselLayoutManager
Add CarouselLayoutManager and set recycler view property as per below
CarouselLayoutManager layoutManager = new CarouselLayoutManager(CarouselLayoutManager.HORIZONTAL, true);
layoutManager.setPostLayoutListener(new CarouselZoomPostLayoutListener());
yourAdapter = new YourAdapter(arrayList, context);
binding.rvGame.setLayoutManager(layoutManager);
binding.rvGame.setHasFixedSize(true);
binding.rvGame.setAdapter(yourAdapter);
binding.rvGame.addOnScrollListener(new CenterScrollListener());
I hope this can help you!
Thank You.
I am working on a tag structure currently and to display that I have used Staggeredgrid layout manager of Recyclerview to get the required result as below image:
But when I used StaggeredGrid, It is providing result as below:
My code to display adapter in Recyclerview is as given below:
val staggeredGridLayoutManager = StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL)
rvTags.layoutManager = staggeredGridLayoutManager
rvTags.adapter = AllergyAdapter(tags)
On increasing the span count to 3, all the items are contracting.
I want that if "Peanut butter" is big enough then only 1 item should come in 1 row and if "neem, garlic and soy" can fit in 1 row, then it should fit.
Basically, I need a way to dynamic span count according to the content size.
Any help will be appreciated.
The suggested answer is not working because it is counting span count for whole of Recyclerview and Not particular row wise.
Either you can go with the dynamic spinning or what you can do is get the help of libraries.
Please check URL for tags libraries.
Tags Views
Here is a most suitable view: ChipView
With custom layouts : ChipView
And for dynamic column binding, you can use AsymmetricGridView.
URL : AsymmetricGridView
I came across such a requirement and ideally, a Flexbox should be a good option to try.
layoutManager=new StaggeredGridLayoutManager(4, LinearLayoutManager.HORIZONTAL);
Well, I have a RecyclerView with an adapter and everything works great. The items in the ArrayList dataset are being updated periodically. So the items and their elements as well as their position in the list change. This is achieved by simple sorting and manually calling these methods, whenever things happen:
// swapping two items
Collections.swap(items, i, j);
itemsAdapter.notifyItemMoved(i, j);
// adding a new one
itemAdapter.notifyItemInserted(items.size());
// when updating valus
itemAdapter.notifyItemChanged(i);
The latter of which, is the cause of my misery. Every time an item is updated, a little "blink" animation is triggered.
I found a couple of solutions for this:
// disabling all animations
recyclerView.getItemAnimator().setSupportsChangeAnimations(false);
// or
// setting the animation duration to zero,
recyclerView.getItemAnimator().setChangeDuration(0);
But both of these kill the animations when items move (being swapped). I just want to override the one animation and keep all of this magic. Is there a way of doing this? And if it's overriding ItemAnimator, does anyone have a simple example?
Thanks in advance!
There is a dedicated method to disable just item changed animations:
((SimpleItemAnimator) myRecyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
Official docs.
Yes, I did.
First, get the source code of DefaultItemAnimator. Take the code and create a class named MyItemAnimator in your project. Then, set the ItemAnimator to a new instance of your modified MyItemAnimator, like so:
recyclerView.setItemAnimator(new MyItemAnimator());
Now, go in the new classes source code and locate the method
animateChangeImpl(final ChangeInfo changeInfo) { ... }
We simply have to locate the method calls changing alpha values. Find the following two lines and remove the .alpha(0) and .alpha(1)
oldViewAnim.alpha(0).setListener(new VpaListenerAdapter() { ... }
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).alpha(1).setListener(new VpaListenerAdapter() { ... }
like so
oldViewAnim.setListener(new VpaListenerAdapter() { ... }
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).setListener(new VpaListenerAdapter() { ... }
Try setting:
mRecyclerview.setItemAnimator(null);
Kotlin version of #Pablo A. MartÃnez answer:
(recyclerView.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
If you are only modifying the data of Recyclerview means no addition or deletion of item then you should add this line.
mRecyclerview.setHasFixedSize(true);
So that recyclerview will get to know there is no change in size after that you can apply
((SimpleItemAnimator) mRecyclerview.getItemAnimator()).setSupportsChangeAnimations(false);
So that animation will be disappear and code will work like charm :)
Slight variation on Alex's answer.
Instead of removing the alpha change altogether, I just reduced it. the only changes needed were:
//changed alpha from 0
ViewCompat.setAlpha(newHolder.itemView, 0.5f);
and
//changed alpha from 0
oldViewAnim.alpha(0.5f).setListener(new VpaListenerAdapter() {
In both cases, change the 0 to 0.5
This has the effect of removing the flicker associated with the alpha going completely to 0, but keeps the morphing qualities of the item change animation.
In my case the recyclerview took all the space below toolbar. All I did was changing the layout_height of recyclerview from wrap_content to match_parent and blinking disappeared.
The android material design documentation suggests adding an 8 dp padding at the top and bottom of a list, and I personally like the idea and want to implement it. I am using the new RecyclerView widget to accomplish the look of a simple list. The problem that I'm having is when I set the attributes: paddingTop and paddingBottom of my RecyclerView, the overscroll shadow which appears at the top and bottom of the list now has a padding too (and kind of looks bad and like an error). I've been reading that setting these attributes:
clipToPadding = false
scrollbarStyle = outsideOverlay
should do the trick for me, but it simply doesn't. The overscroll effect still begins with an 8 dp padding at the top and bottom of the screen and it really bugs me out. Am I doing something wrong here, or there is another solution for my problem? Any advice appreciated. Thx
Adding clipToPadding as false works on latest releases
android:clipToPadding="false"
I'm using recylerview version
compile 'com.android.support:recyclerview-v7:22.2.1'
This is a known bug, will be fixed when RecyclerView is released.
This method will give the padding to the last position view
public class MyAdapter extends RecyclerView.Adapter<VH>{
public int getItemType(int position){
if(arrayList.size()-1==position){
return ITEM_TYPE;
}
return 0;
}
public MyHolder onBindViewHolder(MyHolder holder,int position){
if(getItemViewType(position)==ITEM_TYPE){
holder.itemView.setPadding(0,0,0,10);
}
}
I'm trying to emulate a parallax effect when sliding through my fragments, I've read about beginFakeDrag and fakeDragBy but to be honest, I don't know even if it's the best approach to my problem.
Anyone has done something similar with the ViewPager or have a hint about how should I approach this?
Thank you
An easy way to do this without using a custom library is to implement ViewPager.PageTransformer
I created my layouts to use the same id for their background element. For my example all background images will use the id background
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/background"
android:src="#drawable/img12"
android:scaleType="fitXY"/>
Then when I go in to implement ViewPager.PageTransformer I can reference that image like so:
public class Transformer implements ViewPager.PageTransformer{
#Override
public void transformPage(View page, float position) {
if(position >= -1 && position <= 1){
page.findViewById(R.id.background).setTranslationX(-position * page.getWidth() / 2);
} else {
page.setAlpha(1);
}
}
}
Finally, I assign my ViewPager.PageTransformer to my ViewPager like so.
ViewPager pager = (ViewPager) findViewById(R.id.pager);
pager.setPageTransformer(false, new Transformer());
This question is a bit old, but I found it when I was trying to do exactly that...
I implemented my own solution, basically extending ViewPager and overriding onDraw.
You can find all the code with a simple example here
I know that it's a bit old but take a look to that https://github.com/xgc1986/ParallaxPagerLibrary
It not overrides the onDraw method, and the effect not only with images, it works with every kind of view
mPager.setPageTransformer(false, new ParallaxTransformer(R.id.parallaxContent));
R.id.paraallaxContent is the id of the View you want to have this effect
unless the other solutions, don't need any any concrete structure to work, and also is layout independant
demo: youtube
Maybe this library can help you:
https://github.com/garrapeta/ParallaxViewPager
You can take a look at this :
https://github.com/luxsypher/ParallaxViewPager
you can apply a parallax effect on any element of your view and gave them all different speed
This is a ViewPager subclass I wrote, pretty easy to use. You don't need to do anything different with it, just include the dependency and use it as a standard ViewPager. Available on GitHub.
This library is fully customizable in x and y directions and includes alpha effects:
https://github.com/prolificinteractive/ParallaxPager
Installation (as of v0.7, check README for updates):
Add as a Maven Central dependency with Gradle
Use a ParallaxContainer in layout XML instead of ViewPager
Create a layout XML file for each page (the x/y/alpha attributes can be set separately for each object moving in/out of the page)
There are a few copy/paste lines to add to onCreate of your Activity
Maybe this library could be useful:
https://github.com/matrixxun/ProductTour
?
it uses "ViewPager.PageTransformer" for making things move differently inside.