使用TextView清除视图画布

时间:2015-04-21 18:53:12

标签: android android-edittext android-canvas android-relativelayout

我正在努力实现视觉效果,如果我能让它看起来很棒!我正在做的应用程序的登录看起来像这样:

enter image description here

请记住,背景上的图像是动画,会从该图像稍微过渡到另一个图像。

我想要的是使应用程序“Akrasia”的标题透明,但透明意味着您可以通过标题字母在背景中看到图像,这意味着我必须以某种方式覆盖onDraw包含此表单的RelativeLayout的方法。我试着这样做,但我唯一得到的就是错误。也许我错误地尝试覆盖onDrawTextView两者中的RelativeLayout方法,也许这是最简单的方法。你怎么看?或者也许不可能达到这种效果?

更新

它应该是这样的。

enter image description here

此外,我尝试制作一个从TextView扩展的自定义视图,其方法setBackgroundView将视图实例存储到字段中。稍后在onDraw方法上,我设法从背景图像中获取位图。但我不知道如何使用画布绘制它。

更新 我让它工作!现在我只需要通过背景的可绘制来改变蓝色背景。

enter image description here

观点:

final public class SeeThroughTextView extends TextView
{
    Bitmap mMaskBitmap;
    Canvas mMaskCanvas;
    Paint mPaint;

    Drawable mBackground;
    Bitmap mBackgroundBitmap;
    Canvas mBackgroundCanvas;
    boolean mSetBoundsOnSizeAvailable = false;

    public SeeThroughTextView(Context context)
    {
        super(context);
        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
    }

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

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



    @Override
    @Deprecated
    public void setBackgroundDrawable(Drawable bg)
    {
        mBackground = bg;
        int w = bg.getIntrinsicWidth();
        int h = bg.getIntrinsicHeight();

        // Drawable has no dimensions, retrieve View's dimensions
        if (w == -1 || h == -1)
        {
            w = getWidth();
            h = getHeight();
        }

        // Layout has not run
        if (w == 0 || h == 0)
        {
            mSetBoundsOnSizeAvailable = true;
            return;
        }

        mBackground.setBounds(0, 0, w, h);
        invalidate();
    }



    @Override
    public void setBackgroundColor(int color)
    {
        setBackgroundDrawable(new ColorDrawable(color));
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        super.onSizeChanged(w, h, oldw, oldh);
        mBackgroundBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mBackgroundCanvas = new Canvas(mBackgroundBitmap);
        mMaskBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mMaskCanvas = new Canvas(mMaskBitmap);

        if (mSetBoundsOnSizeAvailable)
        {
            mBackground.setBounds(0, 0, w, h);
            mSetBoundsOnSizeAvailable = false;
        }
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        // Draw background
        mBackground.draw(mBackgroundCanvas);

        // Draw mask
        mMaskCanvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR);
        super.onDraw(mMaskCanvas);

        mBackgroundCanvas.drawBitmap(mMaskBitmap, 0.f, 0.f, mPaint);
        canvas.drawBitmap(mBackgroundBitmap, 0.f, 0.f, null);
    }
}

在我的片段中,我有这个,因为背景中的动画:

vBackground.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                vTitle.setBackgroundDrawable(new BitmapDrawable(vBackground.getDrawingCache()));
                vTitle.invalidate();
            }
        });

2 个答案:

答案 0 :(得分:2)

钉!

enter image description here

观点:

final public class SeeThroughTextView extends TextView
{
    Bitmap mMaskBitmap;
    Canvas mMaskCanvas;
    Paint mPaint;

    Drawable mBackground;
    Bitmap mBackgroundBitmap;
    Canvas mBackgroundCanvas;
    boolean mSetBoundsOnSizeAvailable = false;

    public SeeThroughTextView(Context context)
    {
        super(context);
        init();
    }

    private void init() {
        Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/gillsans.ttf");
        setTypeface(myTypeface);
        mPaint = new Paint();
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
    }

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

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



    @Override
    @Deprecated
    public void setBackgroundDrawable(Drawable bg)
    {
        mBackground = bg;
        int w = bg.getIntrinsicWidth();
        int h = bg.getIntrinsicHeight();

        // Drawable has no dimensions, retrieve View's dimensions
        if (w == -1 || h == -1)
        {
            w = getWidth();
            h = getHeight();
        }

        // Layout has not run
        if (w == 0 || h == 0)
        {
            mSetBoundsOnSizeAvailable = true;
            return;
        }

        mBackground.setBounds(0, 0, w, h);
        invalidate();
    }



    @Override
    public void setBackgroundColor(int color)
    {
        setBackgroundDrawable(new ColorDrawable(color));
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        super.onSizeChanged(w, h, oldw, oldh);
        mBackgroundBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mBackgroundCanvas = new Canvas(mBackgroundBitmap);
        mMaskBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mMaskCanvas = new Canvas(mMaskBitmap);

        if (mSetBoundsOnSizeAvailable)
        {
            mBackground.setBounds(0, 0, w, h);
            mSetBoundsOnSizeAvailable = false;
        }
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        // Draw background
        mBackground.draw(mBackgroundCanvas);

        // Draw mask
        mMaskCanvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR);
        super.onDraw(mMaskCanvas);

        mBackgroundCanvas.drawBitmap(mMaskBitmap, 0.f, 0.f, mPaint);
        canvas.drawBitmap(mBackgroundBitmap, 0.f, 0.f, null);
    }
}

在我的片段中:

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    vLoginBtn = (Button) view.findViewById(R.id.btn_login);
    vRegistrationBtn = (Button) view.findViewById(R.id.btn_registration);
    vForgotBtn = (Button) view.findViewById(R.id.btn_forgot);
    vBackground = (KenBurnsView) view.findViewById(R.id.login_background);
    vTitle = (SeeThroughTextView) view.findViewById(R.id.txt_view_login_title);
    vBackground.setResourceUrls(
            "http://www.youwall.com/papel/peaceful_place_wallpaper_4f3f3.jpg",
            "http://www.fwallpaper.net/wallpapers/P/E/Peaceful-Scenary_1920x1200.jpg",
            "http://p1.pichost.me/i/39/1620902.jpg"
    );
    vBackground.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
            vTitle.setBackgroundDrawable(getResources().getDrawable(R.drawable.drawable_background_login_top));
            vTitle.invalidate();
            vBackground.removeOnLayoutChangeListener(this);
        }
    });

}

抽屉只有两种形状,一种是左上角和右上角,半径为10dp,另一种是半径为底部。 具有顶部可绘制形状的自定义TextViewRelativeLayout上方包含EditText s。 没有多少火箭科学。非常感谢 @Klotor 提出这个想法!

答案 1 :(得分:1)

res/values/colors.xml文件中指定一种新颜色(如果它不存在则创建一个颜色),该文件可能如下所示:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="ltGray">#33999999</color>
</resources>

其中前两个数字是透明度(00 - 完全透明,FF - 完全不透明)。

然后只需在该布局的xml中将所需TextView的文字颜色设置为@color/ltGray,或者转到 tvTitle.setTextColor(getResources().getColor(R.color.ltGray)) 在设置TextView

之后