내 아이템을 GridView
사각형으로 만들고 싶습니다 . 2 개의 열이 있으며 항목 너비는 fill_parent
(예 : 가능한 한 많은 가로 공간을 차지합니다. 항목은 사용자 정의보기입니다.
항목 높이를 가변 너비와 동일하게 만드는 방법은 무엇입니까?
답변:
GridView 열을 늘릴 때 더 간단한 솔루션이 있습니다. GridView 항목 레이아웃의 onMeasure를 다음으로 재정의하십시오.
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
또는 뷰를 확장하려면 다음과 같이 아주 간단한 작업을 수행하십시오.
public class SquareImageView extends ImageView
{
public SquareImageView(final Context context)
{
super(context);
}
public SquareImageView(final Context context, final AttributeSet attrs)
{
super(context, attrs);
}
public SquareImageView(final Context context, final AttributeSet attrs, final int defStyle)
{
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec)
{
final int width = getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
setMeasuredDimension(width, width);
}
@Override
protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh)
{
super.onSizeChanged(w, w, oldw, oldh);
}
}
super.onMeasure()
필요하지 않다는 점 은 주목할 가치가 있습니다. onMeasured
요구 사항은 전화해야한다는 것 setMeasuredDimension
입니다.
super.onMeasure()
내부에 배치 된 ImageView가 그려지지 않습니다. 따라서 onMeasure
방법의 첫 번째 줄로 필요한 것 같습니다 .
현재 위젯에서 이것이 가능한지 잘 모르겠습니다. 가장 좋은 방법은 사용자 정의보기를 사용자 정의 "SquareView"에 넣는 것입니다. 이 뷰는 자식 뷰를 1 개만 포함 할 수 있으며 onLayout 메서드가 호출 될 때 높이를 너비와 동일하게 만들 수 있습니다.
그렇게하려고 한 적은 없지만 너무 어렵지 않을 것 같아요. 대안 (그리고 약간 더 쉬울 수도 있음) 솔루션은 사용자 정의보기의 루트 레이아웃을 하위 클래스로 만들고 (예 : LinearLayout 인 경우 SquareLinearLayout을 만들어) 대신 컨테이너로 사용하는 것입니다.
편집 : 나를 위해 작동하는 기본 구현은 다음과 같습니다.
package com.mantano.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
public class SquareView extends ViewGroup {
public SquareView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onLayout(boolean changed, int l, int u, int r, int d) {
getChildAt(0).layout(0, 0, r-l, d-u); // Layout with max size
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
View child = getChildAt(0);
child.measure(widthMeasureSpec, widthMeasureSpec);
int width = resolveSize(child.getMeasuredWidth(), widthMeasureSpec);
child.measure(width, width); // 2nd pass with the correct size
setMeasuredDimension(width, width);
}
}
고유 한 자식을 갖도록 설계되었지만 단순성을 위해 모든 검사를 무시했습니다. 기본 아이디어는 GridView에서 설정 한 너비 / 높이 매개 변수로 자식을 측정 한 다음 (내 경우에는 너비를 계산하기 위해 numColumns = 4 사용) 높이 = 너비로 최종 치수로 두 번째 패스를 수행하는 것입니다. .. 레이아웃은 단순한 레이아웃으로, (0, 0)에 고유 한 자식을 원하는 크기 (오른쪽-왼쪽, 아래쪽-위)로 레이아웃합니다.
다음은 GridView 항목에 사용되는 XML입니다.
<?xml version="1.0" encoding="utf-8"?>
<com.mantano.widget.SquareView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content">
<LinearLayout android:id="@+id/item" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="horizontal"
android:gravity="center">
<TextView android:id="@+id/text" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="Hello world" />
</LinearLayout>
</com.mantano.widget.SquareView>
모든 중력 가능성, 여백 등을 관리하기 위해 SquareView 내부에 LinearLayout을 사용했습니다.
이 위젯이 방향 및 치수 변경에 얼마나 잘 (또는 나쁘게) 반응하는지 잘 모르겠지만 제대로 작동하는 것 같습니다.
그리드 항목 사각형을 얻는 것은 상당히 쉽습니다.
그리드 어댑터의 "GetView"메소드에서 다음을 수행하십시오.
@Override
public View getView(int position, View convertView, ViewGroup parent) {
GridView grid = (GridView)parent;
int size = grid.getRequestedColumnWidth();
TextView text = new TextView(getContext());
text.setLayoutParams(new GridView.LayoutParams(size, size));
// Whatever else you need to set on your view
return text;
}
getRequestedColumnWidth
해야 getColumnWidth
했고 나를 위해 일했습니다 ... 감사합니다!
이것이 최선의 방법인지는 모르겠지만 사용자 정의보기를 사용하여 onSizeChanged를 재정의하도록 수행합니다.
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (getLayoutParams() != null && w != h) {
getLayoutParams().height = w;
setLayoutParams(getLayoutParams());
}
}
LinearLayout 및 GridView 내에서이 사용자 지정보기를 사용하고 둘 다 사각형으로 표시됩니다!
이것은 나를 위해 일했습니다!
당신이 나와 같고 minSdk가 16보다 낮기 때문에 getRequestedColumnWidth ()를 사용할 수 없다면이 옵션을 제안합니다.
조각에서 :
DisplayMetrics dm = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
int size = dm.widthPixels / nbColumns;
CustomAdapter adapter = new CustomAdapter(list, size, getActivity());
어댑터에서 (getView (int position, View convertView, ViewGroup parent))
v.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, size));
fragment.xml :
<GridView
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:horizontalSpacing="3dp"
android:verticalSpacing="3dp"
android:numColumns="4"
android:stretchMode="columnWidth" />
custom_item.xml : (예)
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/picture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
누군가를 도울 수 있기를 바랍니다!
xml에서 정적 열 수를 설정하면보기의 너비를 열 수로 나눌 수 있습니다.
사용하는 경우 auto_fit
열 수를 얻는 것이 약간 까다로울 것입니다 (getColumnCount () 메서드가 없습니다). btw 이 질문은 어떻게 든 도움이 될 것입니다.
이것은 getView(...)
고정 된 수의 열이있는 어댑터 메서드에 사용하는 코드 입니다.
item_side = mFragment.holder.grid.getWidth() / N_COL;
v.getLayoutParams().height = item_side;
v.getLayoutParams().width = item_side;
이것이 GridView에 정사각형 셀을 표시하기 위해 수행하는 작업입니다. 정사각형 셀이나 다른 것을 원하는지 확실하지 않습니다.
GridView grid = new GridView( this );
grid.setColumnWidth( UIScheme.cellSize );
grid.setVerticalSpacing( UIScheme.gap );
grid.setStretchMode( GridView.STRETCH_COLUMN_WIDTH );
grid.setNumColumns( GridView.AUTO_FIT );
그런 다음 각 셀에 대해 만들고있는 뷰에 대해 다음을 수행해야합니다.
cell.setLayoutParams( new GridView.LayoutParams(iconSize, iconSize) );
API 16+ 인 SteveBorkman의 답변을 기반으로합니다 .
@Override
public View getView(int position, View convertView, ViewGroup parent) {
GridView grid = (GridView)parent;
int size = grid.getColumnWidth();
if (convertView == null){
convertView = LayoutInflater.from(context).inflate(R.layout.your_item, null);
convertView.setLayoutParams(new GridView.LayoutParams(size, size));
}
//Modify your convertView here
return convertView;
}
@Gregory의 답변 라인을 따라 GridView가 정사각형에서 치수를 조작하지 못하도록 LinearLayout에 이미지를 래핑해야했습니다. 외부 LinearLayout은 이미지의 크기를 갖도록 설정해야하며 GridView 열의 너비는 이미지의 너비와 여백을 더한 값이어야합니다. 예를 들면 :
<!-- LinearLayout wrapper necessary to wrap image button in order to keep square;
otherwise, the grid view distorts it into rectangle.
also, margin top and right allows the indicator overlay to extend top and right.
NB: grid width is set in filter_icon_page.xml, and must correspond to size + margin
-->
<LinearLayout
android:id="@+id/sport_icon_lay"
android:layout_width="60dp"
android:layout_height="60dp"
android:orientation="vertical"
android:layout_marginRight="6dp"
android:layout_marginTop="6dp"
>
<ImageButton
android:id="@+id/sport_icon"
android:layout_width="60dp"
android:layout_height="60dp"
android:maxHeight="60dp"
android:maxWidth="60dp"
android:scaleType="fitCenter"
/>
</LinearLayout>
그리고 GridView는 다음과 같습니다.
<GridView
android:id="@+id/grid"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
android:columnWidth="66dp"
android:numColumns="auto_fit"
android:verticalSpacing="25dp"
android:horizontalSpacing="24dp"
android:stretchMode="spacingWidth"
/>
당신의 활동에서
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
valX = displaymetrics.widthPixels/columns_number;
GridView의 CustomAdapter에서
v.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, YourActivity.valX));