답변:
나는 당신이 XML (적어도 안드로이드에서는 아님)로 이것을 할 수 있다고 생각하지 않지만, 여기 에 게시 되어 큰 도움이 될만한 좋은 해결책을 찾았습니다 !
ShapeDrawable.ShaderFactory sf = new ShapeDrawable.ShaderFactory() {
@Override
public Shader resize(int width, int height) {
LinearGradient lg = new LinearGradient(0, 0, width, height,
new int[]{Color.GREEN, Color.GREEN, Color.WHITE, Color.WHITE},
new float[]{0,0.5f,.55f,1}, Shader.TileMode.REPEAT);
return lg;
}
};
PaintDrawable p=new PaintDrawable();
p.setShape(new RectShape());
p.setShaderFactory(sf);
기본적으로 int 배열을 사용하면 여러 색상 정지 점을 선택할 수 있으며 다음 float 배열은 해당 정지 점이 배치되는 위치를 정의합니다 (0에서 1까지). 그런 다음 명시된대로 표준 Drawable로 사용할 수 있습니다.
편집 : 시나리오에서 이것을 사용하는 방법은 다음과 같습니다. XML로 정의 된 Button이 있다고 가정 해 봅시다.
<Button
android:id="@+id/thebutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Press Me!"
/>
그런 다음 onCreate () 메소드에 다음과 같은 것을 넣으십시오.
Button theButton = (Button)findViewById(R.id.thebutton);
ShapeDrawable.ShaderFactory sf = new ShapeDrawable.ShaderFactory() {
@Override
public Shader resize(int width, int height) {
LinearGradient lg = new LinearGradient(0, 0, 0, theButton.getHeight(),
new int[] {
Color.LIGHT_GREEN,
Color.WHITE,
Color.MID_GREEN,
Color.DARK_GREEN }, //substitute the correct colors for these
new float[] {
0, 0.45f, 0.55f, 1 },
Shader.TileMode.REPEAT);
return lg;
}
};
PaintDrawable p = new PaintDrawable();
p.setShape(new RectShape());
p.setShaderFactory(sf);
theButton.setBackground((Drawable)p);
나는 현재 이것을 테스트 할 수 없다. 이것은 내 머리의 코드이지만 기본적으로 필요한 색상을 대체하거나 정지를 추가한다. 기본적으로 내 예에서는 연한 녹색으로 시작하고 중심보다 약간 전에 흰색으로 희미 해져 (가혹한 전환이 아닌 페이드를 제공하기 위해) 45 %에서 55 % 사이의 흰색에서 중간 녹색으로 페이드 인 중간 녹색에서 진한 녹색으로 55 %에서 끝까지. 이것은 모양과 똑같지 않을 수도 있지만 (지금은이 색상을 테스트 할 방법이 없습니다), 예제를 복제하도록이 값을 수정할 수 있습니다.
편집 : 또한 0, 0, 0, theButton.getHeight()
그라디언트의 x0, y0, x1, y1 좌표를 나타냅니다. 따라서 기본적으로 x = 0 (왼쪽), y = 0 (위)에서 시작하여 x = 0으로 확장됩니다 (수직 그라디언트를 원하므로 왼쪽에서 오른쪽 각도가 필요하지 않습니다), y = 높이 버튼의. 따라서 그래디언트는 버튼 상단에서 버튼 하단까지 90도 각도로 진행됩니다.
편집 : 좋아, 그래서 작동하는 아이디어가 하나 더 있습니다. 현재는 XML로 작동하지만 Java의 모양에도 적용 할 수 있어야합니다. 그것은 복잡하고 하나의 모양으로 단순화 할 수있는 방법이 있다고 생각하지만 이것이 내가 지금 얻은 것입니다.
green_horizontal_gradient.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<corners
android:radius="3dp"
/>
<gradient
android:angle="0"
android:startColor="#FF63a34a"
android:endColor="#FF477b36"
android:type="linear"
/>
</shape>
half_overlay.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<solid
android:color="#40000000"
/>
</shape>
layer_list.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android"
>
<item
android:drawable="@drawable/green_horizontal_gradient"
android:id="@+id/green_gradient"
/>
<item
android:drawable="@drawable/half_overlay"
android:id="@+id/half_overlay"
android:top="50dp"
/>
</layer-list>
test.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
>
<TextView
android:id="@+id/image_test"
android:background="@drawable/layer_list"
android:layout_width="fill_parent"
android:layout_height="100dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:gravity="center"
android:text="Layer List Drawable!"
android:textColor="@android:color/white"
android:textStyle="bold"
android:textSize="26sp"
/>
</RelativeLayout>
자, 기본적으로 저는 수평 녹색 그라디언트에 대해 XML로 모양 그라디언트를 만들었습니다. 0도 각도로 설정하여 상단 영역의 왼쪽 녹색에서 오른쪽 녹색으로. 다음으로 반투명 회색 모양의 사각형을 만들었습니다. 레이어 목록 XML에 인라인 되어이 여분의 파일을 제거 할 수 있다고 확신하지만 방법을 잘 모르겠습니다. 그러나 괜찮은 종류의 해키 부분은 layer_list XML 파일에 있습니다. 녹색 그라디언트를 아래쪽 레이어로 넣은 다음 절반 오버레이를 두 번째 레이어로 놓고 위쪽에서 50dp만큼 오프셋합니다. 분명히이 숫자는 항상 고정 크기 50dp가 아닌 뷰 크기의 절반이되기를 원합니다. 그래도 백분율을 사용할 수 있다고 생각하지 않습니다. 여기에서 layer_list.xml 파일을 배경으로 사용하여 test.xml 레이아웃에 TextView를 삽입했습니다.
타다!
한 번 더 편집 : 아이템으로 레이어 목록 드로어 블에 도형을 포함시킬 수 있다는 것을 깨달았습니다. 더 이상 3 개의 별도 XML 파일이 필요하지 않습니다! 다음과 같이 조합하여 동일한 결과를 얻을 수 있습니다.
layer_list.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android"
>
<item>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<corners
android:radius="3dp"
/>
<gradient
android:angle="0"
android:startColor="#FF63a34a"
android:endColor="#FF477b36"
android:type="linear"
/>
</shape>
</item>
<item
android:top="50dp"
>
<shape
android:shape="rectangle"
>
<solid
android:color="#40000000"
/>
</shape>
</item>
</layer-list>
이 방법으로 원하는만큼 항목을 레이어 할 수 있습니다! 나는 장난을 치며 Java를 통해 더 다양한 결과를 얻을 수 있는지 확인할 수 있습니다.
나는 이것이 마지막 편집이라고 생각합니다 ... : 좋아, 다음과 같이 Java를 통해 위치를 확실히 수정할 수 있습니다.
TextView tv = (TextView)findViewById(R.id.image_test);
LayerDrawable ld = (LayerDrawable)tv.getBackground();
int topInset = tv.getHeight() / 2 ; //does not work!
ld.setLayerInset(1, 0, topInset, 0, 0);
tv.setBackgroundDrawable(ld);
하나! 이로 인해 TextView가 그려 질 때까지 TextView를 측정 할 수 없다는 또 다른 성가신 문제가 발생합니다. 아직 어떻게 수행 할 수 있는지 잘 모르겠지만 topInset에 숫자를 수동으로 삽입하면 작동합니다.
거짓말 하나 더 편집
좋아, 컨테이너의 높이에 맞게이 레이어 드로어 블을 수동으로 업데이트하는 방법을 찾았 습니다 . 자세한 설명은 여기를 참조하십시오 . 이 코드는 onCreate () 메소드로 이동해야합니다.
final TextView tv = (TextView)findViewById(R.id.image_test);
ViewTreeObserver vto = tv.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
LayerDrawable ld = (LayerDrawable)tv.getBackground();
ld.setLayerInset(1, 0, tv.getHeight() / 2, 0, 0);
}
});
그리고 끝났어요! 아휴! :)
레이어 목록을 사용하여 XML에서 그라디언트 모양을 레이어 할 수 있습니다. 두 번째 항목이 반투명 한 기본 상태의 버튼을 상상해보십시오. 그것은 일종의 비네팅을 추가합니다. (사용자 정의 색상을 변명하십시오.)
<!-- Normal state. -->
<item>
<layer-list>
<item>
<shape>
<gradient
android:startColor="@color/grey_light"
android:endColor="@color/grey_dark"
android:type="linear"
android:angle="270"
android:centerColor="@color/grey_mediumtodark" />
<stroke
android:width="1dp"
android:color="@color/grey_dark" />
<corners
android:radius="5dp" />
</shape>
</item>
<item>
<shape>
<gradient
android:startColor="#00666666"
android:endColor="#77666666"
android:type="radial"
android:gradientRadius="200"
android:centerColor="#00666666"
android:centerX="0.5"
android:centerY="0" />
<stroke
android:width="1dp"
android:color="@color/grey_dark" />
<corners
android:radius="5dp" />
</shape>
</item>
</layer-list>
</item>
xml 모양 만 사용하여 수행 할 수 있습니다. 레이어 목록과 다음과 같이 네거티브 패딩을 사용하십시오.
<layer-list>
<item>
<shape>
<solid android:color="#ffffff" />
<padding android:top="20dp" />
</shape>
</item>
<item>
<shape>
<gradient android:endColor="#ffffff" android:startColor="#efefef" android:type="linear" android:angle="90" />
<padding android:top="-20dp" />
</shape>
</item>
</layer-list>
이 방법을 사용하면 원하는 모든 것을 할 수 있습니다. 스택
과 같으 므로 어떤 항목이 먼저 또는 마지막에 오게 조심하십시오.
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:right="50dp" android:start="10dp" android:left="10dp">
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="3dp" />
<solid android:color="#012d08"/>
</shape>
</item>
<item android:top="50dp">
<shape android:shape="rectangle">
<solid android:color="#7c4b4b" />
</shape>
</item>
<item android:top="90dp" android:end="60dp">
<shape android:shape="rectangle">
<solid android:color="#e2cc2626" />
</shape>
</item>
<item android:start="50dp" android:bottom="20dp" android:top="120dp">
<shape android:shape="rectangle">
<solid android:color="#360e0e" />
</shape>
</item>