2016-11-25 4 views
0

Как вы, возможно, знаете, невозможно использовать овальный радиальный градиент с помощью обычного API Android.Память овального градиента

Это то, что я хочу добиться:

Expected effect

Так я реализовал это решение: нарисовать регулярный радиальный градиент на площади растрового изображения, а затем это растровый получат растянутый самое зрение (идея нашла здесь: https://stackoverflow.com/a/3543899/649910)

Это прекрасно работает, однако это решение занимает много памяти из-за использования BitmapDrawable (см. подробности реализации ниже).

Любые идеи о том, как избежать использования такого большого растрового изображения, приветствуются!

Это мой код:

public class OvalGradientView extends ImageView { 

    private Drawable defaultBackgroundDrawable; 

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

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

    public OvalGradientView(Context context, AttributeSet attrs, int defStyleAttr, Paint paint) { 
     super(context, attrs, defStyleAttr); 
     init(); 
    } 

    private void init() { 
     setScaleType(ScaleType.FIT_XY); 
     defaultBackgroundDrawable = getResources().getDrawable(R.drawable.default_background); 
    } 

    @Override 
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
     super.onLayout(changed, left, top, right, bottom); 
     int width = getWidth(); 
     int height = getHeight(); 
     Rect currentBounds = defaultBackgroundDrawable.getBounds(); 
     // check if we already have bitmap for these bounds 
     if (currentBounds.right == width && currentBounds.bottom == height) { 
      return; 
     } 
     // draw the drawable on square bitmap, it will be then stretched if needed to rectangular shape 
     // as the view gets more rectangular 
     defaultBackgroundDrawable.setBounds(0, 0, width, width); 
     Bitmap defaultBackgroundBitmap = Bitmap.createBitmap(width, width, Bitmap.Config.ARGB_8888); 
     Canvas canvas = new Canvas(defaultBackgroundBitmap); 
     defaultBackgroundDrawable.draw(canvas); 
     setImageBitmap(defaultBackgroundBitmap); 
    } 
} 

И это вытяжке XML - default_background

<shape xmlns:android="http://schemas.android.com/apk/res/android"> 
    <gradient 
     android:startColor="#ffffff" 
     android:endColor="#ff6600" 
     android:gradientRadius="50%p" 
     android:type="radial" /> 
</shape 

ответ

0

Я закончил с этой реализации:

public class MyBackgroundView extends ImageView { 

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

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

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

    { 
     setBackgroundResource(R.drawable.my_background); 
     setScaleType(ScaleType.FIT_XY); 
    } 

    @Override 
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
     super.onLayout(changed, left, top, right, bottom); 

     if (!changed) { 
      return; 
     } 

     int width = right - left; 
     int height = bottom - top; 
     float aspectRatio = (float) width/height; 
     if (aspectRatio > 1f) { 
      setScaleX(aspectRatio); 
     } else { 
      setScaleY(1/aspectRatio); 
     } 
    } 
} 

где my_background является :

<shape xmlns:android="http://schemas.android.com/apk/res/android"> 
    <gradient 
     android:startColor="@color/my_background_start_color" 
     android:endColor="@color/my_background_end_color" 
     android:gradientRadius="@fraction/my_background_gradient_radius_percent" 
     android:type="radial" /> 
</shape> 

Ширина и высота этого представления совпадают.

1

Я не стал бы доверять свою собственную способность создавать растровые изображения, как это, особенно, если они находятся в полноэкранном режиме , Почему бы не применить форму xml в качестве фона для представления контейнера в xml? Это будет растягиваться до пропорций зрения, если ширина и высота match_parent

public class OvalGradientView extends ImageView { 
    public OvalGradientView(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     inflater.inflate(R.layout.my_sexy_gradient, this, true); 
    } 
} 

my_sexy_gradient.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:background="@drawable/default_background"/> 
Смежные вопросы