Android ColorDrawableの件
2451 ワード
今日開発の過程で1つのとても卵の痛みの問題に出会って、最終的に発見するのは系統的な質問で、総括する価値があります.
前提条件
AdapterベースのLinearLayoutを実装するときは、最初のViewの間に間隔線(Divider)を描き、Drawableオブジェクトを受信することが前提です.
スペーサ線を描くとき、私のコードは次のようになります.
各Childの下に区切り線を描画し,このアルゴリズムは問題ない.
使用時にColorDrawableオブジェクトを設定し、4.xのシステム上は、全く問題ありませんが、2.xのシステムの上で、Linearlayout全体の背景色が私が設定したDividerの色になったのはおかしいですね.私はずっと私のアルゴリズムに問題があるかどうか疑っていましたが、最終的に一つ一つ排除して、Drawableを描く問題を発見して、最後にソースコードを出して見て、やはり、2.xバージョンのColorDrawableと4.xのdraw()メソッドの実装は異なります.
2.xバージョンのColorDrawable#draw()実装:
簡単にCanvas全体にカラーを描くので、View全体が指定された色になります
4.xバージョンのColorDrawable#draw()実装
どうやってこの問題を解決しますか?
簡単です.dividerを描画する前に、指定したboundでCanvasを切り取ります.
これで大丈夫です.
まとめ:
Androidも一歩一歩完備しているとしか言いようがありませんが、そのソースコードもどんどん進歩しています.これは良いことです.これは同時に、Androidアプリケーションを開発する際に、OSバージョンの違いに注意しなければなりません.Googleが新しいOSを発売するたびに、新しい機能、新しい改善に注目しなければなりません.これにより、開発過程においてもこのようなリスクを低減することができます.
前提条件
AdapterベースのLinearLayoutを実装するときは、最初のViewの間に間隔線(Divider)を描き、Drawableオブジェクトを受信することが前提です.
スペーサ線を描くとき、私のコードは次のようになります.
private void drawVerticalDividers(Canvas canvas) {
int count = mShowLastDivider ? getChildCount() : (getChildCount() - 1);
if (null != mDivider && count > 0) {
int height = mDividerSize;
int top = 0;
int offset = (mSpace - height) / 2;
View child = null;
Rect bounds = mTempRect;
bounds.left = getPaddingLeft();
bounds.right = bounds.left + getWidth() - getPaddingRight();
for (int i = 0; i < count; ++i) {
child = getChildAt(i);
top = child.getBottom() + offset;
bounds.top = top;
bounds.bottom = top + height;
drawDivider(canvas, bounds);
}
}
}
各Childの下に区切り線を描画し,このアルゴリズムは問題ない.
使用時にColorDrawableオブジェクトを設定し、4.xのシステム上は、全く問題ありませんが、2.xのシステムの上で、Linearlayout全体の背景色が私が設定したDividerの色になったのはおかしいですね.私はずっと私のアルゴリズムに問題があるかどうか疑っていましたが、最終的に一つ一つ排除して、Drawableを描く問題を発見して、最後にソースコードを出して見て、やはり、2.xバージョンのColorDrawableと4.xのdraw()メソッドの実装は異なります.
2.xバージョンのColorDrawable#draw()実装:
@Override
public void draw(Canvas canvas) {
canvas.drawColor(mState.mUseColor);
}
簡単にCanvas全体にカラーを描くので、View全体が指定された色になります
4.xバージョンのColorDrawable#draw()実装
@Override
public void draw(Canvas canvas) {
if ((mState.mUseColor >>> 24) != 0) {
mPaint.setColor(mState.mUseColor);
canvas.drawRect(getBounds(), mPaint);
}
}
boundsを描画するRectなので、その描画領域は私が指定したboundです.どうやってこの問題を解決しますか?
簡単です.dividerを描画する前に、指定したboundでCanvasを切り取ります.
final Drawable divider = mDivider;
if (null != divider) {
canvas.save();
canvas.clipRect(bounds);
divider.setBounds(bounds);
divider.draw(canvas);
canvas.restore();
}
これで大丈夫です.
まとめ:
Androidも一歩一歩完備しているとしか言いようがありませんが、そのソースコードもどんどん進歩しています.これは良いことです.これは同時に、Androidアプリケーションを開発する際に、OSバージョンの違いに注意しなければなりません.Googleが新しいOSを発売するたびに、新しい機能、新しい改善に注目しなければなりません.これにより、開発過程においてもこのようなリスクを低減することができます.