所以我需要一个水平的RecyclerView。但是,根据从后端返回的内容,其中的项目具有动态高度。
RecyclerView及其项目的高度为" wrap_content"
问题是如果RecyclerView中的第一个可见项很小,那么当用户滚动到较大的项目时,它们会显示为切断。
理想情况下,我们希望RecyclerView足够大以容纳组中的最大项目(但只有最大的现有项目...而不是假设最大的项目)。 RecyclerView动态改变其高度也是可以接受的。
我写了一个示例应用来说明问题。在这个应用程序中,我们有一个水平列表。前33个项目应显示1行文本,而下一个应显示3行文本,最后34个应显示2行。但是,它们都显示1行,因为RecyclerView的高度不会改变。
我尝试在onBindViewHolder()上的RecyclerView(以及TextView)上调用requestLayout(),但它似乎没有做任何事情。
MainActivity :
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAdapter = createAdapter();
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
mRecyclerView.setAdapter(mAdapter);
}
private RecyclerView.Adapter<ViewHolder> createAdapter() {
RecyclerView.Adapter adapter = new RecyclerView.Adapter<ViewHolder>() {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
if (position < 33) {
holder.mText.setText("1 line");
} else if (position > 66) {
holder.mText.setText("2 lines\n2 lines");
} else {
holder.mText.setText("3 lines\n3 lines\n3 lines");
}
}
@Override
public int getItemCount() {
return 100;
}
};
return adapter;
}
private static class ViewHolder extends RecyclerView.ViewHolder {
TextView mText;
public ViewHolder(View itemView) {
super(itemView);
mText = (TextView) itemView.findViewById(R.id.text);
}
}
}
activity_main.xml中:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#888888">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hi"
android:textSize="30sp" />
</LinearLayout>
答案 0 :(得分:1)
将您的recyclerView高度和宽度从wrap_content
更改为match_parent
,或者您也可以像android:layout_height="150dp"
那样给您的recyclerView固定高度
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#888888" />
</RelativeLayout>
或者您可以尝试
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="#888888" />
</RelativeLayout>
答案 1 :(得分:0)
我写了一个可以根据您的物品设置recyclerview的最大高度的类。 试试这个课程:
public class DynamicRecyclerViewHeight extends RecyclerView {
private int mMaxHeight;
public DynamicRecyclerViewHeight(@NonNull Context context) {
super(context);
}
public DynamicRecyclerViewHeight(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initialize(context, attrs);
}
public DynamicRecyclerViewHeight(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize(context, attrs);
}
private void initialize(Context context, AttributeSet attrs) {
TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.CustomRecyclerView);
mMaxHeight = arr.getLayoutDimension(R.styleable.CustomRecyclerView_maxHeight, mMaxHeight);
arr.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mMaxHeight > 0) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxHeight, MeasureSpec.AT_MOST);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void setmMaxHeight(int mMaxHeight) {
this.mMaxHeight = mMaxHeight;
invalidate();
}
}
您应该将以下行添加到attrs.xml文件中:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="DynamicRecyclerViewHeight">
<attr name="maxHeight" format="dimension" />
</declare-styleable>
</resources>
然后您可以使用此方法来设置maxHeight toyour recyclerView:
yourRecyclerView.setMaxHeight(yourHeight);
祝你好运。
答案 2 :(得分:0)
尝试添加你的 textView using System;
using System.Diagnostics;
using System.IO;
namespace testdir
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine($"Launched from {Environment.CurrentDirectory}");
Console.WriteLine($"Physical location {AppDomain.CurrentDomain.BaseDirectory}");
Console.WriteLine($"AppContext.BaseDir {AppContext.BaseDirectory}");
Console.WriteLine($"Runtime Call {Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)}");
}
}
当有多行时它会改变
答案 3 :(得分:0)
使用以下代码更改您的 item.xml 布局内容。 它将解决您的问题。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="160dp"
android:layout_height="match_parent"
android:background="#888888">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hi"
android:textSize="30sp" />
</LinearLayout>
答案 4 :(得分:0)
您可以使用 FlexboxLayoutManager Google 库解决此问题,方法是将 FlexDirection 定义为 FlexDirection.ROW 和 FlexWrap > 到 FlexWrap.NOWRAP 并且还在您的 BaseViewHolder 构造函数中为每个项目设置 FlexShrink 到 0.0f 以便能够水平滚动。可以在此处找到有关如何实现此目标的更多详细信息:Horizontal RecyclerView with dynamic item’s Height
答案 5 :(得分:-3)
只需调用itemAdapter.notifyDataSetChanged();