GridView行不膨胀

时间:2015-10-21 21:28:44

标签: java android android-layout android-arrayadapter android-gridview

我的布局中有一个简单的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();

 @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;
    }

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

1 个答案:

答案 0 :(得分:1)

实施自定义视图时,必须实施onMeasure。此方法将告诉Android框架您的视图应该是多大。由于您没有为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)内。我没有在这里列出这个限制,你可以确定自己在这种情况下想做什么。 您可以在guide中找到有关创建自定义组件的更多相关信息。有关onMeasure的具体信息可以在here找到。