开放式安卓中风?

有没有可能创建一个 Android 形状的对象,只在某些方面有笔划?

例如:

<stroke
android:width="3dip"
android:color="#000000"
android:dashWidth="10dip"
android:dashGap="6dip" />

它类似于这个 CSS:

border: 3px dashed black;

我怎样才能只在一边设置笔画? 这就是我在 CSS 中的做法:

border-left: 3px dashed black;

如何在 Android XML 中实现这一点?

60069 次浏览

I solved this by using a list-layer, combining two shapes, one of which with height 1dp placed at the bottom

optionscreen_bottomrectangle.xml:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- This is the line -->
<item>
<shape>
<solid android:color="#535353" />
</shape>
</item>
<!-- This is the main color -->
<item android:bottom="1dp">
<shape>
<solid android:color="#252525" />
</shape>
</item>
</layer-list>

Then, in the layout/main.xml file

<TextView
android:id="@+id/bottom_rectangle"
android:background="@drawable/optionscreen_bottomrectangle"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_below="@id/table_options"
android:layout_above="@id/exit_bar"/>

Which fills the gap between table_options and exit_bar with a background and just before exit_bar prints a 1dp line. This did the trick for me, I hope it helps someone else.

Answer edited to place layers in the correct order. Thx Alex!

@Maragues's answer is backwards, as layer-list drawables draw from top to bottom (meaning the last item in the list is drawn on top):

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- This is the line -->
<item>
<shape>
<solid android:color="#535353" />
</shape>
</item>
<!-- This is the main color -->
<item android:bottom="1dp">
<shape>
<solid android:color="#252525" />
</shape>
</item>


</layer-list>

This will effectively fill the shape with the line color, then draw the background color on top of it, leaving the last 1dp clear for the line color to show through.

I achieved a good solution with this one:

<?xml version="1.0" encoding="utf-8"?>


<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- This is the line -->
<item android:top="-1dp" android:right="-1dp" android:left="-1dp">
<shape>
<solid android:color="@android:color/transparent" />
<stroke android:width="1dp" android:color="#ffffff" />
</shape>
</item>


</layer-list>

This works well in case you need a transparent background but still an open stroke color (In my case I only needed a bottom line). If you need a background color you can add a solid shape color as in Maragues answer.

EDIT 1

Sometimes, for High Density devices, using low dip values may end in very thin or invisible strokes or distances. This may happen to you also when setting ListView dividers.

The simplest workaround is to use a distance of 1px instead of 1dp. This will make the line always visible at all densities. The best solution would be to create dimension resources for each density, to get the best size for each device.

Edit 2

Fun, but I tried to use this 6 years later and I can't get a good result on Lollipop devices.

Probably the current solution is to use 9-patch. Android should have made an easy solution for this problem after all this time.

Another take on the other responses using padding instead. This little snipplet makes a border on top and bottom.

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- This is the line -->
<item>
<shape>
<padding android:left="0dp" android:top="1dp" android:right="0dp" android:bottom="1dp"/>
<solid android:color="#898989" />
</shape>
</item>
<!-- This is the main color -->
<item>
<shape>
<solid android:color="#ffffff" />
</shape>
</item>
</layer-list>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >




<item>
<shape android:shape="rectangle" >
<stroke  android:width="2dp"
android:color="#BBBBBB" />
<solid android:color="@android:color/transparent" />
</shape>
</item>
<item  android:bottom="2dp" >
<shape android:shape="rectangle" >
<stroke  android:width="2dp"
android:color="@color/main_background_color" />
<solid android:color="@android:color/transparent" />
</shape>
</item>

I know this question was posted long ago, so the answer will not be used by the person who posted this question, but it may still help others.

 <?xml version="1.0" encoding="UTF-8"?>
<!-- inset is used to remove border from top, it can remove border from any other side-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetTop="-2dp"
>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rectangle">
<stroke android:width="1dp" android:color="#b7b7b7" />
<corners android:bottomRightRadius="5dp"  android:bottomLeftRadius="5dp"/>


<solid android:color="#454444"/>
</shape>
</inset>

Use the inset tag and give a negative value for the side border you want to remove.

The possible values are:

android:insetTop="-1dp" android:insetBottom="-1dp" android:insetLeft="-1dp" android:insetRight="-1dp"

I've used following code.

<?xml version="1.0" encoding="UTF-8"?>
<!-- inset is used to remove border from top, it can remove border from any other side-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetTop="-2dp" android:insetLeft="-2dp" android:insetRight="-2dp"
>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rectangle">
<stroke android:width="1dp" android:color="@color/colorPrimary" />
<solid android:color="#0000"/>
<padding android:left="2dp" android:top="2dp" android:bottom="2dp" android:right="2dp"/>
</shape>
</inset>

Simple and efficient

To have a transparent view and everything that is outside has an overlay of some color, what you can do is build the views that encapsulate the center view without the outside views stepping on the center view.

This way you avoid having a drawable external to the layout and you have more control over the distances of the views without having to perform calculations at runtime.

<androidx.constraintlayout.widget.ConstraintLayout .. >


<View
android:id="@+id/center"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:background="@color/transparent"/>


<View
android:id="@+id/left_overlay"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/center"
app:layout_constraintTop_toBottomOf="@id/top_overlay"
app:layout_constraintBottom_toTopOf="@id/bottom_overlay"
android:background="@color/black"
android:alpha="0.5"
/>


<View
android:id="@+id/right_overlay"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toRightOf="@id/center"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/top_overlay"
app:layout_constraintBottom_toTopOf="@id/bottom_overlay"
android:background="@color/black"
android:alpha="0.5"
/>


<View
android:id="@+id/top_overlay"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/center"
android:background="@color/black"
android:alpha="0.5"
/>


<View
android:id="@+id/bottom_overlay"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/center"
android:background="@color/black"
android:alpha="0.5"
/>


</androidx.constraintlayout.widget.ConstraintLayout>

GL