2012-06-24 24 views
35

Tôi đang cố gắng tạo một hình dạng có thể vẽ được với nền gradient hướng tâm, với bán kính sẽ điều chỉnh kích thước màn hình (hãy xem documentation có liên quan).Gradient Radius là phần trăm kích thước màn hình

Đây là mã của tôi:

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle" > 

    <gradient 
     android:endColor="#000" 
     android:gradientRadius="50%p" 
     android:startColor="#5d2456" 
     android:type="radial" /> 
</shape> 

Nhưng nó doens't có vẻ làm việc. nếu tôi loại bỏ "% p", nó hoạt động, nhưng sau đó bán kính sẽ được tĩnh, do đó không điều chỉnh kích thước màn hình ... Bất kỳ ý tưởng gì là sai?

+0

gradientRadius là thuộc tính dựa trên giá trị số nguyên. Đặt một phần trăm hoặc bất kỳ loại giá trị đo lường nào sẽ không hoạt động. Tôi biết đây không phải là câu trả lời bạn đang tìm kiếm nhưng ít nhất nó sẽ giúp thu hẹp những gì bạn đang tìm kiếm. – Sababado

+0

Cùng một vấn đề ở đây (ít nhất là khi xem trước bố cục của tôi trong Eclipse): gradient không được áp dụng nếu bán kính được chỉ định bằng '%' hoặc '% p' –

+0

Phần tồi tệ nhất là nó không hoạt động ngay cả khi tôi có tài nguyên số nguyên được định nghĩa ở nơi khác, và tham khảo ở đây (@ integer/gradientRadius). Dường như chỉ chấp nhận các số nguyên được mã hóa tuyệt đối. – Gunanaresh

Trả lời

0

Bạn có thể tạo một drawable hình tại tương tự runtime bài này https://stackoverflow.com/a/4943888/604504

Bằng cách này bạn có thể tính toán tỷ lệ phần trăm sau khi lấy các kích thước màn hình.

8

tôi đã kết thúc việc tạo ra một Xem tùy chỉnh với sau đây overriden onDraw phương pháp:

@Override 
protected void onDraw(Canvas canvas) { 
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); 

    int maxSize = Math.max(getHeight(), getWidth()); 
    RadialGradient gradient = new RadialGradient(
      getWidth()/2, 
      getHeight()/2, 
      maxSize, 
      new int[] {Color.RED, Color.BLACK}, 
      new float[] {0, 1}, 
      android.graphics.Shader.TileMode.CLAMP); 

    paint.setDither(true); 
    paint.setShader(gradient); 

    canvas.drawRect(0, 0, getWidth(), getHeight(), paint); 
} 

Trong cách bố trí của bạn chỉ cần thêm Xem:

<yourpackage.GradientView 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

Tất nhiên nó sẽ có thể phải tạo thuộc tính cho Xem, ví dụ: màu sắc, tỷ lệ phần trăm để cho phép tùy chỉnh thông qua XML.

11

Từ những gì tôi đã thử nghiệm, % không hoạt động, nhưng không như bạn mong đợi.
Trước hết

android:gradientRadius="50" 

dường như mất giá trị như pixel 50px

android:gradientRadius="50%" 

được chuyển đổi, nếu như 50% = 0,5 px, hãy thử

android:gradientRadius="5000%" 

và bạn sẽ thấy một Bán kính 50px.
Sử dụng %p có kết quả tương tự. Rõ ràng đây là điều tôi hy vọng sẽ được thay đổi trong tương lai, bởi vì nó không có nhiều sử dụng như nó được. Thông thường, các tài nguyên XML ShapeDrawable có thể điều chỉnh kích thước của chúng cho một số vùng chứa bên ngoài, trong trường hợp này, gradientRadius đang đặt kích thước bất kể vùng chứa.

+7

"50000% p" giống với "50", như ilomambo đã nói trước đây, vì vậy nếu bạn muốn một số khả năng đọc, bạn không nên sử dụng nó. – Joan

+3

Giải pháp tốt hơn là sử dụng các thư mục giá trị-mdpi, giá trị-hdpi và cung cấp các giá trị làm mờ khác nhau và tham chiếu chúng trong trường giá trị bán kính. –

5

Lưu ý rằng tỷ lệ phần trăm gradientRadius hoạt động trong Lollipop. Nhưng nếu bạn phải hỗ trợ trước Lollipop, tôi mở rộng khi câu trả lời của @ marnaish thêm các thuộc tính XML. gradientRadius của tôi được định nghĩa là một tỷ lệ phần trăm của chiều rộng quan điểm của cha mẹ:

public class RadialGradientView extends View { 
    private final int endColor; 
    private final int startColor; 
    private final float gradientRadiusWidthPercent; 
    private final float centerY; 
    private final float centerX; 
    private Paint paint; 

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

     TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RadialGradientView, 0, 0); 

     startColor = a.getColor(R.styleable.RadialGradientView_startColor, Color.RED); 
     endColor = a.getColor(R.styleable.RadialGradientView_endColor, Color.BLACK); 
     gradientRadiusWidthPercent = a.getFloat(R.styleable.RadialGradientView_gradientRadiusWidthPercent, 1); 
     centerX = a.getFloat(R.styleable.RadialGradientView_centerX, .5f); 
     centerY = a.getFloat(R.styleable.RadialGradientView_centerY, .5f); 

     a.recycle(); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
     int parentWidth = MeasureSpec.getSize(widthMeasureSpec); 
     int parentHeight = MeasureSpec.getSize(heightMeasureSpec); 

     paint = new Paint(Paint.ANTI_ALIAS_FLAG); 
     RadialGradient gradient = new RadialGradient(
       parentWidth*centerX, 
       parentHeight*centerY, 
       parentWidth*gradientRadiusWidthPercent, 
       new int[] {startColor, endColor}, 
       null, 
       android.graphics.Shader.TileMode.CLAMP); 

     paint.setDither(true); 
     paint.setShader(gradient); 

    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     canvas.drawRect(0, 0, getWidth(), getHeight(), paint); 
    } 

} 

Trong attrs.xml:

<declare-styleable name="RadialGradientView"> 
    <attr name="startColor" format="color|reference"/> 
    <attr name="endColor" format="color|reference"/> 
    <attr name="gradientRadiusWidthPercent" format="float"/> 
    <attr name="centerX" format="float"/> 
    <attr name="centerY" format="float"/> 
</declare-styleable> 

Đáng tiếc là bạn không thể tạo một drawable XML từ một lớp tùy chỉnh, vì vậy bạn có thể' Đặt nó làm android: background. Cách giải quyết là sử dụng FrameLayout để lớp nó làm nền.

<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="100dp"> 

    <com.RadialGradientView 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     app:centerX=".3" 
     app:centerY=".5" 
     app:endColor="#0f0" 
     app:startColor="#f00" 
     app:gradientRadiusWidthPercent=".5" 
     /> 
    <TextView 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:gravity="center" 
     android:text="What's up world?"/> 
</FrameLayout>