2011-07-05 74 views
16

我發現如何change the opacity of a View,但我需要實際變暗View。我最好的想法是在它上面放一個透明的黑色矩形,然後慢慢增加矩形的不透明度。以編程方式變暗視圖android

你知道更好的方法嗎?

public class Page07AnimationView extends ParentPageAnimationView { 
    private final String TAG = this.getClass().getSimpleName(); 
    private ImageView overlay; 
    private int mAlpha = 0; 

    public Page07AnimationView(Context context) { 
     super(context); 
    } 

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

    protected void init() 
    { 
     overlay = new ImageView(mContext); 
     overlay.setImageResource(R.drawable.black_background); 
     overlay.setAlpha(0); 
     overlay.setWillNotDraw(false); 
     // make the PageAniSurfaceView focusable so it can handle events 
     setFocusable(true); 
    } 

    protected void draw_bitmaps(Canvas canvas) 
    { 
     overlay.draw(canvas); 
     update_bitmaps(); 
     invalidate(); 
    } 

    public void update_bitmaps() 
    { 
     if(mAlpha < 250) 
     { 
      mAlpha += 10; 
      overlay.setAlpha(mAlpha); 
     } 
    } 
} 

上面的代碼沒有做我希望的。 Page07AnimationView被添加到我需要變暗的視圖上的FrameLayoutR.drawable.black_background指向787px x 492px黑色png圖像。

我加了overlay.setWillNotDraw(false);但它沒有幫助。 我將第一個setAlpha(0)更改爲setAlpha(255),但這並沒有幫助。 我完全刪除了setAlpha()調用,但它沒有幫助。

添加PageNNAnimationView這種基本技術一直在努力繪製Bitmaps,但不繪製ImageView overlay。 (我會用Bitmaps,但他們似乎並不有一個alpha分量。)

EDIT2:這是上面的類的父:

public class ParentPageAnimationView extends View { 
    private final String TAG = this.getClass().getSimpleName(); 
    protected Context mContext; 

    public ParentPageAnimationView(Context context) { 
     super(context); 
     mContext = context; 
     init(); 
    } 

    public ParentPageAnimationView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     mContext = context; 
     init(); 
    } 

    protected void init() 
    { 
    } 

    protected void draw_bitmaps(Canvas canvas) 
    { 
     // will be overridden by child classes 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     if(this.getVisibility() == View.VISIBLE) 
     { 
      if(canvas != null) 
      { 
       draw_bitmaps(canvas); 
      } 
     } 
    } 

    public void update_bitmaps() 
    { 
     // will be overridden by child classes 
    } 

    public void elementStarted(PageElement _pageElement) { 
     // Nothing in parent class 
    } 

    public void elementFinished(PageElement mElement) { 
     // Nothing in parent class 
    } 
} 
+0

我已經證實,draw_bitmaps和update_bitmaps被重複調用。 –

回答

10

我寧願做相反的方式 - 在視圖後面放置一個黑色矩形,並設置視圖的不透明度。這可以在視圖100%不透明時節省繪製矩形。

+0

這是一個整潔的想法!儘管如此,我認爲我受限於在視圖上做某些事情,因爲我已經佈置了佈局。但是,他們背後的動畫布局*可能會解決另一個問題;謝謝! –

+0

在半透明視圖後面運行動畫時,可能會觸發重新繪製整個屏幕。在模擬器的DevTools中啓用「顯示屏幕更新」並查看重新繪製的內容。 – JBM

1

你可以嘗試使用奧飛動漫這樣的(也許在矩形):

Animation animation = new AlphaAnimation(0.0f, 1.0f); 
    animation.setDuration(350); 

,將導致矩形逐漸成爲了350秒不透明......

+2

我認爲當他說*更好*他的意思是「更合適」,而不是「cuter」 – JBM

0

您應該檢查iPaulPro的在this question回答。您需要延長ImageView並覆蓋onDraw()方法。

