如何自动确定 RecyclerView 网格的项目适合计数
How to automatically determine item fit count for RecyclerView grid
是否可以使用指定的宽度 (100dp) 为 RecyclerView 平均 space 输出网格中的项目(尽可能多),而不是使用确切的列数? int numberOfColumns = 3;
、int numberOfColumns = 4;
等将无法完成这项工作,因为这会导致大屏幕上出现大量空白 space。
纵向
横向
Fragment中RecyclerView相关代码
static final String[] frenchVowels = new String[]{
"a", "e", "i", "o", "u", "y"
};
RecyclerViewAdapter rvAdapterGL;
final RecyclerView rvGL = viewHolder.itemView.findViewById(R.id.rv);
int numberOfColumns = 2;
rvGL.setLayoutManager(new GridLayoutManager(getActivity(), numberOfColumns));
rvAdapterGL = new RecyclerViewAdapter(getActivity(), frenchVowels);
rvGL.setAdapter(rvAdapterGL);
RecyclerView 适配器class
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private String[] mData;
private LayoutInflater mInflater;
// data is passed into the constructor
public RecyclerViewAdapter(Context context, String[] data) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
}
// inflates the cell layout from xml when needed
@Override
@NonNull
public RecyclerViewAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.gridview_item, parent, false);
return new RecyclerViewAdapter.ViewHolder(view);
}
// binds the data to the TextView in each cell
@Override
public void onBindViewHolder(@NonNull RecyclerViewAdapter.ViewHolder holder, int position) {
holder.myTextView.setText(mData[position]);
}
// total number of cells
@Override
public int getItemCount() {
return mData.length;
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder {
TextView myTextView;
ViewHolder(View itemView) {
super(itemView);
myTextView = itemView.findViewById(R.id.item_gridview);
}
}
}
XML
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:id="@+id/cv_gv"
android:layout_marginBottom="20dp"
>
<LinearLayout
android:id="@+id/cardview_gv_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp"
android:animateLayoutChanges="true">
<LinearLayout
android:id="@+id/cardview_gv_titlerow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="2dp"
android:weightSum="100">
<TextView
android:id="@+id/tv_gv_A"
android:layout_weight="90"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorPrimary"
style="@android:style/TextAppearance.Medium" />
<TextView
android:id="@+id/tv_gv_expandcollapse"
android:importantForAccessibility="no"
android:clickable="true"
android:focusable="true"
android:layout_weight="10"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:textColor="?android:attr/textColorPrimary"
style="@android:style/TextAppearance.Large" />
</LinearLayout>
<RelativeLayout
android:id="@+id/relativelayout_gv"
android:animateLayoutChanges="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<GridView
android:id="@+id/gv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:columnWidth="100dp"
android:numColumns="auto_fit"
android:layout_marginBottom="20dp"
android:stretchMode="columnWidth" />
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
有几种不同的方法可以处理这个问题。您可以做的一件事是获取屏幕宽度并将其除以所需的单元格宽度以获得列数。
您还可以使用资源框架为不同的屏幕尺寸设置不同的列数。例如,您可以使用将列数设置为 3 的 res/values/integers.xml
,以及将列数设置为 5 的 res/values-sw400dp/integers.xml
,依此类推。
res/values/integers.xml
<resources>
<integer name=“column_count”>3</integer>
</resources>
res/values-sw400dp/integers.xml
<resources>
<integer name=“column_count”>5</integer>
</resources>
现在你可以替换
int numberOfColumns = 2;
和
int numberOfColumns = getResources().getInteger(R.integer.column_count);
并且您可以使用任意数量的 values-swXXXdp/integers.xml
文件,其中包含许多 XXX
的不同值,以便为许多不同的屏幕尺寸设置大量不同的列数。
如果你使用GridView布局,这个问题就回答了here。
或者,如果你想使用 GridLayoutManager,可以这样做
if(getActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
mRecycler.setLayoutManager(new GridLayoutManager(mContext, 2));
}
else{
mRecycler.setLayoutManager(new GridLayoutManager(mContext, 4));
}
您应该使用 flexbox-layout 库。由Google设计的开源库,会根据行宽自动设置列数,无需指定列数。
而且它的用法也很简单:
RecyclerView recyclerView = (RecyclerView) context.findViewById(R.id.recyclerview);
FlexboxLayoutManager layoutManager = new FlexboxLayoutManager(context);
recyclerView.setLayoutManager(layoutManager);
Gradle:
dependencies {
implementation 'com.google.android:flexbox:1.0.0'
}
是否可以使用指定的宽度 (100dp) 为 RecyclerView 平均 space 输出网格中的项目(尽可能多),而不是使用确切的列数? int numberOfColumns = 3;
、int numberOfColumns = 4;
等将无法完成这项工作,因为这会导致大屏幕上出现大量空白 space。
纵向
横向
Fragment中RecyclerView相关代码
static final String[] frenchVowels = new String[]{
"a", "e", "i", "o", "u", "y"
};
RecyclerViewAdapter rvAdapterGL;
final RecyclerView rvGL = viewHolder.itemView.findViewById(R.id.rv);
int numberOfColumns = 2;
rvGL.setLayoutManager(new GridLayoutManager(getActivity(), numberOfColumns));
rvAdapterGL = new RecyclerViewAdapter(getActivity(), frenchVowels);
rvGL.setAdapter(rvAdapterGL);
RecyclerView 适配器class
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private String[] mData;
private LayoutInflater mInflater;
// data is passed into the constructor
public RecyclerViewAdapter(Context context, String[] data) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
}
// inflates the cell layout from xml when needed
@Override
@NonNull
public RecyclerViewAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.gridview_item, parent, false);
return new RecyclerViewAdapter.ViewHolder(view);
}
// binds the data to the TextView in each cell
@Override
public void onBindViewHolder(@NonNull RecyclerViewAdapter.ViewHolder holder, int position) {
holder.myTextView.setText(mData[position]);
}
// total number of cells
@Override
public int getItemCount() {
return mData.length;
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder {
TextView myTextView;
ViewHolder(View itemView) {
super(itemView);
myTextView = itemView.findViewById(R.id.item_gridview);
}
}
}
XML
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:id="@+id/cv_gv"
android:layout_marginBottom="20dp"
>
<LinearLayout
android:id="@+id/cardview_gv_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp"
android:animateLayoutChanges="true">
<LinearLayout
android:id="@+id/cardview_gv_titlerow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="2dp"
android:weightSum="100">
<TextView
android:id="@+id/tv_gv_A"
android:layout_weight="90"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorPrimary"
style="@android:style/TextAppearance.Medium" />
<TextView
android:id="@+id/tv_gv_expandcollapse"
android:importantForAccessibility="no"
android:clickable="true"
android:focusable="true"
android:layout_weight="10"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:textColor="?android:attr/textColorPrimary"
style="@android:style/TextAppearance.Large" />
</LinearLayout>
<RelativeLayout
android:id="@+id/relativelayout_gv"
android:animateLayoutChanges="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<GridView
android:id="@+id/gv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:columnWidth="100dp"
android:numColumns="auto_fit"
android:layout_marginBottom="20dp"
android:stretchMode="columnWidth" />
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
有几种不同的方法可以处理这个问题。您可以做的一件事是获取屏幕宽度并将其除以所需的单元格宽度以获得列数。
您还可以使用资源框架为不同的屏幕尺寸设置不同的列数。例如,您可以使用将列数设置为 3 的 res/values/integers.xml
,以及将列数设置为 5 的 res/values-sw400dp/integers.xml
,依此类推。
res/values/integers.xml
<resources>
<integer name=“column_count”>3</integer>
</resources>
res/values-sw400dp/integers.xml
<resources>
<integer name=“column_count”>5</integer>
</resources>
现在你可以替换
int numberOfColumns = 2;
和
int numberOfColumns = getResources().getInteger(R.integer.column_count);
并且您可以使用任意数量的 values-swXXXdp/integers.xml
文件,其中包含许多 XXX
的不同值,以便为许多不同的屏幕尺寸设置大量不同的列数。
如果你使用GridView布局,这个问题就回答了here。
或者,如果你想使用 GridLayoutManager,可以这样做
if(getActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
mRecycler.setLayoutManager(new GridLayoutManager(mContext, 2));
}
else{
mRecycler.setLayoutManager(new GridLayoutManager(mContext, 4));
}
您应该使用 flexbox-layout 库。由Google设计的开源库,会根据行宽自动设置列数,无需指定列数。
而且它的用法也很简单:
RecyclerView recyclerView = (RecyclerView) context.findViewById(R.id.recyclerview);
FlexboxLayoutManager layoutManager = new FlexboxLayoutManager(context);
recyclerView.setLayoutManager(layoutManager);
Gradle:
dependencies {
implementation 'com.google.android:flexbox:1.0.0'
}