I'm using RecyclerView
along with StaggeredGridLayoutManager
for showing items with slightly different appearance. in items I use AspectRatioImageView
by JakeWharton (link) to maintain the imageView sizes before the image actually downloaded and shown by Picasso
. RV (RecyclerView) is populated by server data in infinite scroll pattern.
The problem is (as shown in included pictures), when scolling, some gaps appear on top and bottom of RV (in picture and sometimes items moves between the columns! (taking screenshot is hard :D)
Edit 2: A really important thing I forgot, is that I use the same layout for all of the items but regarding to adapter items some part of the layouts change their visibility to Gone
or vice versa.
My question: Why RV behave like this? Am I doing something wrong? Is this normal in RV?
The code is large and I don't know which part is useful to put here. If you can narrow down the cause I will put some code here.
EDIT: Code parts related to problem
xml:
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_texture"
android:padding="@dimen/padding_lvlhalf"
android:scrollbarStyle="outsideOverlay"/>
initializing view:
@Bind(R.id.recycler_view) RecyclerView mRecyclerView;
.
.
.
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(columnCount, direction));
mRecyclerView.setAdapter(
new RecyclerViewAdapter<>(ctx, new ViewFiller<Post, DashboardPostViewHolder>() {
@Override
public void fill(Post post, DashboardPostViewHolder holder) {
holder.fill(post);
}
@Override
public DashboardPostViewHolder getViewHolder(View view) {
return new DashboardPostViewHolder(view, receiverName);
}
@Override
public int getLayoutID() {
return R.layout.post_dashboard;
}
});)
My custom Adapter:
public RecyclerViewAdapter(Context context, ViewFiller filler) {
super();
this.filler = filler;
mLayoutInflater = LayoutInflater.from(context);
items = new ArrayList<>();
}
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View v = mLayoutInflater.inflate(filler.getLayoutID(), parent, false);
return filler.getViewHolder(v);
}
@Override
public void onBindViewHolder(BaseViewHolder holder, int position) {
filler.fill(getItem(position), holder);
}
@Override
public int getItemCount() {
return items.size();
}
@Override
public long getItemId(int position) {
return position;
}
public T getItem(int position){
return items.get(position);
}
public void addItem(int position, T item){
items.add(position, item);
notifyItemInserted(position);
}
public void addItem(T item){
items.add(item);
notifyItemInserted(items.size() - 1);
}
public void addItems(List<T> data){
int oldSize = items.size();
items.addAll(data);
notifyItemRangeInserted(oldSize, data.size());
}
public void addItemsToListHead(List<T> data){
items.addAll(0, data);
notifyItemRangeInserted(0, data.size());
}
public void resetData(List<T> data) {
this.items = data;
notifyDataSetChanged();
}
public void removeItem(int position){
items.remove(position);
notifyItemRemoved(position);
}
public void clear(){
this.items.clear();
notifyDataSetChanged();
}
public List<T> getItems(){
return items;
}
ViewFiller
interface
public interface ViewFiller<D, VH extends BaseViewHolder>{
void fill(D data, VH holder);
VH getViewHolder(View view);
@LayoutRes int getLayoutID();
}
Edit 2 (Cont.): My items xml and how I fill them..
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/margin_lvlhalf"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/post"
android:background="@color/poinila_background">
<TextView
android:layout_gravity="right"
android:text="@string/test_title"
android:layout_margin="@dimen/margin_lvl1"
style="@style/match_wrap.large_text.centered_right"
android:id="@+id/post_title"
android:visibility="gone"/>
<!--Post Image-->
<com.shaya.poinila.android.presentation.view.AspectRatioImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:contentDescription="@string/post_content_description"
android:id="@+id/post_image"
android:visibility="gone"
app:aspectRatioEnabled="true"
app:dominantMeasurement="width"
/>
<!--Content-->
<TextView
android:id="@+id/post_content"
style="@style/match_wrap.medium_text.three_line.end_ellipsize"
android:layout_margin="@dimen/margin_lvl1"/>
<!--android:text="@string/test_long"-->
<include layout="@layout/horizontal_line"
/>
<!--Post Author-->
<include android:id="@+id/post_author"
layout="@layout/circle_image_title_subtitle_reverse"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_lvl1"/>
<include layout="@layout/horizontal_line"
/>
<!--Post Stats (favs, comments, etc) -->
<include android:id="@+id/post_stats"
layout="@layout/stats"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_lvlhalf"
android:layout_marginBottom="@dimen/margin_lvlhalf"/>
<include layout="@layout/horizontal_line"/>
<!--Post Collection Info-->
<include layout="@layout/rounded_image_title_subtitle_reverse"
android:id="@+id/post_collection"/>
</LinearLayout>
</android.support.v7.widget.CardView>
PostViewHolder
class
public class PostViewHolder extends RecyclerView.ViewHolder
public void fill(Post post) {
if (post.type == PostType.IMAGE) {
postImage.setVisibility(View.VISIBLE);
postName.setVisibility(TextUtils.isEmpty(post.name) ? View.VISIBLE : View.GONE);
/*if (TextUtils.isEmpty(post.summary))
postContent.setVisibility(View.GONE);*/
}else{ //post.type == PostType.TEXT
postImage.setVisibility(View.GONE);
postName.setVisibility(View.VISIBLE);
postContent.setVisibility(View.VISIBLE);
}
// contetnt
if (TextUtils.isEmpty(post.summary) && !TextUtils.isEmpty(post.contentUrl)) {
DataRepository.getInstance().getPostContent(post.contentUrl, postContent);
}
else{
setText(postContent, post.summary);
}
.
.
.
}
}
Sorry for the long post!