2015-05-02 2 views
1

В настоящее время я использую XML-объект BluringView, полученный из файла BlurringView.java (https://github.com/500px/500px-android-blur). Это в основном просто пользовательский вид, который размывает вид сестры, который находится под ним. Проблема, с которой я сталкиваюсь, заключается в том, что я не могу заполнить BlurringView другими объектами. Вот код:использовать blurview как относительный вид

package com.fivehundredpx.android.blur; 

import android.content.Context; 
import android.content.res.Resources; 
import android.content.res.TypedArray; 
import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.drawable.ColorDrawable; 
import android.support.v8.renderscript.Allocation; 
import android.support.v8.renderscript.Element; 
import android.support.v8.renderscript.RenderScript; 
import android.support.v8.renderscript.ScriptIntrinsicBlur; 
import android.util.AttributeSet; 
import android.view.View; 

/** 
* A custom view for presenting a dynamically blurred version of another view's content. 
* <p/> 
* Use {@link #setBlurredView(android.view.View)} to set up the reference to the view to be blurred. 
* After that, call {@link #invalidate()} to trigger blurring whenever necessary. 
*/ 
public class BlurringView extends View { 

public BlurringView(Context context) { 
    this(context, null); 
} 

public BlurringView(Context context, AttributeSet attrs) { 
    super(context, attrs); 

    final Resources res = getResources(); 
    final int defaultBlurRadius = res.getInteger(R.integer.default_blur_radius); 
    final int defaultDownsampleFactor = res.getInteger(R.integer.default_downsample_factor); 
    final int defaultOverlayColor = res.getColor(R.color.default_overlay_color); 

    initializeRenderScript(context); 

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PxBlurringView); 
    setBlurRadius(a.getInt(R.styleable.PxBlurringView_blurRadius, defaultBlurRadius)); 
    setDownsampleFactor(a.getInt(R.styleable.PxBlurringView_downsampleFactor, 
      defaultDownsampleFactor)); 
    setOverlayColor(a.getColor(R.styleable.PxBlurringView_overlayColor, defaultOverlayColor)); 
    a.recycle(); 
} 

public void setBlurredView(View blurredView) { 
    mBlurredView = blurredView; 
} 

@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    if (mBlurredView != null) { 
     if (prepare()) { 
      // If the background of the blurred view is a color drawable, we use it to clear 
      // the blurring canvas, which ensures that edges of the child views are blurred 
      // as well; otherwise we clear the blurring canvas with a transparent color. 
      if (mBlurredView.getBackground() != null && mBlurredView.getBackground() instanceof ColorDrawable){ 
       mBitmapToBlur.eraseColor(((ColorDrawable) mBlurredView.getBackground()).getColor()); 
      }else { 
       mBitmapToBlur.eraseColor(Color.TRANSPARENT); 
      } 

      mBlurredView.draw(mBlurringCanvas); 
      blur(); 

      canvas.save(); 
      canvas.translate(mBlurredView.getX() - getX(), mBlurredView.getY() - getY()); 
      canvas.scale(mDownsampleFactor, mDownsampleFactor); 
      canvas.drawBitmap(mBlurredBitmap, 0, 0, null); 
      canvas.restore(); 
     } 
     canvas.drawColor(mOverlayColor); 
    } 
} 

public void setBlurRadius(int radius) { 
    mBlurScript.setRadius(radius); 
} 

public void setDownsampleFactor(int factor) { 
    if (factor <= 0) { 
     throw new IllegalArgumentException("Downsample factor must be greater than 0."); 
    } 

    if (mDownsampleFactor != factor) { 
     mDownsampleFactor = factor; 
     mDownsampleFactorChanged = true; 
    } 
} 

public void setOverlayColor(int color) { 
    mOverlayColor = color; 
} 

private void initializeRenderScript(Context context) { 
    mRenderScript = RenderScript.create(context); 
    mBlurScript = ScriptIntrinsicBlur.create(mRenderScript, Element.U8_4(mRenderScript)); 
} 

