android 使用GridLayoutManager和RecyclerView更改列数

wribegjk  于 2022-12-31  发布在  Android
关注(0)|答案(9)|浏览(437)

在我的片段中,我以如下方式设置GridLayout:第一个月
所以,我只是想改变24,当用户旋转手机/平板电脑。我读了关于onConfigurationChanged,我试图使它为我的情况下工作,但它是不是在正确的方式。当我旋转我的手机,应用程序崩溃...
你能告诉我怎么解决这个问题吗?
下面是我找到解决方案的方法,但效果不佳:

@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));
        }
    }
jv4diomz

jv4diomz1#

如果你有一个以上的条件或者在多个地方使用这个值,那么很快就会失控。我建议创建以下结构:

res
  - values
    - integers.xml
  - values-land
    - integers.xml

其中res/values/integers.xml为:

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

res/values-land/integers.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
}
hc2pp10m

hc2pp10m2#

请尝试在onCreateView方法中处理此问题,因为每次发生方向更改时都会调用此方法:

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

sqougxex3#

除了答案。它也可以只使用XML属性。下面是代码。

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/pax_seat_map_rv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:spanCount="3"
        android:orientation="vertical"
        app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" />
vsmadaxz

vsmadaxz4#

循环视图支持自动调整循环视图。
您需要在xml文件中添加android:numColumns="auto_fit"
您可以参考此AutofitRecycleViewLink

nom7f22z

nom7f22z5#

确定列数的一个更可靠的方法是在运行时根据屏幕宽度计算列数,我通常使用下面的函数。

public static int calculateNoOfColumns(Context context) {
    DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
    float dpWidth = displayMetrics.widthPixels / displayMetrics.density;
    int scalingFactor = 200; // You can vary the value held by the scalingFactor
    // variable. The smaller it is the more no. of columns you can display, and the
    // larger the value the less no. of columns will be calculated. It is the scaling
    // factor to tweak to your needs.
    int columnCount = (int) (dpWidth / scalingFactor);
    return (columnCount>=2?columnCount:2); // if column no. is less than 2, we still display 2 columns
}

这是一种更动态的方法,可以准确计算列数,更适合屏幕大小不同的用户,而不会被限制为只有两个可能的值。

注意:您可以改变scalingFactor变量的值。该值越小,您可以显示的列数越多;该值越大,计算的列数越少。它是根据您的需要调整的比例因子。

5lwkijsr

5lwkijsr6#

在onCreate()事件中,可以使用交错网格布局管理器

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);           
    }
}
kiayqfof

kiayqfof7#

我最后在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();
}

这对我的应用程序来说非常完美。

r7knjye2

r7knjye28#

您可以在RecyclerView onMeasure中实现该方法。首先,创建Java类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"/>

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

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

它可以用于不同的屏幕分辨率值-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));
}
evrscar2

evrscar29#

我会一步一步地解释它。你可以检查我分享的github项目的integers.xml,integers.xml(land)和MainFragment文件。你会看到列数会根据方向或屏幕大小而改变(平板电脑还是手机)(我只会解释当方向改变时如何做,因为问题只是关于它)。https://github.com/b-basoglu/NewsApp/blob/master/app/src/main/java/com/news/newsapp/ui/main/MainFragment.kt
1.创建一个名为integers. xml的资源文件。-〉在Project〉Android窗格中打开res文件夹,右键单击values文件夹,然后选择New〉Values resource file。
1.将文件命名为integers.xml,然后单击“确定”。
1.在标记之间创建一个名为grid_column_count的整数常量,并将其设置为2:
< integer name="grid_column_count">2</ integer >
1.创建另一个值资源文件,也称为integers.xml;但是,在从“可用限定词”窗格添加资源限定词时,系统会修改该名称。资源限定词用于标记各种情况下的资源配置。
1.在“可用限定符”窗格中选择“方向”,然后按对话框中间的〉〉符号以指定此限定符。
1.将Screen方向菜单更改为Landscape,并注意目录名称values-land的显示方式,这是资源限定符的本质:目录名告诉Android什么时候使用那个特定的布局文件。2在这种情况下,也就是手机旋转到横向模式的时候。
1.单击“确定”(OK)生成新布局文件。
1.将您创建的整型常量复制到这个新资源文件中,但将值更改为4。
< integer name="grid_column_count">4</ integer >
[You我有这些文件][1]
1.现在您所要做的就是在配置更改时重新分配跨度计数,如下所示:

override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        gridLayoutManager?.let {
            it.spanCount = resources.getInteger(R.integer.grid_column_count)
        }
    }
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        gridLayoutManager = GridLayoutManager(requireContext(), 
                                resources.getInteger(R.integer.grid_column_count))
        ${yourRecyclerView}.layoutManager = gridLayoutManager
        ...
  [1]: https://i.stack.imgur.com/3NZdq.png

相关问题