使用GridLayoutManager和RecyclerView更改列数

在我的片段内我以下面的方式设置我的GridLayout: mRecycler.setLayoutManager(new GridLayoutManager(rootView.getContext(), 2));

所以,我只是想在用户旋转手机/平板电脑时将其更改为4 。 我已阅读onConfigurationChanged并试图使其适用于我的情况,但它不会以正确的方式。 当我旋转我的手机,应用程序崩溃…

你能告诉我如何解决这个问题?

这是我的方法来find解决scheme,这是不正确的工作:

  @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); int orientation = newConfig.orientation; if (orientation == Configuration.ORIENTATION_PORTRAIT) { mRecycler.setLayoutManager(new GridLayoutManager(mContext, 2)); } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) { mRecycler.setLayoutManager(new GridLayoutManager(mContext, 4)); } } 

提前致谢!

尝试在onCreateView方法中处理这个问题,因为每当方向发生变化时都会调用它:

 if(getActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){ mRecycler.setLayoutManager(new GridLayoutManager(mContext, 2)); } else{ mRecycler.setLayoutManager(new GridLayoutManager(mContext, 4)); } 

如果你有多个条件或在多个地方使用这个值,这个速度可能会非常快。 我build议创build以下结构:

 res - values - dimens.xml - values-land - dimens.xml 

res/values/dimens.xml是:

 <?xml version="1.0" encoding="utf-8"?> <resources> <integer name="gallery_columns">2</integer> </resources> 

res/values-land/dimens.xml是:

 <?xml version="1.0" encoding="utf-8"?> <resources> <integer name="gallery_columns">4</integer> </resources> 

然后代码变成(并永远保持)这样:

 final int columns = getResources().getInteger(R.integer.gallery_columns); mRecycler.setLayoutManager(new GridLayoutManager(mContext, columns)); 

您可以很容易地看到添加确定列数的新方法是多么容易,例如使用-w500dp / -w600dp / -w700dp资源文件夹而不是-land

将这些文件夹分组到单独的资源文件夹中也很容易,以防您不希望混淆其他(更相关的)资源:

 android { sourceSets.main.res.srcDir 'src/main/res-overrides' // add alongside src/main/res } 

回收视图支持AutofitRecycleView。

你需要在你的xml文件中添加android:numColumns="auto_fit"

你可以参考这个AutofitRecycleViewLink

一个更强大的方式来确定没有。 的列将根据屏幕宽度和在运行时计算它。 我通常使用以下function。

 public static int calculateNoOfColumns(Context context) { DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); float dpWidth = displayMetrics.widthPixels / displayMetrics.density; int scalingFactor = 180; int noOfColumns = (int) (dpWidth / scalingFactor); return noOfColumns; } 

这是一个更加dynamic的方法来准确计算no。 列。 这对于不同屏幕大小的用户来说更适应,而不会被篡改为只有两个可能的值。

注意:你可以改变scalingFactorvariables的值。 越小越没有。 你可以显示的列数量越多,值越小。 的列将被计算。 这是调整您的需求的比例因子。

在onCreate()事件中,您可以使用StaggeredGridLayoutManager

 mRecyclerView = (RecyclerView) v.findViewById(R.id.recyclerView); mStaggeredGridLayoutManager = new StaggeredGridLayoutManager( 1, //number of grid columns GridLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(mStaggeredGridLayoutManager); 

然后,当用户旋转屏幕捕捉事件,并自动更改列数

 @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (getActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { mStaggeredGridLayoutManager.setSpanCount(1); } else { //show in two columns mStaggeredGridLayoutManager.setSpanCount(2); } } 

你可以在你的recyclerView onMeasure中实现这个方法。 首先,创buildJava类AutofitRecyclerView

 public class AutofitRecyclerView extends RecyclerView { //private GridLayoutManager manager; private StaggeredGridLayoutManager manager; private int columnWidth = -1; public AutofitRecyclerView(Context context) { super(context); init(context, null); } public AutofitRecyclerView(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public AutofitRecyclerView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } private void init(Context context, AttributeSet attrs) { if (attrs != null) { int[] attrsArray = { android.R.attr.columnWidth }; TypedArray array = context.obtainStyledAttributes(attrs, attrsArray); columnWidth = array.getDimensionPixelSize(0, -1); array.recycle(); } manager = new StaggeredGridLayoutManager(1, GridLayoutManager.VERTICAL); setLayoutManager(manager); } @Override protected void onMeasure(int widthSpec, int heightSpec) { super.onMeasure(widthSpec, heightSpec); if (columnWidth > 0) { int spanCount = Math.max(1, getMeasuredWidth() / columnWidth); manager.setSpanCount(spanCount); } }} 

在你的xlm布局文件activity_main.xml中

 <yourpackagename.AutofitRecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" android:columnWidth="@dimen/column_width" android:clipToPadding="false"/> 

然后将variables设置为值文件夹值/ dimens.xml的文件大小中每个项目的宽度

 <resources> <dimen name="column_width">250dp</dimen> </resources> 

它可以为不同的屏幕分辨率values-xxhdpi / dimens.xml

 <resources> <dimen name="column_width">280dp</dimen> </resources> 

在onCreate事件的活动中放置下面的代码

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); recyclerView.addItemDecoration(new MarginDecoration(this)); recyclerView.setHasFixedSize(true); recyclerView.setAdapter(new NumberedAdapter(50)); } 

我结束了在onCreate方法中处理这个。

 private RecyclerView recyclerView = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = (RecyclerView) findViewById(R.id.recycler_view); recyclerView.setHasFixedSize(true); Configuration orientation = new Configuration(); if(this.recyclerView.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { recyclerView.setLayoutManager(new GridLayoutManager(this, 2)); } else if (this.recyclerView.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { recyclerView.setLayoutManager(new GridLayoutManager(this, 4)); } connectGetApiData(); } 

它为我的应用程序完美解决。