shamylzakariya / stickyheaders Goto Github PK
View Code? Open in Web Editor NEWAdapter and LayoutManager for Android RecyclerView which enables sticky header positioning.
License: MIT License
Adapter and LayoutManager for Android RecyclerView which enables sticky header positioning.
License: MIT License
hi,
is it possible to implement different types of view for item row ?
i tried to do so according to the adapter functions but i found it not really possible.
if there is a way please share
thank you for your time !
I added StickyheaderLayoutManager. It works well. But when I use scrollToPosition(int position) of this layout manager, it doesn't work well. How should I use scrollToPosition function?
What is position on recycler view of stickyheaders.
How can i say that in 1 section, the item will be displayed in 2 columns with the StickyHeaderLayoutManager ?
thanks in advance
Hello, is there any way to use onClickITem...?
Hi first of all thanks for nice library, Is there a way to show header at the end of each section?
When refreshing a data set, the suggested method call is notifyAllSectionsDataSetChanged()
.
I would imagine this to clear all collapsed states, ensuring that each section is no longer collapsed. This is not the case, as can be seen in the example app's 'Collapsing Headers' demo. Try collapsing a section, then hit 'Reload' from the menu. The header view's state is restored to appear not collapsed, but the items remain hidden.
I believe this is due to the ordering of method calls:
public void notifyAllSectionsDataSetChanged() {
buildSectionIndex();
notifyDataSetChanged();
collapsedSections.clear();
selectionStateBySection.clear();
}
should rather be:
public void notifyAllSectionsDataSetChanged() {
collapsedSections.clear();
selectionStateBySection.clear();
buildSectionIndex();
notifyDataSetChanged();
}
because buildSectionIndex()
uses isSectionCollapsed(s)
(which checks the collapsedSections
map) to determine section length
and numberOfItems
.
I'm happy to make a PR, but thought I would just check to see if this is the intended behavior?
I am trying to set header for every item but getting crash.
Attempt to invoke virtual method 'int org.zakariya.stickyheaders.SectioningAdapter.getItemViewType(int)' on a null object reference at org.zakariya.stickyheaders.StickyHeaderLayoutManager.getViewType(StickyHeaderLayoutManager.java:590)
public class AdapterTimeline extends SectioningAdapter {
public ArrayList<Video> results;
private LeadActionView.onClickListener listener;
public AdapterTimeline(ArrayList<Video> results) {
this.results = results;
}
@Override
public ItemViewHolder onCreateItemViewHolder(ViewGroup parent) {
return new ItemHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view, parent, false), parent.getContext(), listener);
}
@Override
public HeaderViewHolder onCreateHeaderViewHolder(ViewGroup parent) {
return new HeaderHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.header_view_timeline, parent, false), parent.getContext());
}
@Override
public void onBindHeaderViewHolder(HeaderViewHolder holder, int position) {
super.onBindHeaderViewHolder(holder, position);
if (results.size() == 0)
return;
Video item = results.get(position);
HeaderHolder vh = (HeaderHolder) holder;
vh.itemContainerView.setTag(item);
vh.profileImage.setTag(item.owner.uuid);
GlideLoader(vh.profileImage, item.owner.avatar_url_small);
vh.username.setText(item.owner.username);
vh.date.setText(DateUtils.parse(item.created_at, item.publish_date));
}
@Override
public void onBindItemViewHolder(ItemViewHolder holder, int sectionIndex, int position) {
super.onBindItemViewHolder(holder, sectionIndex, position);
if (results.size() == 0)
return;
Video item = results.get(position);
final ItemHolder vh = (ItemHolder) holder;
GlideLoader(vh.placeHolder, item.thumbnail_small_url);
vh.actionView.setItem(item, position);
vh.explain.setText(item.description);
vh.placeHolder.setTag(item.video_url);
if (item.video_url == null)
vh.imageNotYet.setVisibility(View.VISIBLE);
else
vh.imageNotYet.setVisibility(View.GONE);
vh.placeHolder.setVisibility(View.VISIBLE);
vh.scalableView.setVisibility(View.GONE);
vh.setItem(item);
HashTagHelper.Creator.create(vh.getContext().getResources().getColor(android.R.color.black), new HashTagHelper.OnHashTagClickListener() {
@Override
public void onHashTagClicked(String hashTag) {
vh.getContext().startActivity(new Intent(vh.getContext(), ActivityHashTag.class).putExtra(Common.HASH_TAG, hashTag));
}
}).handle(vh.explain);
}
@Override
public int getNumberOfSections() {
return (null != results ? results.size() : 0);
}
@Override
public int getNumberOfItemsInSection(int sectionIndex) {
return 1;
}
@Override
public boolean doesSectionHaveHeader(int sectionIndex) {
return true;
}
@Override
public boolean doesSectionHaveFooter(int sectionIndex) {
return false;
}
@Override
public void onViewAttachedToWindow(ViewHolder holder) {
super.onViewAttachedToWindow(holder);
// ItemHolder itemHolder = (ItemHolder) holder;
// itemHolder.scalableView.finish();
}
public class HeaderHolder extends SectioningAdapter.HeaderViewHolder implements View.OnClickListener {
final Context context;
LeadTextView date;
CircleImageView profileImage;
LeadTextView username;
LinearLayout itemContainerView;
public HeaderHolder(View itemView, Context context) {
super(itemView);
this.context = context;
itemContainerView = (LinearLayout) itemView.findViewById(R.id.item_view_container);
profileImage = (CircleImageView) itemView.findViewById(R.id.profile_image_timeline);
profileImage.setOnClickListener(this);
username = (LeadTextView) itemView.findViewById(R.id.user_name);
date = (LeadTextView) itemView.findViewById(R.id.post_date);
}
public Context getContext() {
return context;
}
@Override
public void onClick(View v) {
context.startActivity(new Intent(context, ActivityProfile.class).putExtra(ActivityProfile.PROFILE_UUID, ((String) v.getTag())));
}
}
public class ItemHolder extends SectioningAdapter.ItemViewHolder implements View.OnClickListener {
final Context context;
LeadActionView actionView;
SquareImageView placeHolder;
LeadTextView explain;
ScalableView scalableView;
ImageView mediaPlayer;
AnimationSet animationSet;
CircleImageView imageNotYet;
private Video item;
public ItemHolder(View itemView, Context context, LeadActionView.onClickListener listener) {
super(itemView);
this.context = context;
scalableView = (ScalableView) itemView.findViewById(R.id.scalableVideoView);
actionView = (LeadActionView) itemView.findViewById(R.id.actionView);
actionView.setOnClickListener(listener);
placeHolder = (SquareImageView) itemView.findViewById(R.id.place_holder);
imageNotYet = (CircleImageView) itemView.findViewById(R.id.image_not_yet);
placeHolder.setMaxHeight(itemView.getWidth());
placeHolder.setOnClickListener(this);
scalableView.setOnClickListener(this);
explain = (LeadTextView) itemView.findViewById(R.id.explain);
mediaPlayer = (ImageView) itemView.findViewById(R.id.button_media_player);
}
public Context getContext() {
return context;
}
@Override
public void onClick(View v) {
if (!scalableView.isPrepared() && item.video_url != null) {
animationSet = startAnimation(mediaPlayer);
scalableView.prepareAsync(item, new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
scalableView.setPrepared(true);
if (animationSet != null)
animationSet.cancel();
scalableView.post(new Runnable() {
@Override
public void run() {
scalableView.setVisibility(View.VISIBLE);
}
});
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
placeHolder.setVisibility(View.VISIBLE);
scalableView.setVisibility(View.GONE);
scalableView.finish();
}
});
scalableView.start();
placeHolder.setVisibility(View.GONE);
}
});
} else if (scalableView.isPlaying()) {
scalableView.pause();
} else if (scalableView.isPaused())
scalableView.start();
}
private AnimationSet startAnimation(ImageView mediaPlayer) {
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator());
fadeIn.setDuration(900);
Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator());
fadeOut.setStartOffset(1000);
fadeOut.setDuration(900);
AnimationSet animation = new AnimationSet(false);
animation.addAnimation(fadeIn);
animation.addAnimation(fadeOut);
mediaPlayer.setAnimation(animation);
mediaPlayer.startAnimation(animation);
return animation;
}
public void setItem(Video item) {
this.item = item;
}
public Video getItem() {
return item;
}
}
public void setListener(LeadActionView.onClickListener listener) {
this.listener = listener;
}
private void GlideLoader(final ImageView targetImageView, final String url) {
Glide.with(targetImageView.getContext())
.load(url)
.dontAnimate().into(targetImageView);
}
}
mAdapter = new AdapterTimeline(results);
mAdapter.setListener(this);
mLayoutManager = new StickyHeaderLayoutManager();
mRecyclerView.setLayoutManager(mLayoutManager);
mLayoutManager.setHeaderPositionChangedCallback(new StickyHeaderLayoutManager.HeaderPositionChangedCallback() {
@Override
public void onHeaderPositionChanged(int sectionIndex, View header, StickyHeaderLayoutManager.HeaderPosition oldPosition, StickyHeaderLayoutManager.HeaderPosition newPosition) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
boolean elevated = newPosition == StickyHeaderLayoutManager.HeaderPosition.STICKY;
header.setElevation(elevated ? 8 : 0);
}
}
});
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
Hello Zak, I really like your project and I'm interested in using it in a beautiful app am building. Anyway, I would like to request for a tutorial to be made on such a nice project. Finding it difficult to implement.
Thanks
Regards
First of all thanks for this lib, it's great!
I call the notifySectionItemChanged(sectionIndex, itemIndex)
method.
But had a problem is
java.lang.IllegalArgumentException: view is not a child, cannot hide android.widget.LinearLayout{21e33088 V.E...CL ......I. 0,612-600,683}
java.lang.IllegalArgumentException: Tmp detached view should be removed from RecyclerView before it can be recycled
Thanks in advance
How to click on the head of a child view?
Attaching StickyHeaderLayoutManager. View ist empty.
LinearLayoutManager the Views are rendered.
supportLibraryVersion = '23.4.0'
Hello @ShamylZakariya,
I was wondering if your LayoutManager could be included (and adapted) in my FlexibleAdapter library. Currently, I use a different solution to make headers sticky and clickable(!), it works fair enough, but it has some bugs due to different internal state of the default LayoutManagers especially when removing items.
Basically, I searched a way, since long time now, to create a custom LayoutManager, but never had time to work on it.
Adaptation is necessary to cover:
Let me know. Thanks,
Davide
We have the notifySectionFooterInserted
, notifySectionFooterRemoved
and notifySectionFooterChanged
.
But we don't have notifySectionHeaderInserted
, notifySectionHeaderRemoved
and notifySectionHeaderChanged
. Add them would be usefull.
The manifest merge task will fail when trying to set the application label if the project also set the label for the application.
Is the label really needed ? Couldn't find an easy way to avoid this as tools:replace does not seem to work.
Manifest merger failed : Attribute application@label value=(@string/APP_NAME) from AndroidManifest.xml:61:9-43
is also present at [org.zakariya.stickyheaders:stickyheaders:0.7.5] AndroidManifest.xml:12:9-41 value=(@string/app_name).
Suggestion: add 'tools:replace="android:label"' to element at AndroidManifest.xml:9:5-20:19 to override.
Hi , i am using your lib to sticky header , i have an Tab layout with 2 fragments and when i try to get data from database in background and try to set adpater in the fragment onCreateView() method , i am getting
java.lang.NullPointerException: Attempt to invoke virtual method 'int org.zakariya.stickyheaders.SectioningAdapter.getItemViewType(int)' on a null object reference
Process: competent.groove.swalok, PID: 28820
java.lang.NullPointerException: Attempt to invoke virtual method 'int org.zakariya.stickyheaders.SectioningAdapter.getItemViewType(int)' on a null object reference
at org.zakariya.stickyheaders.StickyHeaderLayoutManager.getViewType(StickyHeaderLayoutManager.java:707)
at org.zakariya.stickyheaders.StickyHeaderLayoutManager.onLayoutChildren(StickyHeaderLayoutManager.java:183)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3028)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2906)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3283)
at android.view.View.layout(View.java:15671)
at android.view.ViewGroup.layout(ViewGroup.java:5038)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15671)
at android.view.ViewGroup.layout(ViewGroup.java:5038)
at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1695)
at android.view.View.layout(View.java:15671)
at android.view.ViewGroup.layout(ViewGroup.java:5038)
at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:122)
at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1170)
at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:814)
at android.view.View.layout(View.java:15671)
at android.view.ViewGroup.layout(ViewGroup.java:5038)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15671)
at android.view.ViewGroup.layout(ViewGroup.java:5038)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15671)
at android.view.ViewGroup.layout(ViewGroup.java:5038)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15671)
at android.view.ViewGroup.layout(ViewGroup.java:5038)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15671)
at android.view.ViewGroup.layout(ViewGroup.java:5038)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15671)
at android.view.ViewGroup.layout(ViewGroup.java:5038)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2086)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1843)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:550)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
in my fragment
public class GetStartedFragment extends Fragment{
RecyclerView recyclerView; PersonalAdapter adapter; DatabaseHelper db; Database_Result db_insert; ProgressDialog pd ; SharedPreferences pref; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.personal_recyclerview, container, false); recyclerView = (RecyclerView) view.findViewById(R.id.personal_recycler); db = new DatabaseHelper(getActivity()); db_insert = new Database_Result(getActivity()); pref = PreferenceManager.getDefaultSharedPreferences(getActivity()); adapter = new PersonalAdapter(getActivity()); try { Thread thread = new Thread(){ @Override public void run() { super.run(); getActivity().runOnUiThread(new Runnable() { @Override public void run() { pd = ProgressDialog.show(getActivity(), "", "Loading messages...", true); pd.setCancelable(false); pd.setCanceledOnTouchOutside(false); //bar.setVisibility(View.VISIBLE); } }); if(db_insert.isTableExists(DatabaseHelper.CALL_TABLE) == false){ boolean table = db_insert.Create_CALL_TABLE(); Log.e("-----isTableExists Create_CALL_TABLE-----", "="+table); } final List<Sms> lstSms = getAllSms(); Log.e("==Personal Fragment=lstSms.size=====", "" + lstSms.size()); db_insert.Update_DB_FLAG(); db_insert.ADD_SMS_DATA(lstSms); try { db_insert.Insert_CALLOG_DATA(Call_LogUtils.logCallLog(getActivity())); } catch (Exception e) { e.printStackTrace(); } final List<Sms> SmsList = db_insert.getAllSMSList(); Log.e("=2==Personal=getAllSMSList===", "" + SmsList.size()); adapter.setSMS(SmsList); Log.e("==setSMS==getAllSMSList===", "" + SmsList.size()); getActivity().runOnUiThread(new Runnable() { @Override public void run() { recyclerView.setLayoutManager(new StickyHeaderLayoutManager()); recyclerView.setAdapter(adapter); pd.dismiss(); } }); } }; thread.start(); } catch (Exception e) { e.printStackTrace(); //bar.setVisibility(View.GONE); pd.dismiss(); } return view; }
Hi,
I added PagedLoadScrollListener after setting adapter to recyclerview to adapter.
Its works properly. But sometimes it does not work. I have to add PagedLoadScrollListener method after setting data to adapter.
Can you explain me why it works that way???
Hi
I use this lib to animate recyclerview : https://github.com/wasabeef/recyclerview-animators
but when i use SectioningAdapter i get this cast error :
Caused by: java.lang.ClassCastException: StickyHeaderLayoutManager must be used with a RecyclerView where the adapter is a kind of SectioningAdapter at org.zakariya.stickyheaders.StickyHeaderLayoutManager.onAdapterChanged(StickyHeaderLayoutManager.java:103) at android.support.v7.widget.RecyclerView.setAdapterInternal(RecyclerView.java:920) at android.support.v7.widget.RecyclerView.setAdapter(RecyclerView.java:877) at com.farahefaz.app.activities.SpecActivity.onCreate(SpecActivity.java:98) at android.app.Activity.performCreate(Activity.java:6285) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2524) at android.app.ActivityThread.access$900(ActivityThread.java:154) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1391) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:234) at android.app.ActivityThread.main(ActivityThread.java:5526) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
is there any other way to animate this StickyHeaders?
thanks in advance...
it's mentionned in the documentation tahat we should avoid th use of notifyItemChanged();
But the problem is there is no method in the library that allows us to pass the payloads
public final void notifyItemChanged(int position, Object payload)
Add DiffUtil support which will allow the ability to dispatch updates to a sectioned list.
https://medium.com/@nullthemall/diffutil-is-a-must-797502bc1149#.f33ov92og
hey, do you have any good idea about how to set All sections collapsed by default, currently all the sections are open by default.
Thanks!
when I use toggleSectionSelected(index) method select all the selection.
use traverseSelection() to delete the select, use notifySectionRemoved(index) refresh data, but this no work. only delete one section once.
I find you code in SectioningAdapter-->notifySectionRemoved() --> notifyAllSectionsDataSetChanged() --> selectionStateBySection.clear();
I guess the problem here.
Hello
I have List
object of FeedProvider
one feedprovider included List
of ViewModels. I want to get hashcode of one viewmodel object.
@Override
public long getItemId(int position) {
int sectionPostion = getSectionForAdapterPosition(position);
int positionItem = getPositionOfItemInSection(sectionPostion, position);
return feedDataProviders.get(sectionPostion - 1).getTileViewModelList().get(positionItem).hashCode();
}
But I got IndexOutOfBoundsException. What I am doing wrong?
It seems only support 4 types, TYPE_ITEM, TYPE_HEADER, TYPE_GHOST_HEADER or TYPE_FOOTER, so what could I do if my TYPE_ITEM has different sub types?
Hey,
I'm using a RecyclerView which contains CardViews and want to have StickyHeaders.
When using a LinearLayout in my RecyclerView, I can't get a Sticky Header only a header separating the cards (it's already a huge improvement actually). I'm guessing that this is correct behaviour with this layout.
But when using the provided layout it seems like the margin properties on my card have no effect and takes the whole screen.
It would be nice and convenient to include fast scroller. Any plan to have it soon?
Hi, is there a way to find out which item (that is not a section header) is currently being displayed on the screen?
Thanks in advance
I found one issue
@Override
public void onBindItemViewHolder(ItemViewHolder viewHolder, int sectionIndex, int itemIndex, int itemType) {
int sectionPosition = includeHeader ? sectionIndex - 1 : sectionIndex;
switch (itemType) {
case ITEM_HEADER:
...
break;
case ITEM_TILE:
initTile((FeedViewHolder) viewHolder, feedDataProviders.get(sectionPosition).getTileViewModelList().get(itemIndex), sectionPosition);
break;
case ITEM_FOOTER:
...
break;
default:
break;
}
}
Where feedDataProviders
is List<FeedDataProvider>
. FeedDataProvider
has list of custom objects TileViewModel
.
I got IndexOutOfBoundsException: Invalid index 0, size is 0
in line initTile()
because getTileViewModelList()
return empty list and itemIndex
is 0. I think if getNumberOfItemsInSection
return 0 then is should not called the onBindItemViewHolder
right?
@Override
public int getNumberOfItemsInSection(int sectionIndex) {
if((includeHeader && sectionIndex == 0) || (includeFooter && sectionIndex == getNumberOfSections() - 1)) {
return 1;
}
return feedDataProviders.get(includeHeader ? sectionIndex - 1 : sectionIndex).getTileViewModelList().size();
}
my xml layout is:
`<android.support.v4.widget.NestedScrollView
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"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:fillViewport="true"
tools:showIn="@layout/fragment_product_details">
<LinearLayout
android:id="@+id/content_product_details"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/lay_product_name"
app:cardElevation="1dp"
app:cardCornerRadius="0dp"
app:cardUseCompatPadding="false"
app:cardPreventCornerOverlap="false"
android:layout_marginBottom="2dp"
app:contentPadding="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center|left"
android:layout_weight="1">
<ImageButton
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_margin="8dp"
android:id="@+id/btn_share"
style="@style/Widget.AppCompat.Button.Borderless"
android:tint="@color/textSecondary"
app:srcCompat="@drawable/ic_share" />
<ImageButton
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_margin="8dp"
android:id="@+id/btn_favorite"
android:tint="@color/textSecondary"
style="@style/Widget.AppCompat.Button.Borderless"
app:srcCompat="@drawable/ic_favorite" />
</LinearLayout>
<com.iarcuschin.simpleratingbar.SimpleRatingBar
android:layout_width="wrap_content"
android:id="@+id/comment_rate"
app:srb_gravity="right"
app:srb_numberOfStars="5"
app:srb_stepSize="0.5"
app:srb_rating="0"
app:srb_starCornerRadius="0"
app:srb_starBorderWidth="1"
app:srb_borderColor="@color/divider_color"
app:srb_fillColor="@color/rate_fill_color"
android:layout_height="25dp" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorPrimary"
android:id="@+id/txt_product_name"
android:textSize="18dp"
android:layout_margin="8dp"
android:gravity="right"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorSecondary"
android:textSize="16sp"
android:id="@+id/txt_product_eng_name"
android:layout_margin="8dp"
android:gravity="right"/>
</LinearLayout>
</android.support.v7.widget.CardView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/title_btn_compare"
android:drawableLeft="@drawable/ic_compare"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:drawablePadding="10dp"
android:drawableTint="@color/textSecondary"
android:textColor="@color/textPrimary"
android:textSize="18sp"
android:id="@+id/btn_compare"
android:background="@drawable/btn_white_background"
android:layout_margin="8dp"/>
<Button
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/title_btn_product_comments"
android:drawableLeft="@drawable/ic_user_comments"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:drawablePadding="10dp"
android:drawableTint="@color/textSecondary"
android:textColor="@color/textPrimary"
android:textSize="18sp"
android:id="@+id/btn_comments"
android:background="@drawable/btn_white_background"
android:layout_margin="8dp"/>
</LinearLayout>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/lay_product_property"
app:cardElevation="1dp"
app:cardCornerRadius="0dp"
app:cardUseCompatPadding="true"
app:cardPreventCornerOverlap="false"
android:layout_marginBottom="2dp"
app:contentPadding="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/colorAccent"
android:id="@+id/txt_product_property"
android:text="@string/title_card_properties"
android:layout_margin="8dp"
android:gravity="right"/>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:id="@+id/rec_property"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>`
when i run the app recyclerView push top layers up outside the screen. How fix it?
java.lang.IllegalArgumentException: Scrapped or attached views may not be recycled. isScrap:false isAttached:true
at android.support.v7.widget.RecyclerView$Recycler.recycleViewHolderInternal(RecyclerView.java:5420)
at android.support.v7.widget.RecyclerView$Recycler.recycleView(RecyclerView.java:5364)
at android.support.v7.widget.RecyclerView$LayoutManager.removeAndRecycleView(RecyclerView.java:7698)
at org.zakariya.stickyheaders.StickyHeaderLayoutManager.recycleViewsOutOfBounds(StickyHeaderLayoutManager.java:624)
at org.zakariya.stickyheaders.StickyHeaderLayoutManager.scrollVerticallyBy(StickyHeaderLayoutManager.java:435)
at android.support.v7.widget.RecyclerView.scrollByInternal(RecyclerView.java:1640)
at android.support.v7.widget.RecyclerView.onTouchEvent(RecyclerView.java:2759)
at android.view.View.dispatchTouchEvent(View.java:10023)
When i want to scroll to a specific item in recyclerview with for example: mRecyclerview.scrollToPosition(20), the adapter list will not move, but start normally by the first item.
It also happens when i call scroll to position from your StickyLayoutManager.
Is there an way i can fix this issue?
Thanks in advance,
Yilzer
For endless scrolling ,StickyHeaderLayoutManager need findFirstVisibleItemPosition() method.
First of all thanks for this lib, it's great!
I don't know why this error occurs.
i just click on the item very quickly.
java.lang.NullPointerException at org.zakariya.stickyheaders.StickyHeaderLayoutManager.getViewViewHolder(StickyHeaderLayoutManager.java:599) at org.zakariya.stickyheaders.StickyHeaderLayoutManager.getViewAdapterPosition(StickyHeaderLayoutManager.java:603) at org.zakariya.stickyheaders.StickyHeaderLayoutManager.getBottommostChildView(StickyHeaderLayoutManager.java:447) at org.zakariya.stickyheaders.StickyHeaderLayoutManager.scrollVerticallyBy(StickyHeaderLayoutManager.java:274) at android.support.v7.widget.RecyclerView.scrollByInternal(RecyclerView.java:1529) at android.support.v7.widget.RecyclerView.onTouchEvent(RecyclerView.java:2486) at android.view.View.dispatchTouchEvent(View.java:7758) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2224) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2071) at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1518) at android.app.Activity.dispatchTouchEvent(Activity.java:2531) at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60) at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60)
Thanks in advance
I have a RecyclerView
with paddingBottom="16dp"
. When using StickyHeaderLayoutManager()
this padding is not there. If I switch to LinearLayoutManager()
it is correctly rendered.
Hi,
I'm developing an app where I use your library to show list of speficic documents. There are around 35 sections with 3 items in each of them. On HTC10 everything is fine, but on older phones such as Nexus 5, view is really choppy and I can see in console: Skipped 703 frames! The application may be doing too much work on its main thread. - almost all the time. When I sort the list to 5 sections with 15 items there is no such problem so I guess the problem is linked to too much section headers in one list.
Is there any way around it?
when i use this layout
`<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/top_line"
android:background="@color/gray_background">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_study_list"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>`
i can not swipe to refresh.
Since ItemViewHoldersetPositionInSection(positionInSection)
is only called in onBindViewHolder
the method ItemViewHolder.getPositionInSection()
returns wrong value when new items were inserted and SectionAdapter.notifySectionItemInserted
was called.
At the end of the method notifySectionFooterRemoved you have such piece of code:
notifyItemRemoved(section.adapterPosition + section.length - 1);
Suppose i have 24 items in my section, one header and one footer (total item count -27),. I want to remove my footer So after my call notifySectionFooterRemoved buildSectionIndex() will assign to section.length = 26 (24 (items)+ 2(header and ghost header)).
So notifyItemRemoved(25) called - and thats wrong, should be notifyItemRemoved(26)
hello.I just do like this:
in stickyHeaderLayoutManager.setHeaderPositionChangedCallback(...(){
//do left recyclerView smoothScrollToPosition(sectionIndex);
cause to Rv StickyHeader Sliding Caton.
})
can you tell me why?
Edge fading not working.. of RecyclerView
When set StickyHeaderLayoutManager as LayoutManager of RecyclerView
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:requiresFadingEdge="vertical"
android:fadingEdgeLength="50dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
/>
Because we remove the adapter on detach, we can't save after the view is detached (another library I'm using performs the save there, so it's not ideal for me).
A tweak which shouldn't adversely affect anything would be to updateFirstAdapterPosition() in onDetachedFromWindow before removing the adapter, and then we can wrap the call to update in onSaveInstanceState to only occur if the adapter is not null.
With headers A, B, and C:
Collapse header B. Scroll up so that C is the sticky header. Scroll back down to section A; the last item in the section now overlaps with header B.
Looks to be an issue with the layoutmanager class; I'll do some digging.
Can you please explain, How to use Load More functionality in this with sticky headers?
I am using the following link for load more feature:
https://guides.codepath.com/android/Endless-Scrolling-with-AdapterViews-and-RecyclerView
This works fine if I use LinearLayoutManager but that removes the Sticky header feature.
I want both the feature in one. Can you help me on this?
I need to use android:clipToPadding="false" for Sticky Header RecyclerView with some top padding. I am not able to get it working with StickyHeaderLayoutManager. It's working fine if used with LinearLayoutManager
First of all thanks for this lib, it's great!
I'm running into some performance issues when there are a large number of sections, my use case is a list of events, each section is labeled with a date, and the items are events for that date.
It starts off smooth as butter, but the farther down the list you go the slower it gets. I profiled it and it looks like updateHeaderPositions
takes more and more cycles the deeper down the list you go, to the point of being unusable at around the 500th section for my use case. I understand that number may vary depending on the implementation of the view holder methods, but nothing I'm doing is a long running blocking operation, I'm simply loading some data into a handful of views.
Is this a known issue with the library? If not, I am happy to provide my profiler .trace file if that would help
Hey @ShamylZakariya how u doing !recently I found an issue : when I collapse last section everything is disappeared, last section was sticky on top, and has 10 child items, when I collapse them everything is gone, here i changed this line :
https://github.com/ShamylZakariya/StickyHeaders/blob/master/stickyheaders/src/main/java/org/zakariya/stickyheaders/SectioningAdapter.java#L938
to offset += 1;
it is working fine? do u want me to make PR?
Hi, I need to use the LinearLayoutManager instead of StickyHeaderLayoutManager. But while using the LinearLayoutManager it's constantly crashing with the following error message:
E/AndroidRuntime: FATAL EXCEPTION: main java.lang.IllegalArgumentException: Scrapped or attached views may not be recycled. isScrap:false isAttached:true at android.support.v7.widget.RecyclerView$Recycler.recycleViewHolderInternal(RecyclerView.java:5659) at android.support.v7.widget.RecyclerView$Recycler.recycleView(RecyclerView.java:5603) at android.support.v7.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:277) at android.support.v7.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:324) at android.support.v7.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:337) at android.support.v7.widget.GapWorker.prefetch(GapWorker.java:344) at android.support.v7.widget.GapWorker.run(GapWorker.java:370) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6126) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
How can I fix this issue? Thank you very much in advance! :)
When we delete the last item, the animation is wrong, because all items move up, but they need to move down.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.