【问题标题】:Recycler View Scrolling messed up回收站视图滚动搞砸了
【发布时间】:2016-11-10 17:06:39
【问题描述】:

我正在按照本教程尝试异构回收器视图。 Heterogeneous Layouts 一切正常,除了我滚动 Recycler 视图的部分,布局显示不正确。我有 2 种布局,一种有文本,另一种有图像,滚动时我在文本部分留下了很多空白空间,让查看者感觉这里以前有一些图像。 我已经检查了在线链接,但没有解决问题。需要并感谢您的帮助。
这是我的代码

ComplexRecyclerViewAdapter

public class ComplexRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Object> items;
private final int STATUS = 0, IMAGE_STATUS = 1;
public ComplexRecyclerViewAdapter(List<Object> items) {
    this.items = items;
}
@Override
public int getItemCount() {
    return this.items.size();
}
@Override
public int getItemViewType(int position) {
    if (items.get(position) instanceof ArrayFeedItem) {
        return STATUS;
    } else if (items.get(position) instanceof ArrayFeedItemWithImage) {
        return IMAGE_STATUS;
    }
    return -1;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {

    RecyclerView.ViewHolder viewHolder;
    LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());

    if (viewType == STATUS){
        View v1 = inflater.inflate(R.layout.layout_viewholder1, viewGroup, false);
        viewHolder = new ViewHolder1(v1);
    }
    else if(viewType ==IMAGE_STATUS){
        View v2 = inflater.inflate(R.layout.layout_viewholder2, viewGroup, false);
        viewHolder = new ViewHolder2(v2);
    }
    else
    viewHolder=null;
    return viewHolder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {

    if (viewHolder.getItemViewType() == STATUS )
    {
        ViewHolder1 vh1 = (ViewHolder1) viewHolder;
        configureViewHolder1(vh1, position);
        vh1.setIsRecyclable(false);
    }
    else
    {
        ViewHolder2 vh2 = (ViewHolder2) viewHolder;
        configureViewHolder2(vh2, position);
        vh2.setIsRecyclable(false);
    }
}
private void configureViewHolder1(ViewHolder1 vh1, int position) {
    ArrayFeedItem item = (ArrayFeedItem) items.get(position);
    if (item != null) {
        vh1.getHolderImage().setImageResource(item.img);
        vh1.getHolderText().setText(item.txtname);
        vh1.getStatusMsg().setText(item.StatusMsg);
        vh1.getTimestamp().setText(item.Timestamp);
        vh1.getUrl().setText(item.URL);
    }
}

private void configureViewHolder2(ViewHolder2 vh2, int position) {
    ArrayFeedItemWithImage item = (ArrayFeedItemWithImage) items.get(position);
    if (item != null) {
        vh2.getHolderImage().setImageResource(item.img);
        vh2.getHolderText().setText(item.txtname);
        vh2.getStatusMsg().setText(item.StatusMsg);
        vh2.getTimestamp().setText(item.Timestamp);
        vh2.getUrl().setText(item.URL);
        vh2.getFeedImage().setImageResource(item.feedImage1);
    }
}
}

这就是我将适配器绑定到回收视图的方式。

家庭活动

list=(RecyclerView) findViewById(R.id.list);
adapter =new ComplexRecyclerViewAdapter(items);
list.setNestedScrollingEnabled(false);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
list.setLayoutManager(mLayoutManager);
list.setItemAnimator(new DefaultItemAnimator());
list.setAdapter(adapter);

ViewHolder1

public class ViewHolder1 extends RecyclerView.ViewHolder {
private ImageView Image;
private TextView Text,Timestamp,StatusMsg,Url;
public ViewHolder1(View itemView) {
    super(itemView);
    Image=(ImageView) itemView.findViewById(R.id.img);
    Text=(TextView)itemView.findViewById(R.id.txt);
    Timestamp=(TextView)itemView.findViewById(R.id.timestamp);
    StatusMsg=(TextView)itemView.findViewById(R.id.txtStatusMsg);
    Url=(TextView)itemView.findViewById(R.id.txtUrl);

}
public ImageView getHolderImage() {
    return Image;
}

public void setHolderImage(ImageView image) {
    this.Image = image;
}
public TextView getHolderText() {
    return Text;
}

public void setHolderText(TextView text) {
    this.Text = text;
}
public TextView getTimestamp() {
    return Timestamp;
}

public void setTimestamp(TextView timestamp) {
    this.Timestamp = timestamp;
}
public TextView getStatusMsg() {
    return StatusMsg;
}

public void setStatusMsg(TextView statusmsg) {
    this.StatusMsg = statusmsg;
}
public TextView getUrl() {
    return Url;
}

public void setUrl(TextView url) {
    this.Url = url;
}

}