protected boolean prepare() { 
    final int width = mBlurredView.getWidth(); 
    final int height = mBlurredView.getHeight(); 

    if (mBlurringCanvas == null || mDownsampleFactorChanged 
      || mBlurredViewWidth != width || mBlurredViewHeight != height) { 
     mDownsampleFactorChanged = false; 

     mBlurredViewWidth = width; 
     mBlurredViewHeight = height; 

     int scaledWidth = width/mDownsampleFactor; 
     int scaledHeight = height/mDownsampleFactor; 

     // The following manipulation is to avoid some RenderScript artifacts at the edge. 
     scaledWidth = scaledWidth - scaledWidth % 4 + 4; 
     scaledHeight = scaledHeight - scaledHeight % 4 + 4; 

     if (mBlurredBitmap == null 
       || mBlurredBitmap.getWidth() != scaledWidth 
       || mBlurredBitmap.getHeight() != scaledHeight) { 
      mBitmapToBlur = Bitmap.createBitmap(scaledWidth, scaledHeight, 
        Bitmap.Config.ARGB_8888); 
      if (mBitmapToBlur == null) { 
       return false; 
      } 

      mBlurredBitmap = Bitmap.createBitmap(scaledWidth, scaledHeight, 
        Bitmap.Config.ARGB_8888); 
      if (mBlurredBitmap == null) { 
       return false; 
      } 
     } 

     mBlurringCanvas = new Canvas(mBitmapToBlur); 
     mBlurringCanvas.scale(1f/mDownsampleFactor, 1f/mDownsampleFactor); 
     mBlurInput = Allocation.createFromBitmap(mRenderScript, mBitmapToBlur, 
       Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); 
     mBlurOutput = Allocation.createTyped(mRenderScript, mBlurInput.getType()); 
    } 
    return true; 
} 

protected void blur() { 
    mBlurInput.copyFrom(mBitmapToBlur); 
    mBlurScript.setInput(mBlurInput); 
    mBlurScript.forEach(mBlurOutput); 
    mBlurOutput.copyTo(mBlurredBitmap); 
} 

@Override 
protected void onDetachedFromWindow() { 
    super.onDetachedFromWindow(); 
    if (mRenderScript != null){ 
     mRenderScript.destroy(); 
    } 
} 

private int mDownsampleFactor; 
private int mOverlayColor; 

private View mBlurredView; 
private int mBlurredViewWidth, mBlurredViewHeight; 

private boolean mDownsampleFactorChanged; 
private Bitmap mBitmapToBlur, mBlurredBitmap; 
private Canvas mBlurringCanvas; 
private RenderScript mRenderScript; 
private ScriptIntrinsicBlur mBlurScript; 
private Allocation mBlurInput, mBlurOutput; 

}

Есть ли способ изменить класс BlurringView.java поэтому объект XML BlurringView может быть использован как RelativeView или что-то подобное? Я хочу, чтобы BlurringView был родителем для других объектов.

Мне нужно это, потому что я использую BlurringView вместе с SlidingUpPanelLayout (https://github.com/umano/AndroidSlidingUpPanel), а SlidingUpPanelLayout разрешает только двум детям. Таким образом, я не могу просто накладывать элементы поверх BlurringView. Мне нужно, чтобы BlurringView был их родителем.

Пожалуйста, дайте мне знать, если вам нужно уточнение.

-R

+1

Вы пытались сделать метод экстракта вашего конструктора, реализовать те же methon в каждом из трех конструкторов по умолчанию и простираются от 'RelativeLayout'? – 4gus71n

+0

@astinx Я попробовал то, что вы предлагали, BlurringView затем расширяется как относительный вид, но проблема в том, что он не выполняет функцию размытия. – redstonedev

+0

@astinx - Я понял, что BlurringView должен быть просто регулярным представлением для его эффекта размытия. Это связано с тем, что для достижения эффекта используется метод onDraw(). Когда BlurringView изменен на что угодно, кроме представления, метод onDraw() не может быть использован. – redstonedev

ответ

2

Blockquote Вы пытались сделать метод экстракта вашего конструктора, реализовать ту же methon в каждом из трех конструкторов по умолчанию и простираются от RelativeLayout?

У RelativeLayout действительно есть метод onDraw, возможно, он не вызывается, потому что вы не вызывали метод setWillNotDraw (false), попробуйте использовать этот метод для запуска onDraw или использования invalidate() в конце конструкторы.

@astinx ответил на этот вопрос.

Все, что мне нужно было сделать, это изменить класс BlurringView, чтобы расширить RelativeLayout вместо представления. Затем я вызвал метод setWillNotDraw (false), а также метод invalidate() в конструкторе, и теперь я могу заполнить BlurringView детьми! Магия.

-R

Смежные вопросы