web-dev-qa-db-ja.com

GridLayoutManagerとRecyclerViewを使用して列の数を変更する

フラグメント内で、次の方法でGridLayoutを設定しています:mRecycler.setLayoutManager(new GridLayoutManager(rootView.getContext(), 2));

そのため、ユーザーが電話/タブレットを回転させたときに、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));
        }
    }

前もって感謝します!

54
fapps

代わりに、方向の変更があるたびに呼び出されるため、onCreateViewメソッド内でこれを処理してみてください。

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

複数の条件がある場合、または値を複数の場所で使用する場合、これはかなり速く手に負えなくなる可能性があります。次の構造を作成することをお勧めします。

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 being:

<?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
}
77
TWiStErRob

リサイクルビューはAutofitRecycleViewをサポートしています。

XmlファイルにAndroid:numColumns="auto_fit"を追加する必要があります。

これを参照できます AutofitRecycleViewLink

7
kattashri

いいえを決定するためのより堅牢な方法。列の数は、画面幅と実行時に基づいて計算することになります。私は通常、次の機能を使用します。

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
}

Noを正確に計算するより動的な方法です。列の。これは、2つの可能な値に制限されることなく、さまざまな画面サイズのユーザーにより適応的です。

NB:scalingFactor変数によって保持される値を変更できます。小さければ小さいほどいいです。表示できる列の数が多く、値が大きいほど小さい。の列が計算されます。これは、ニーズに合わせて調整するためのスケーリング係数です。

7
Rowland Mtetezi

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

私はこれを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();
}

私のアプリでは完璧に機能しました。

1
user6731701

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