layout_viewholder1

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/feed_bg"
android:orientation="vertical" >

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_marginLeft="@dimen/feed_item_margin"
    android:layout_marginRight="@dimen/feed_item_margin"
    android:layout_marginTop="@dimen/feed_item_margin"
    android:background="@drawable/bg_parent_rounded_corner"
    android:orientation="vertical"
    android:paddingBottom="@dimen/feed_item_padding_top_bottom"
    android:paddingTop="@dimen/feed_item_padding_top_bottom"
    android:id="@+id/layout1"
    >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:paddingLeft="@dimen/feed_item_padding_left_right"
        android:paddingRight="@dimen/feed_item_padding_left_right" >

        <ImageView
            android:id="@+id/img"
            android:layout_width="@dimen/feed_item_profile_pic"
            android:layout_height="@dimen/feed_item_profile_pic"
            android:scaleType="fitCenter" >
        </ImageView>

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:paddingLeft="@dimen/feed_item_profile_info_padd" >

            <TextView
                android:id="@+id/txt"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:textSize="@dimen/feed_item_profile_name"
                android:textStyle="bold"
                android:textColor="@color/black"/>

            <TextView
                android:id="@+id/timestamp"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/timestamp"
                android:textSize="@dimen/feed_item_timestamp"
                />
        </LinearLayout>
    </LinearLayout>

    <TextView
        android:id="@+id/txtStatusMsg"
        android:textColor="@color/black"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="5dp"
        android:paddingLeft="@dimen/feed_item_status_pad_left_right"
        android:paddingRight="@dimen/feed_item_status_pad_left_right"
        android:paddingTop="@dimen/feed_item_status_pad_top" />

    <TextView
        android:id="@+id/txtUrl"
        android:textColor="@color/black"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:linksClickable="true"
        android:paddingBottom="10dp"
        android:paddingLeft="@dimen/feed_item_status_pad_left_right"
        android:paddingRight="@dimen/feed_item_status_pad_left_right"
        android:textColorLink="@color/link" />
</LinearLayout>

</LinearLayout>

提前致谢。

【问题讨论】:

  • 发布您的 ViewHolder1ViewHolder2 代码,可能还有 xml 行。
  • 你需要setIsRecyclable(false)吗?你在构造函数中有两次这个this.items = items;,这不是你的问题的原因
  • @R.Zagórski ViewHolder1 和 ViewHolder2 非常相似,只是 ViewHolder2 中增加了一个图像视图。发布 ViewHolder1 的 xml 和代码,节省空间和时间,但我想那里没有问题。 :)
  • @Raghunandan 如果我将 Recyclable 设置为 false,我会在帖子中阅读它,这可能有助于解决问题,而不破坏视图。 P.s 感谢您指出构造函数中的错误,已更正。
  • @SundusBokhari 在这段代码中没有看到任何异常。尝试将LinearLayout 更改为wrap_content 而不是match_parentfill_parent

标签: android android-recyclerview adapter vertical-scrolling


【解决方案1】:

我遇到了这个问题,并意识到在我的情况下,我正在切换内部的视图可见性 public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {}

所以发生的事情是由于我的代码错误,有时某些视图被完全隐藏,因此没有被删除或回收。这导致了视图中的随机性。因此,如果您有一些更改视图可见性的代码,请将其删除并测试问题是否仍然存在。

【讨论】:

  • 我同意。就是这样。
【解决方案2】:

请注意这一点!

如果您的应用出于任何原因需要删除项目,并且您希望在 recyclerview 中查看已删除项目的过程,因此 setISRecyclable 为 false 不好,请检查!因此,对于每个人都想将其添加到适配器中,除了(那些出于任何原因不想回收某些物品的人)我有消息:

请考虑这一点,在 onBindViewHolder 中的适配器中,对于需要切换东西的情况每次对 onBindViewHolder 的调用都必须包含 load() 调用或 clear() 调用。

例如,如果您检查布尔值或 0-1 以将 RecyclerView 项目布局的某些部分设置为消失或可见,您应该在您的 If-Statement 块中考虑它们。

例如,在这个问题中,我在 configureViewHolder2 和 1 中看不到 else 块,所以可能会发生混乱的项目。

tnx 读取患者阅读器

【讨论】: