我有以下代码。
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<String> names = new ArrayList<>();
names.add("one");
names.add("two");
names.add("three");
names.add("four");
names.add("five");
names.add("six");
names.add("seven");
names.add("eight");
names.add("nine");
names.add("ten");
RecyclerView rv = (RecyclerView) findViewById(R.id.rv);
LinearLayoutManager llm = new LinearLayoutManager(this);
rv.setLayoutManager(llm);
RvAdapter adapter = new RvAdapter(names);
rv.setAdapter(adapter);
}
}
RvAdapter.java
public class RvAdapter extends RecyclerView.Adapter<RvAdapter.PersonViewHolder> {
public static final String TAG = RvAdapter.class.getSimpleName();
List<String> persons;
RvAdapter(List<String> persons) {
this.persons = persons;
}
@Override
public RvAdapter.PersonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
return new PersonViewHolder(v);
}
@Override
public void onBindViewHolder(RvAdapter.PersonViewHolder holder, int position) {
holder.name.setText(persons.get(position));
Log.d(TAG, "onBindViewHolder: " + position);
}
@Override
public int getItemCount() {
return persons.size();
}
public static class PersonViewHolder extends RecyclerView.ViewHolder {
CardView cv;
TextView name;
PersonViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.cv);
name = (TextView) itemView.findViewById(R.id.name);
}
}
}
activity_main.xml中
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="com.example.mrmayhem.myapplication.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
item.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="wrap_content"
android:padding="16dp">
<android.support.v7.widget.CardView
android:id="@+id/cv"
android:layout_width="match_parent"
android:layout_height="200dp">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</android.support.v7.widget.CardView>
</LinearLayout>
它运作良好和正确。当我滚动列表时,我在Logs中逐个接收来自Adapter的连续消息:&#34; onBindViewHolder:&#34; +位置。但接下来我的问题。当我尝试在RecyclerView
上方添加一些视图时,如下面的代码所示。适配器同时显示方法onBindViewHolder
的所有调用。通过下一个代码将RecyclerView
包裹在 activity_main.xml 中。
activity_main.xml(带标题)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="com.example.mrmayhem.myapplication.MainActivity">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="HEADER" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</RelativeLayout>
答案 0 :(得分:2)
RecyclerView是一个ListView。它只显示您当前可以看到的项目,在滚动时重复使用部分。
现在您将RecyclerView封装在LinearLayout
NestedScrollView
内,会发生什么?
NestedScrollView
需要知道LinearLayout
的尺寸才能处理滚动。
如果不知道RecyclerViews的总长度,LinearLayout
如何知道应该多长时间? 它没有。
因此,recyclerView完全膨胀,所有视图一次完成,所有这些都在一条长线上。没有回收,没有重复使用。这是你遇到的现象
现在LinearLayout
可以正确地告诉NestedScrollView
它的高度(TextView的总高度和所有 RecyclerView的项目)和{{1} }可以处理滚动。
这就是为什么嵌套滚动总是一个坏主意。如果可能,请尝试将NestedScrollView
作为项目移动到 RecyclerView中,然后摆脱包裹TextView
。
例如如下所示:Is there an addHeaderView equivalent for RecyclerView?
另一种选择是从滚动视图中删除recyclerview并将其放在下面。然而,标题不会滚动。
答案 1 :(得分:0)
除非您有充分的理由在层次结构中拥有NestedScrollView
,否则您可以使用下面的RecyclerView在此顶部使用此布局代码实现TextView:
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.mrmayhem.myapplication.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="HEADER" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>