Android 自定义View和ViewGroup

本文介绍了一种自定义Android UI组件的方法,包括一个自定义的单选按钮MyRadioButton和一个自定义的单选按钮组MyRadioGroup。通过这些组件,开发者可以实现特定的功能和样式,例如在单选按钮上绘制文本和响应触摸事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自定义View:

package com.gdseed.canvastestboard;


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Typeface;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;


public class MyRadioButton extends View {
private int mWidth = 0;
private int mHeight = 0;
private Paint mPaint = new Paint();
private String[] index = new String[]{"1", "2", "3", "4"};
private boolean isBTB = true;
private OnSwitchListener onSwitchListener = null;
private boolean enabled = true;
private boolean checked = false;

public MyRadioButton(Context context) {
this(context, null);
}

public MyRadioButton(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public MyRadioButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

public void initView(int a[], boolean b) {
for (int i=0; i<a.length; i++) {
index[i] = String.valueOf(a[i]);
}
isBTB = b;
}


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mWidth = View.MeasureSpec.getSize(widthMeasureSpec);
mHeight = View.MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(mWidth, mHeight);
}


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

canvas.drawColor(Color.WHITE);

if (checked && enabled) {
mPaint.setColor(Color.argb(255, 0, 165, 70));
} else {
mPaint.setColor(Color.BLACK);
}
mPaint.setStyle(Style.STROKE);
canvas.drawRect(0, 0, mWidth-1, mHeight-1, mPaint);

mPaint.setStyle(Style.FILL);
mPaint.setTextSize(18);
mPaint.setTypeface(Typeface.DEFAULT_BOLD);
FontMetrics fontMetrics = mPaint.getFontMetrics();  
float fontTotalHeight = fontMetrics.bottom - fontMetrics.top;
float fontTotalWidth = mPaint.measureText("99");
if (isBTB) {
canvas.drawText(index[0], 6, fontTotalHeight, mPaint);
canvas.drawText(index[1], mWidth-fontTotalWidth-5, fontTotalHeight, mPaint);
canvas.drawText(index[2], 6, mHeight-10, mPaint);
canvas.drawText(index[3], mWidth-fontTotalWidth-5, mHeight-10, mPaint);
} else {
canvas.drawText(index[0], 6, fontTotalHeight-2, mPaint);
canvas.drawText(index[1], mWidth-fontTotalWidth-7, fontTotalHeight-2, mPaint);
}
}


@Override
public boolean onTouchEvent(MotionEvent event) {
if (!enabled) {
return true;
}

int mCurrentX = (int)event.getX();
int mCurrentY = (int) event.getY();

switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:

if ((mCurrentX > 0 && mCurrentX < mWidth) && (mCurrentY > 0 && mCurrentY <mHeight)) {
checked = true;
}

if (onSwitchListener != null) {
onSwitchListener.onSwitch(this, checked);
}

break;
}

invalidate();
return true;
}


@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
this.enabled=enabled;
invalidate();
}

public void setChecked(boolean checked) {
this.checked=checked;
invalidate();
}

public void toggle() {
setChecked(!checked);
}

public void setOnSwitchListener(OnSwitchListener listener) {
onSwitchListener = listener;
}


public interface OnSwitchListener {
public void onSwitch(MyRadioButton myRadioButton, boolean isChecked);
}
}


自定义ViewGroup:

package com.gdseed.canvastestboard;


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;


public class MyRadioGroup extends ViewGroup {
private int mWidth = 0;
private int mHeight = 0;
private Paint mPaint = new Paint();
private RectF mRectF = new RectF();
private Rect mRect = new Rect();
private String str = "BTB方向设置";

public MyRadioGroup(Context context) {
this(context,null);
}

public MyRadioGroup(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public MyRadioGroup(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setWillNotDraw(false);
}

public void initView(boolean isBTB) {

if (isBTB) {
str = "BTB方向设置";
} else {
str = "ZIF方向设置";
}
}


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mWidth = View.MeasureSpec.getSize(widthMeasureSpec);
mHeight = View.MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(mWidth, mHeight);
measureChildren(widthMeasureSpec, heightMeasureSpec); 
}


@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int mPainterPosX = 10;
   int mPainterPosY = 30; 
   int mViewGroupWidth  = getMeasuredWidth();
   int mChildCount = getChildCount();
   
   for (int i=0; i<mChildCount; i++) {
    View childView = getChildAt(i);      
        int childWidth  = childView.getMeasuredWidth();
        int childHeight = childView.getMeasuredHeight();  
        
        MyRadioGroup.LayoutParams margins = (MyRadioGroup.LayoutParams)(childView.getLayoutParams());
                    
        if( mPainterPosX + childWidth + margins.leftMargin + margins.rightMargin > mViewGroupWidth ) {              
            mPainterPosX = 10; 
            mPainterPosY += childHeight + margins.topMargin + margins.bottomMargin;
        }                    
        
        childView.layout(mPainterPosX+margins.leftMargin, mPainterPosY+margins.topMargin, mPainterPosX+childWidth+margins.leftMargin, mPainterPosY+childHeight+margins.topMargin);
        
        mPainterPosX += childWidth+ margins.leftMargin + margins.rightMargin;
   }
}


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


canvas.drawColor(Color.WHITE);

mRectF.set(0, 8, mWidth-1, mHeight-1);
mPaint.setColor(Color.GRAY);
mPaint.setStyle(Style.STROKE);
canvas.drawRoundRect(mRectF, 10, 10, mPaint);

FontMetrics fontMetrics = mPaint.getFontMetrics();  
int fontTotalHeight = (int)(fontMetrics.bottom - fontMetrics.top) + 1;
int fontTotalWidth = (int)mPaint.measureText(str) + 5;

mRect.set(12, 0, fontTotalWidth, fontTotalHeight);
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Style.FILL);
canvas.drawRect(mRect, mPaint);

mPaint.setColor(Color.GRAY);
mPaint.setStyle(Style.FILL);
mPaint.setTextSize(10);
canvas.drawText(str, 13, fontTotalHeight-3, mPaint);
}

@Override  
    public LayoutParams generateLayoutParams(AttributeSet attrs) {  
        return new MyRadioGroup.LayoutParams(getContext(), attrs);  
    }

public static class LayoutParams extends ViewGroup.MarginLayoutParams {
public LayoutParams(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值