根據你將要做的事情,Alexandru Cristescu的回答也是有效的,但你應該 致電setFillAter(true)讓動畫在完成後繼續。

2

這就是我最終做到的。關鍵是使用一個Paint,它的alpha設置爲我想要的任何東西。

public class Page07AnimationView extends ParentPageAnimationView { 
    private final String TAG = this.getClass().getSimpleName(); 
    private Bitmap bitmap; 
    private BitmapDrawable drawable; 
    private ImageView overlay; 
    private int which = -1; 
    private long last_time; 
    private Page07State state; 
    private int mAlpha; 
    private int maxAlpha; 
    private Paint mPaint; 
    private int _alpha_step; 
    private int minAlpha; 

    public enum Page07State { 
     WAITING, DARKENING, DARKENED 
    } 

    public Page07AnimationView(Context context) { 
     super(context); 
    } 

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

    protected void init() 
    { 
     minAlpha = 0; 
     mAlpha = minAlpha; 
     _alpha_step = 5; 
     maxAlpha = 255; 
     mPaint = new Paint(); 
     mPaint.setAlpha(minAlpha); 
     state = Page07State.WAITING; 
     overlay = new ImageView(mContext); 
     overlay.setImageResource(R.drawable.black_background); 
     drawable = (BitmapDrawable) overlay.getDrawable(); 
     bitmap = drawable.getBitmap(); 
     last_time = 0; 
    } 

    protected void draw_bitmaps(Canvas canvas) 
    { 
     if(state != Page07State.WAITING) 
     { 
      DebugLog.d(TAG, "drawing " + Integer.toString(which)); 
      canvas.drawBitmap(bitmap, 0, 0, mPaint); 
     } 
     update_bitmaps(); 
     invalidate(); 
    } 

    public void update_bitmaps() 
    { 
     if(state == Page07State.DARKENING) 
     { 
      if(mAlpha < maxAlpha) 
      { 
       if(System.currentTimeMillis() > last_time + 12) 
       { 
        last_time = System.currentTimeMillis(); 
        mAlpha += _alpha_step; 
        mPaint.setAlpha(mAlpha); 
       } 
      } 
      else 
      { 
       state = Page07State.DARKENED; 
      } 
     } 
    } 

    public void runAnimation() 
    { 
     state = Page07State.DARKENING; 
    } 
} 
28

在ImageView的情況下,這裏有一個方法來實現它:

imageView.setColorFilter(Color.rgb(123, 123, 123), android.graphics.PorterDuff.Mode.MULTIPLY); 
+0

這是否使用更多或更少的資源,然後設置'.setAlpha((float)1.0)'(對於sdk 11或更高)或'。 setAlpha(100)'(對於sdk 11和以下)。我問的原因是因爲即時設置不透明度來實現這一點,如果我可以打電話給它,如果它更兼容,那就太棒了。 –

+0

@AaronRussell我認爲如果你使用setAlpha,它會更好,因爲它可能是GPU優化的。當然,我可能是錯的。最好的事情應該是始終使用最新的API函數。 –

6

我會做這樣的事情:

view.getBackground().setColorFilter(color, PorterDuff.Mode.DARKEN); 

使用黑色與一些阿爾法像0x7f000000爲典型的變黑。

它更加簡潔,您還可以通過動畫或滾動事件將View變暗。只需將Color.argb(alpha, 0, 0, 0)設置爲顏色並設置爲alpha,或者根據滾動偏移更改它。

2

添加到Android開發者的回答是:

imageView.setColorFilter(Color.rgb(123, 123, 123), android.graphics.PorterDuff.Mode.MULTIPLY); 

,你可以在任何像這樣的觀點setColorFilter:

GradientDrawable gd = (GradientDrawable) textView.getBackground(); 
gd.setColor(color); //you can also set BG color to a textview like this 
gd.setColorFilter(Color.rgb(123, 123, 123), android.graphics.PorterDuff.Mode.MULTIPLY);