创建由其他自定义视图制作的自定义视图

时间:2013-11-19 16:16:08

标签: java android xml relativelayout android-custom-view

我正在尝试创建由其他自定义视图组成的自定义视图。这些视图扩展了View类。我正在尝试创建的自定义视图是游戏的标题,目前可在iOS上使用,它由8个NodeViews制成,每个字母对应一个游戏标题,Word Flow。

我希望TitleView自定义视图具有灵活性,因为我可以使用attrs.xml定义它的大小,因此可以为不同的屏幕密度设置不同的版本。

我面临的主要问题是:如何在TitleView中正确定位这些NodeView? 这是TitleView的样子:

1

这是我的NodeView类代码:

package com.limeshift.wordflow;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

public class NodeView extends View {

    int nodeColour;
    String nodeText;
    Paint backgroundPaint = new Paint();
    Paint textPaint = new Paint();

    public NodeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(
                attrs,
                R.styleable.NodeView,
                0, 0);

        try {
            nodeText = a.getString(R.styleable.NodeView_nodeText);
            nodeColour = a.getColor(R.styleable.NodeView_nodeColour, 0);
        } finally {
            a.recycle();
        }
    }


    public int getNodeColour() {
        return nodeColour;
    }

    public void setNodeColour(int colour) {
        nodeColour = colour;
        invalidate();
        requestLayout();
    }

    public String getNodeText() {
        return nodeText;
    }

    public void setNodeText(String text) {
        nodeText = text;
        invalidate();
        requestLayout();
    }

    @Override
    public void onMeasure(int w, int h) {
        super.onMeasure(w, h);

        w = getResources().getDimensionPixelSize(R.dimen.title_node_size);
        h = getResources().getDimensionPixelSize(R.dimen.title_node_size);

        setMeasuredDimension(w, h);
    }

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

        //NodeView background
        backgroundPaint.setColor(getNodeColour());
        backgroundPaint.setAntiAlias(true);
        canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, getMeasuredHeight() / 2, backgroundPaint);

        //NodeView text
        textPaint.setColor(getResources().getColor(R.color.white));

        Typeface tf = Typeface.createFromAsset(getResources().getAssets(), "fonts/dosis_centered.ttf");
        textPaint.setTypeface(tf);

        textPaint.setAntiAlias(true);
        textPaint.setTextSize(getResources().getDimensionPixelSize(R.dimen.title_node_text_size));
        textPaint.setTextAlign(Paint.Align.CENTER);

        int xPos = (canvas.getWidth() / 2);
        int yPos = (int) ((canvas.getHeight() / 2) - ((textPaint.descent() + textPaint.ascent()) / 2));

        canvas.drawText(getNodeText(), xPos, yPos, textPaint);
    }
}

它使用两个自定义XML属性< declare-styleable>标签。 NodeView现在只是一个基本的圆圈,颜色从菜单活动的XML布局传入,而字母则使用自定义字体。

在iOS中,可以定义所有内容的绝对位置,使得创建这样的标题非常简单,而我在Android上最接近的就是RelativeLayout,它允许我使用边距定位NodeView并说明如何节点相对于彼此或父节点定位。但这不太实用。

如果我可以指定节点的中心位置,我真的很喜欢它。

感谢阅读。

1 个答案:

答案 0 :(得分:0)

您的TitleView应该布局NodeView,您可以通过扩展ViewGroup并覆盖onLayout来实现