在自定义视图组中未绘制自定义视图

时间:2018-06-26 06:34:24

标签: android android-layout android-custom-view viewgroup android-viewgroup

我有一个自定义视图类,它绘制一个矩形,并且有一个自定义视图组,我试图在其中添加这些自定义视图,但是以某种方式无法正确绘制视图(有时仅绘制一个视图)。 无法找到问题!

MainActivity.java

public class MainActivity extends Activity {

private CustomTaskView customTaskView;
private FrameLayout frameLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    customTaskView = new CustomTaskView(MainActivity.this);


    frameLayout = new FrameLayout(MainActivity.this);
    frameLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));


    Paint blackPaint = new Paint();
    blackPaint.setColor(Color.BLACK);
    blackPaint.setStyle(Paint.Style.STROKE);

    CustomView customView1 = new CustomView(MainActivity.this, 100, 50, 100, 300, blackPaint);

    customView1.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT));
    frameLayout.addView(customView1);


    Paint redPaint = new Paint();
    redPaint.setColor(Color.RED);
    redPaint.setStyle(Paint.Style.STROKE);

    CustomView customView2 = new CustomView(MainActivity.this, 200, 50, 300, 400, redPaint);
    customView2.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT));
    frameLayout.addView(customView2);



    setContentView(frameLayout);
  }

}

CustomView.java

public class CustomView extends View {

private Paint paint;

private float l, t, r, b;

public CustomView(Context context, float l, float t, float r, float b, Paint paint) {
    super(context);
    this.b = b;
    this.l = l;
    this.r = r;
    this.t = t;
    this.paint = paint;
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawRect(l, t, r, b, paint);
}
}

CustomTaskView.java(自定义视图组文件)

public class CustomTaskView extends ViewGroup implements LongPressGestureListener.HandleClicks {

int width, height;
private GestureDetectorCompat mGestureDetector;
private LongPressGestureListener longPressGestureListener;
private Map<Integer, List<Point>> map;


public CustomTaskView(Context context) {
    super(context);
    longPressGestureListener = new LongPressGestureListener(context, CustomTaskView.this);
    mGestureDetector = new GestureDetectorCompat(context, longPressGestureListener);
    map = new HashMap<>();
}

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

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

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {

}


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    width = getMeasuredWidth();
    height = getMeasuredHeight();
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    mGestureDetector.onTouchEvent(event);
    // Handle any other event here, if not long press.
    return true;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
}

@Override
public void handleLongClick(MotionEvent event) {
    Log.e("ganesh", "handling long clicks!");
}

@Override
public void handleSingleClick(MotionEvent event) {

    float xCoordinate = event.getX();
    float yCoordinate = event.getY();

    Point tempPoint = new Point(xCoordinate, yCoordinate);

    int count = 0;

    for (Map.Entry<Integer, List<Point>> entry : map.entrySet()) {
        if (isPointInside(entry.getValue(), tempPoint))
            count++;
    }

    Log.e("ganesh", "handling single clicks!" + xCoordinate + " " + yCoordinate + " count: " + count);


}


public boolean isPointInside(List<Point> pointList, Point targetPoint) {
    return targetPoint.getxCoordinate() >= pointList.get(0).getxCoordinate() && targetPoint.getxCoordinate() <= pointList.get(1).getxCoordinate() && targetPoint.getyCoordinate() >= pointList.get(0).getyCoordinate() && targetPoint.getyCoordinate() <= pointList.get(2).getyCoordinate();
}

}

2 个答案:

答案 0 :(得分:0)

每当对自定义视图进行任何更改时,都需要重建项目以供XML预览解析器绘制。尝试一次Build-> Rebuild Project

答案 1 :(得分:0)

如果直接扩展ViewGroup类,则必须在自定义视图中提供 onLayout onMeasure 方法的正确实现。您可以在Google Developers Guide Custom ViewGroup

中找到有关这两种方法的更多信息。

这是对当前CustomTaskView.java的编辑,以使代码正常工作。

 @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int count = getChildCount();
    for (int i = 0; i < count; i++) {
        CustomView customView = (CustomView) this.getChildAt(i);
        customView.layout(l, t, r, b);
    }
}

在自定义视图中, onLayout 方法负责将所有子项放置在布局中。您需要在所有子项上调用 layout 方法,并向其提供计算出的left,top,right,bottom属性。