更改方向后更改RecyclerView的布局仅适用于第一个视图

时间:2019-01-19 10:31:50

标签: android android-fragments android-recyclerview

在我的应用程序中,我有这段代码可以计算手机尺寸并将RecyclerView布局管理器更改为GridLayoutManagerLinearLayoutManager

private void changeFeedsLayout() {
    // Choose between one, two or three elements per row
    if (dpWidth > 720 && getResources().getConfiguration().orientation ==
            ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
        instagram_feeds.setLayoutManager(new GridLayoutManager(
                context, 3, LinearLayoutManager.VERTICAL, false));
    } else if (dpWidth > 520) {
        instagram_feeds.setLayoutManager(new GridLayoutManager(
                context, 2, LinearLayoutManager.VERTICAL, false));
    } else {
        instagram_feeds.setLayoutManager(new LinearLayoutManager(
                context, LinearLayoutManager.VERTICAL, false));
    }
}

当我将每个片段附加或提交到MainActivity上的容器时,此代码工作正常,但是在更改电话方向时不起作用,为解决此问题,我正在使用此代码:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    changeFeedsLayout();
}

,不幸的是RecyclerView的layoutmanager始终是LinearLayoutManager,我无法解决。在打开其他片段并返回到先前的片段后工作正常。

更新

在更改手机方向时,此代码为:

instagram_feeds.setLayoutManager(new LinearLayoutManager(
                    context, LinearLayoutManager.VERTICAL, false));

changeFeedsLayout()方法上无法更改手机方向,并且此方法在更改手机方向时无法正确计算手机大小

3 个答案:

答案 0 :(得分:3)

这听起来可能很奇怪,但是在这种情况下,唯一有效的解决方案是将此设置放入资源中。 Android OS会基于许多属性来获取资源,其中之一就是宽度最小。要将列表与网格分开: values / bools.xml

<resources>
    <bool name="is_grid">false</bool>
</resources>

另一个将是 values-sw520dp / bools.xml

<resources>
    <bool name="is_grid">true</bool>
</resources>

对于相同逻辑的列数 values-sw520dp / integers.xml

<resources>
    <integer name="grid_column_count">2</integer>
</resources>

values-sw720dp / integers.xml

<resources>
    <integer name="grid_column_count">3</integer>
</resources>

因此,在代码中,它将类似于:

if (getResources().getBoolean(R.bool.is_grid)) {
    instagram_feeds.setLayoutManager(new GridLayoutManager(getActivity(), getResources().getInteger(R.integer.grid_column_count));
} else {
    instagram_feeds.setLayoutManager(new LinearLayoutManager(getActivity());
}

无论何时创建视图,都应应用此选项,无需处理配置更改-已经为您完成了。让操作系统完成工作。

答案 1 :(得分:0)

为了能够适应方向变化并相应地工作,我做了以下工作:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        Log.i("SCREEN DP","Orientation:"+ getResources().getConfiguration().orientation +" Width = "+getWidthDp());
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Log.i("SCREEN DP","Orientation:"+ newConfig.orientation +" Width = "+getWidthDp());
    }

    public float getWidthDp(){
        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        return displayMetrics.widthPixels / displayMetrics.density;
    }
}

日志显示:

I/SCREEN DP: Orientation:1 Width = 411.42856
I/SCREEN DP: Orientation:2 Width = 683.4286
I/SCREEN DP: Orientation:1 Width = 411.42856
I/SCREEN DP: Orientation:2 Width = 683.4286

别忘了在清单上添加android:screenOrientation="fullSensor"以便能够处理所有方向。

答案 2 :(得分:0)

GridLayoutManager.LayoutParams在其注释中进行了解释:

if the orientation is VERTICAL, the width parameter is ignored and

if the orientation is HORIZONTAL, the height parameter is ignored

because child view is expected to fill all of the space given to it.

重点是:

LinearLayoutManager始终只有1列;

GridLayoutManager“可能”具有1(或更多)列。