当前位置: 代码迷 >> Android >> GridView行未膨胀
  详细解决方案

GridView行未膨胀

热度:103   发布时间:2023-08-04 11:08:33.0

我的布局中有一个带有自定义适配器的简单GridView 我的代码如下:

CircleActivity.java:

public class CircleActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_circle);

        List<Integer> listColors = new ArrayList<>();
        listColors.add(getResources().getColor(R.color.colorAccent));
        listColors.add(getResources().getColor(R.color.colorPrimary));
        listColors.add(getResources().getColor(R.color.colorPrimaryDark));

        GridView gridView = (GridView) findViewById(R.id.grid_colors);
        CircleAdapter adapter = new CircleAdapter(this,listColors);
        gridView.setAdapter(adapter);
    }
}

activity_circle.xml:

<?xml version="1.0" encoding="utf-8"?>

    <GridView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/grid_colors"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

CircleAdapter.java:

public class CircleAdapter extends BaseAdapter{
private Context context;
private List<Integer> listColor;

public CircleAdapter(Context context, List<Integer> listColor) {
    this.listColor = listColor;
    this.context = context;
}

@Override
public int getCount() {
    return listColor.size();
}

@Override
public Integer getItem(int position) {
    return listColor.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if(convertView==null){
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.row_grid,parent,false);
        holder = new ViewHolder(convertView);
        convertView.setTag(holder);
    }
    else{
        holder = (ViewHolder) convertView.getTag();
    }

    holder.customCircleView.setFillColor(listColor.get(position));
    holder.customCircleView.setCircleRadius(100);
    return convertView;
}


static class ViewHolder{
    private CustomCircleView customCircleView;
    public ViewHolder(View row){
        customCircleView = (CustomCircleView) row.findViewById(R.id.custom_circle_view);
    }
  }
}

row_grid.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:background="@color/colorAccent"
    android:layout_width="match_parent"
    android:gravity="center"
    android:layout_height="match_parent">
    <com.droidexperiments.gridexpand.CustomCircleView
        android:id="@+id/custom_circle_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        custom:fill_color="@color/colorPrimary"
        custom:circle_radius="50"
        android:padding="25dp" />

</LinearLayout>

CircleView.java:

public class CustomCircleView extends View {
private int circleRadius = 20;
private int fillColor = Color.BLACK;


public CustomCircleView(Context context) {
    super(context);
}

public CustomCircleView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context, attrs);
}

public CustomCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(context, attrs);
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CustomCircleView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    init(context, attrs);
}

private void init(Context context, AttributeSet attrs) {
    TypedArray typedArray = context.obtainStyledAttributes(R.styleable.CustomCircle);
    circleRadius = typedArray.getInteger(R.styleable.CustomCircle_circle_radius,20);
    fillColor = typedArray.getColor(R.styleable.CustomCircle_fill_color, Color.BLACK);
    typedArray.recycle();
}

public int getCircleRadius() {
    return circleRadius;
}

public void setCircleRadius(int circleRadius) {
    this.circleRadius = circleRadius;
}

public int getFillColor() {
    return fillColor;
}

public void setFillColor(int fillColor) {
    this.fillColor = fillColor;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    Paint paint = new Paint();
    paint.setColor(fillColor);
    paint.setStyle(Paint.Style.FILL);

    canvas.drawCircle(canvas.getWidth()/2,canvas.getHeight()/2,circleRadius,paint);
}

}

attrts.xml:

   <declare-styleable name="CustomCircle">
        <attr name="fill_color" format="reference|color"/>
        <attr name="circle_radius" format="integer"/>
    </declare-styleable>

问题在于屏幕保持空白,并且在GridView中没有行被放大/显示。

我检查了一切。 GridView或网格行的布局或CustomCircleView没有任何问题。 如果我将adapter更改为简单的ArrayAdapter ,则可以正常工作。 因此,我的适配器一定存在问题:

我在适配器中getView()检查了getView()

 @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if(convertView==null){
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.row_grid,parent,false);
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        }
        else{
            holder = (ViewHolder) convertView.getTag();
        }

        holder.customCircleView.setFillColor(listColor.get(position));
        holder.customCircleView.setCircleRadius(100);
        return convertView;
    }

但无法确定为什么显示空白。 有人可以帮我吗?

实现自定义视图时,必须实现onMeasure 此方法将告诉Android框架您的视图应为多大。 由于您没有为CustomCircleView指定此参数, CustomCircleView在布局中使用了wrap_content ,因此它的大小为零。 因此, GridView所有元素都是不可见的,从而使适配器看起来好像不起作用。 我做了一个onMeasure的简单示例实现,可以解决您的问题(只需在CustomCircleView添加此方法):

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int size = View.MeasureSpec.makeMeasureSpec(2 * this.circleRadius, MeasureSpec.EXACTLY);
    setMeasuredDimension(size, size);
}

该文档建议size保持在给定参数( widthMeasureSpecheightMeasureSpec )之内。 我没有在此处包括该限制,您可以确定自己在这种情况下想要做什么。 您可以在创建自定义组件的找到有关此信息的更多信息。 关于onMeasure特定信息可以在找到。