RecyclerView 23.2.x height = 0dp导致onBind调用所有项目并且scrollToPosition无法正常工作

时间:2016-03-17 15:59:07

标签: android android-linearlayout android-recyclerview

更新 我刚刚将支持库更新为23.3.0,这个问题似乎不再发生了。我想这是23.2.X版本中的一个错误。好吧,这不是我第一次花费数小时处理一个奇怪的问题,后来发现这是Android SDK的一个错误。 END UPDATE

在以下代码中,我将layout_height="0dp"layout_weight="1"设置为回收器视图,以使其填充线性布局的剩余空间。在我看来,由于layout_weight已设置,因此不需要layout_height,但省略该属性被视为错误,我在Stack Overflow上的其他问题中找到的示例建议使用“0dp”。

奇怪的是,如果我设置layout_height =“0dp”,则会立即为所有项目调用onBindViewHolder()。也就是说,调试输出就像

onBindViewHolder(0)
...
onBindViewHolder(99)

如果我设置layout_height =“1dp”,则仅在前几个项目中调用onBindViewHolder(),直到滚动为止。也就是说,调试输出就像

onBindViewHolder(0)
...
onBindViewHolder(8)

在RecyclerView版本23.1.1中不会发生这种情况,但在版本23.2.0和23.2.1(例如com.android.support:recyclerview-v7:23.2.1)中会发生这种情况,并且它也会使编程滚动无法正常工作。为什么会这样?在这种情况下,我应该使用“1dp”吗?

以下是整个源代码。

activity_main.xml中

<?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:orientation="horizontal"
>

<FrameLayout
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:background="@android:color/holo_green_dark"
    />

<View
    android:layout_width="1dp"
    android:layout_height="match_parent"
    android:background="#ff111111"/>

<LinearLayout
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="3"
    android:orientation="vertical">

    <FrameLayout
        android:background="@android:color/holo_orange_light"
        android:layout_width="match_parent"
        android:layout_height="50dp">

    </FrameLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/mylist"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_weight="1"
        >

    </android.support.v7.widget.RecyclerView>

    <FrameLayout
        android:background="@android:color/holo_blue_bright"
        android:layout_width="match_parent"
        android:layout_height="50dp">
    </FrameLayout>
</LinearLayout>

my_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:orientation="horizontal"
          android:layout_width="match_parent"
          android:clickable="true"
          android:focusable="true"
          android:id="@+id/itemRect"
          android:background="?android:attr/selectableItemBackground"
          android:layout_height="wrap_content">

<ImageView
    android:src="@android:drawable/ic_menu_camera"
    android:layout_width="48sp"
    android:layout_height="48sp"/>
<TextView
    tools:text="Hello world"
    android:id="@+id/name"
    android:gravity="center_vertical"
    android:layout_width="0dp"
    android:layout_weight="1"
    android:layout_height="48sp"/>

MainActivity.java

public class MainActivity extends AppCompatActivity
{
String TAG = this.getClass().getName();
RecyclerView mylist;
@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mylist = (RecyclerView)findViewById(R.id.mylist);

    ArrayList<String> source = new ArrayList<>();
    for(int i =0; i< 100; i++)
    {
        source.add("List item " + i);
    }

    LinearLayoutManager lay = new LinearLayoutManager(mylist.getContext());
    mylist.setLayoutManager(lay);
    MyAdapter adap = new MyAdapter(source);
    mylist.setAdapter(adap);
}


class MyViewHolder extends RecyclerView.ViewHolder
{
    TextView name;
    public MyViewHolder(View itemView)
    {
        super(itemView);
        name = (TextView) itemView.findViewById(R.id.name);
    }

    public void bind(String item)
    {
        name.setText(item);
    }
}
class MyAdapter extends RecyclerView.Adapter<MyViewHolder>
{
    List<String> items;
    public MyAdapter(List<String> items)
    {
        this.items = items;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_item, null);
        MyViewHolder vh = new MyViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position)
    {
        Log.d(TAG, "onBindViewHolder(" + position + ")");
        holder.bind(items.get(position));
    }

    @Override
    public int getItemCount()
    {
        return items.size();
    }
}

enter image description here

0 个答案:

没有答案