关于foreground与background的区别

xiaoxiao2021-02-28  38

关于foreground与background的区别


先看字面翻译,background是背景色foreground 也就是前景色,也就是说foreground与background相对应,顾名思义,foreground指定的drawable是在view视图的上方绘制的。

先写一个简单的布局

<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="QWERTYUIOPASDFGHJKLZXCVBNM" /> </FrameLayout>

我们在FrameLayout中包了一个TextView这时候FrameLayout既没有设置background,也没设置foreground。显示是这样的

这时候我们给FrameLayout加上android:background=”@color/colorPrimary”效果如下

我们再给FrameLayout加上android:foreground=”@color/colorAccent”效果变成这样:

这时候连TextView都不见了,所以可以发现一般可以用foreground来实现一些遮罩层效果.

对了,忘记说了,虽然Android在所有布局的基类 View 类中 就定义了 Foreground 这个属性,但是测试发现 运行时,只有FrameLayout布局上设置该属性才会生效。观察View的代码发现这样一段。它只针对是FrameLayout的实例做获取该styleable的操作。

解决方案如下:

模拟,FrameLayout的相关实现为TextView添加foreGround的代码功能

public class ForegroundTextView extends TextView { // UI private Drawable foreground; // Controller/logic fields private final Rect rectPadding = new Rect(); private boolean foregroundPadding = false; private boolean foregroundBoundsChanged = false; private boolean backgroundAsForeground = false; // Constructors public ForegroundTextView(Context context) { super(context); } public ForegroundTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ForegroundTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ForegroundLayout, defStyle, 0); final Drawable d = a.getDrawable(R.styleable.ForegroundLayout_foreground); foregroundPadding = a.getBoolean(R.styleable.ForegroundLayout_foregroundInsidePadding, false); backgroundAsForeground = a.getBoolean(R.styleable.ForegroundLayout_backgroundAsForeground, false); // Apply foreground padding for ninepatches automatically if (!foregroundPadding && getBackground() instanceof NinePatchDrawable) { final NinePatchDrawable npd = (NinePatchDrawable) getBackground(); if (npd != null && npd.getPadding(rectPadding)) { foregroundPadding = true; } } final Drawable b = getBackground(); if (backgroundAsForeground && b != null) { setForeground(b); } else if (d != null) { setForeground(d); } a.recycle(); } /** * Supply a Drawable that is to be rendered on top of all of the child views in the layout. * * @param drawable The Drawable to be drawn on top of the children. */ public void setForeground(Drawable drawable) { if (foreground != drawable) { if (foreground != null) { foreground.setCallback(null); unscheduleDrawable(foreground); } foreground = drawable; if (drawable != null) { setWillNotDraw(false); drawable.setCallback(this); if (drawable.isStateful()) { drawable.setState(getDrawableState()); } } else { setWillNotDraw(true); } requestLayout(); invalidate(); } } /** * Returns the drawable used as the foreground of this layout. The foreground drawable, * if non-null, is always drawn on top of the children. * * @return A Drawable or null if no foreground was set. */ public Drawable getForeground() { return foreground; } @Override protected void drawableStateChanged() { super.drawableStateChanged(); if (foreground != null && foreground.isStateful()) { foreground.setState(getDrawableState()); } } @Override protected boolean verifyDrawable(Drawable who) { return super.verifyDrawable(who) || (who == foreground); } @Override public void jumpDrawablesToCurrentState() { super.jumpDrawablesToCurrentState(); if (foreground != null) { foreground.jumpToCurrentState(); } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); foregroundBoundsChanged = true; } @Override public void draw(Canvas canvas) { super.draw(canvas); if (foreground != null) { final Drawable foreground = this.foreground; if (foregroundBoundsChanged) { foregroundBoundsChanged = false; final int w = getRight() - getLeft(); final int h = getBottom() - getTop(); if (foregroundPadding) { foreground.setBounds(rectPadding.left, rectPadding.top, w - rectPadding.right, h - rectPadding.bottom); } else { foreground.setBounds(0, 0, w, h); } } foreground.draw(canvas); } } @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public boolean onTouchEvent(MotionEvent e) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (e.getActionMasked() == MotionEvent.ACTION_DOWN) { if (foreground != null) { foreground.setHotspot(e.getX(), e.getY()); } } } return super.onTouchEvent(e); } }

以上代码来自:http://blog.csdn.net/zhuoxiuwu/article/details/50976145

转载请注明原文地址: https://www.6miu.com/read-620704.html

最新回复(0)