表示サイズに基づいて、リサイクラービュー(グリッドレイアウト)に表示される列の数を変更しようとしています。しかし、それを達成するための適切な方法を理解することができませんでした。現在、私はtreeViewObserver
を使用して、画面のサイズの変化に基づいて(方向付け中)列数を変更しています。したがって、アプリが縦向きモードで開く場合、列の数(電話上)は1であると判断されますが、見栄えは良いですが、アプリが横向きモードで直接開くと、グリッド内の1枚のカードがストレッチされます。この方法は機能しません。画面にが表示されます。
recListはRecyclerViewで、glmはRecyclerViewで使用されるGridLayoutManagerです
viewWidth = recList.getMeasuredWidth();
cardViewWidthZZ = recList.getChildAt(0).getMeasuredWidth();
if (oldWidth == 0) {
oldWidth = cardViewWidthZZ;
}
if (oldWidth <= 0)
return;
int newSpanCount = (int) Math.floor(viewWidth / (oldWidth / 1.3f));
if (newSpanCount <= 0)
newSpanCount = 1;
glm.setSpanCount(newSpanCount);
glm.requestLayout();
宜しくお願いします
public class VarColumnGridLayoutManager extends GridLayoutManager {
private int minItemWidth;
public VarColumnGridLayoutManager(Context context, int minItemWidth) {
super(context, 1);
this.minItemWidth = minItemWidth;
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler,
RecyclerView.State state) {
updateSpanCount();
super.onLayoutChildren(recycler, state);
}
private void updateSpanCount() {
int spanCount = getWidth() / minItemWidth;
if (spanCount < 1) {
spanCount = 1;
}
this.setSpanCount(spanCount);
}}
固定列幅を提供する場合、RecyclerView
を拡張し、それに応じてonMeasure
にスパン数を設定できます。
public AutofitRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
if (attrs != null) {
// Read Android:columnWidth from xml
int[] attrsArray = {
Android.R.attr.columnWidth
};
TypedArray array = context.obtainStyledAttributes(attrs, attrsArray);
columnWidth = array.getDimensionPixelSize(0, -1);
array.recycle();
}
manager = new GridLayoutManager(getContext(), 1);
setLayoutManager(manager);
}
protected void onMeasure(int widthSpec, int heightSpec) {
super.onMeasure(widthSpec, heightSpec);
if (columnWidth > 0) {
int spanCount = Math.max(1, getMeasuredWidth() / columnWidth);
manager.setSpanCount(spanCount);
}
}
詳細については、私のブログ投稿を参照してください: http://blog.sqisland.com/2014/12/recyclerview-autofit-grid.html
これが私の解決策です。
public class ResponsiveGridLayoutManager extends GridLayoutManager {
boolean hasSetupColumns;
int columnWidthPx;
public ResponsiveGridLayoutManager(Context context, int orientation,
boolean reverseLayout, int columnWidthUnit, float columnWidth) {
super(context, 1, orientation, reverseLayout);
Resources r;
if (context == null) {
r = Resources.getSystem();
} else {
r = context.getResources();
}
float colWidthPx = TypedValue.applyDimension(columnWidthUnit,
columnWidth, r.getDisplayMetrics());
this.columnWidthPx = Math.round(colWidthPx);
}
public ResponsiveGridLayoutManager(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
int[] requestedValues = {
Android.R.attr.columnWidth,
};
TypedArray a = context.obtainStyledAttributes(attrs, requestedValues);
this.columnWidthPx = a.getDimensionPixelSize(0, -1);
a.recycle();
}
@Override
public int getWidth() {
int width = super.getWidth();
if (!hasSetupColumns && width > 0) {
this.setSpanCount((int)Math.floor(width / this.columnWidthPx));
}
return width;
}
}
どちらのXMLでも使用できます。
<Android.support.v7.widget.RecyclerView
Android:id="@+id/recycler"
Android:scrollbars="vertical"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:layoutManager="com.caff.localflix.ResponsiveGridLayoutManager"
Android:columnWidth="148dp" />
またはJava:
ResponsiveGridLayoutManager layoutManager = new ResponsiveGridLayoutManager(
this,
GridLayoutManager.VERTICAL,
false,
TypedValue.COMPLEX_UNIT_DIP,
148f
);
画面に依存するリソースファイルを作成して読み込むことができます。たとえば、values-w820pフォルダー内のbooleans.xml。または、おそらく大画面のレイアウトを作成して、それで完了できます。