【发布时间】:2015-09-09 13:32:45
【问题描述】:
我使用RecyclerView 和StaggeredGridLayoutManager 来显示外观略有不同的项目。在我使用 JakeWharton (link) 的 AspectRatioImageView 的项目中,在 Picasso 实际下载和显示图像之前保持 imageView 的大小。 RV(RecyclerView)由无限滚动模式的服务器数据填充。
问题是(如图所示),scolling时,RV顶部和底部出现一些间隙(在图片中,有时项目在列之间移动!(截图很难: D)
编辑 2: 我忘记了一件非常重要的事情,我对所有项目使用相同的布局,但关于适配器项目 某些部分布局将它们的可见性更改为 @ 987654330@,反之亦然。
我的问题: 为什么 RV 会这样?难道我做错了什么?这在 RV 中正常吗?
代码很大,不知道放在这里哪个部分有用。如果你能缩小原因,我会在这里放一些代码。
编辑:与问题相关的代码部分
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"/>
初始化视图:
@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;
}
});)
我的自定义适配器:
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接口
public interface ViewFiller<D, VH extends BaseViewHolder>{
void fill(D data, VH holder);
VH getViewHolder(View view);
@LayoutRes int getLayoutID();
}
编辑 2(续):我的项目 xml 以及我如何填充它们..
<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类
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);
}
.
.
.
}
}
抱歉,帖子太长了!
【问题讨论】:
-
你好.. 你解决了这个问题吗?我也有同样的问题。。谢谢。
-
@GennadiiSaprykin :不完全!但请记住 RV 使用有限数量的子视图并将它们重用于不同的项目(RV 适配器中的对象),因此在
onBindView中,您必须完全初始化(可见性、值、大小、状态等)子视图的部分和子视图从开始。抱歉英语不好,希望我足够清楚! -
是的,我想我在
onBindViewHolder中初始化了所有内容,尽管我仍然有差距。不过,这个 hack 对我有用:stackoverflow.com/questions/33126960/… 看起来很丑,但消除了所有的差距。