使用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(); }
它为我的应用程序完美解决。