Android:在画布上绘制自定义TextView

问题描述 投票:0回答:1

我正在关注TextView

public class Cube extends TextView {

Context mContext;

Drawable background;//Hintergrund des Blocks
char mLetter;//Buchstabe des Blocks
int x, y;//Koordinaten des Blocks

@SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public Cube(Context context, char letter, int _x, int _y) {
    super(context);
    mContext = context;
    mLetter = letter;
    background = ContextCompat.getDrawable(getContext(), R.drawable.cube);
    x = _x;
    y = _y;
    this.setText("" + letter);
    if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN)
        this.setBackgroundDrawable(background);
    else
        this.setBackground(background);
}

public void drawCube(Canvas canvas){//how to draw now!? This is called from a separate thread in SurfaceView
}

}

如果我在drawCube()中调用以下方法:

    background.setBounds(x, y, x + 20, y + 20);
    background.draw(canvas);

它只是绘制backgroundDrawable。但是,如何在里面加上文字/字母来绘制呢?它看起来像这样:(背景是画布,橙色和白色是背景,“ A”是字母/文本)

enter image description here

编辑:代码为21.09这是我的(缩短的)线程:

public class CanvasThread extends Thread {

private SurfaceHolder mSh;

private ArrayList<Cube> mCubes;

private Canvas mCanvas;
private Context mContext;
private boolean mRun = false;
private boolean mDown = false;
private boolean newCube = false;
public CanvasThread(SurfaceHolder sh, Context context){
    mSh = sh;
    mCubes = new ArrayList<>();
    mContext = context;
}

public void run(){
    while(mRun){
        mCanvas = null;

        try{
            mCanvas = mSh.lockCanvas(null);
            synchronized (mSh){
                mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
                newCube = true;
                for(int i = 0; i < mCubes.size(); i++){
                    if(mCubes.get(i).getSpeed() > 0)
                        newCube = false;
                    if(mDown) {
                        if (mCubes.get(i).moveDown(feld)) {
                            mDown = false;
                        }
                    }
                    //mCubes.get(i).invalidate();
                    //mCubes.get(i).requestLayout();
                    mCubes.get(i).draw(mCanvas);
                }
                if(newCube)
                    addCube();
            }
        } finally {
            if(mCanvas != null){
                mSh.unlockCanvasAndPost(mCanvas);
            }
        }
    }
}

public void addCube(){
    Random r = new Random();
    Cube cube = new Cube(mContext, mBuchstaben[r.nextInt(29)], r.nextInt(10), 0, mCanvas);
    mCubes.add(cube);
}

}

这是我的(缩短的)片段,它使用画布/曲面视图:

public class KlassischFragment extends Fragment implements SurfaceHolder.Callback {

SurfaceHolder sh;
SurfaceView sv;

private CanvasThread thread;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_klassisch, container, false);
    sv = (SurfaceView) view.findViewById(R.id.surfaceView);
    sh = sv.getHolder();
    sh.addCallback(this);
    sh.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    return view;
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    thread = new CanvasThread(sh, getContext());
    thread.setRunnable(true);
    thread.start();
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    boolean retry = true;
    //thread.setRunnable(false);

    while(retry){
        try{
            thread.join();
            retry = false;
        } catch(InterruptedException ie){
            //Immer wieder versuchen
        }
        break;
    }
    thread = null;
}

}

android textview android-canvas drawable
1个回答
1
投票

这里是有关如何在正方形上方绘制文本的示例。一些值是硬编码的,但是您应该可以使它们动态化。

public class Cube extends View {

    private final static String TEST_STRING = "ABC";
    private Paint mBackgroundPaint;
    private Paint mTextPaint;

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

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

    public Cube(Context context, AttributeSet attrs) {
        this(context, attrs, -1);
    }

    public Cube(Context context) {
        this(context, null, -1);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // Just for demo purposes this should be calculated properly
        int desiredWidth = 100;
        int desiredHeight = 100;

        setMeasuredDimension(desiredWidth, desiredHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int savedCount = canvas.save();
        drawRectangle(canvas);
        drawText(canvas);
        canvas.restoreToCount(savedCount);
    }

    private void init() {
        mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBackgroundPaint.setColor(Color.BLUE);
        mBackgroundPaint.setStyle(Paint.Style.FILL);

        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        // This need to be adjusted based on the requirements that you have
        mTextPaint.setTextSize(20.0f);

    }

    private void drawRectangle(Canvas canvas) {
        canvas.drawRect(0, 0, getWidth(), getHeight(), mBackgroundPaint);
    }

    private void drawText(Canvas canvas) {
        Rect rect = new Rect();
        // For simplicity I am using a hardcoded string
        mTextPaint.getTextBounds(TEST_STRING, 0, 1, rect);
        int w = getWidth(), h = getHeight();
        float x = (w - rect.width()) / 2, y = ((h - rect.height()) / 2) + rect.height();
        canvas.drawText(TEST_STRING, 0, 1, x, y, mTextPaint);


    }
}
© www.soinside.com 2019 - 2024. All rights reserved.