Linia pionowa przy użyciu XML do rysowania

162

Próbuję wymyślić, jak zdefiniować pionową linię (o grubości 1 dp), która ma być używana jako rysowana.

Aby zrobić poziomą, jest całkiem prosta:

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line">
    <stroke android:width="1dp" android:color="#0000FF"/>
    <size android:height="50dp" />     
</shape>

Pytanie brzmi, jak ustawić tę linię pionowo?

Tak, istnieją obejścia, takie jak rysowanie kształtu prostokąta o grubości 1 piksela, ale to komplikuje rysowany plik XML, jeśli składa się z wielu <item>elementów.

Czy ktoś miał z tym jakąś szansę?

AKTUALIZACJA

Sprawa jest nadal nierozwiązana. Jednak dla każdego, kto bierze udział w krucjacie dokumentacji Androida - może się to przydać: Brak instrukcji XML dla Androida

AKTUALIZACJA

Nie znalazłem innej drogi niż ta, którą oznaczyłem jako poprawną. To załatwia sprawę, choć wydaje się nieco „ciężkie”, więc jeśli znasz odpowiedź, nie zapomnij jej udostępnić;)

Kaspa
źródło

Odpowiedzi:

394

Zamiast kształtu możesz spróbować View:

<View
    android:layout_width="1dp"
    android:layout_height="fill_parent"
    android:background="#FF0000FF" />

Użyłem tego tylko do linii poziomych, ale myślę, że zadziałaby również dla linii pionowych.

Posługiwać się:

<View
    android:layout_width="fill_parent"
    android:layout_height="1dp"
    android:background="#FF0000FF" />

dla linii poziomej.

CommonsWare
źródło
4
dzięki Mark :)! Wiem, że mogę to osiągnąć za pomocą widoku. Chodzi o to, że tworzę nieco bardziej złożony widok, którego chcę użyć jako rysowalnego tła komórki tabeli. Są tam różne rodzaje kształtów / gradientów / linii. Użycie widoku byłoby rozwiązaniem, jednak musiałbym umieścić go w innej "warstwie" rysunku i to jest potencjalnie strzelanie sobie w stopę, kiedy napotkam zmianę rozmiaru itp. Zastanawiam się tylko, dlaczego nie ma dokumentacji na temat " shape "xmls, może ktoś z Google mógłby nas oświecić? :)
Kaspa
1
Używanie marginRight / Start i Left / End jest również czasami interesujące, aby uzyskać przestrzeń po bokach.
George
108

Możesz zagnieździć swój kształt wewnątrz tagu obracanego.

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="90"
    android:toDegrees="90">
    <shape 
        android:shape="line">
        <stroke
            android:width="1dp"
            android:color="#ff00ff"
            android:dashWidth="1dp"
            android:dashGap="2dp" />
    </shape>
</rotate>

Jednak jedynym problemem jest to, że parametrami układu zdefiniowanymi w pliku XML układu będą wymiary używane do narysowania oryginalnego kształtu. Oznacza to, że jeśli chcesz, aby Twoja linia miała wysokość 30 dp, musisz zdefiniować layout_width o wartości 30 dp w pliku XML układu. Ale ostateczna szerokość w tym przypadku również będzie wynosić 30 dp, co jest prawdopodobnie niepożądane w większości sytuacji. Zasadniczo oznacza to, że zarówno szerokość, jak i wysokość muszą mieć tę samą wartość, wartość żądanej długości linii. Nie mogłem wymyślić, jak to naprawić.

Wydaje się, że jest to rozwiązanie „na Androida”, ale jeśli nie ma jakiegoś rozwiązania lub obejścia problemu z wymiarami, o którym wspominam, to prawdopodobnie nie zadziała dla większości ludzi. To, czego naprawdę potrzebujemy, to atrybut orientacji w <shape /> lub <stroke />.

Możesz również spróbować odwołać się do innego elementu rysowalnego w atrybutach tagu obracania, takich jak:

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="90"
    android:toDegrees="90"
    android:drawable="@drawable/horizontal_line" />

Jednak nie testowałem tego i oczekuję, że będzie miał te same problemy.

-- EDYTOWAĆ --

Och, właściwie wymyśliłem rozwiązanie. Możesz użyć ujemnego marginesu w pliku XML układu, aby pozbyć się niepożądanego dodatkowego miejsca. Jak na przykład:

<ImageView
    android:layout_width="35dp"
    android:layout_height="35dp"
    android:layout_marginLeft="-15dp"
    android:layout_marginRight="-15dp"
    android:src="@drawable/dashed_vertical_line" />
cephus
źródło
4
podczas gdy ujemny margines zadziała dla 99% urządzeń ... po prostu wiedz, że są tam urządzenia, które wymuszą zamknięcie, jeśli to zrobisz. Niektóre urządzenia mają problem z zawyżeniem ujemnej marży
Kent Andersen
2
@cephus Używam twojego pierwszego kodu, ale potrzebuję linii u góry widoku. Jest w centrum mojego widoku. Jak mogę ustawić dla niego grawitację (wewnątrz pliku Shape xml)?
Behzad,
20

Możesz użyć atrybutu obracania

 <item>
    <rotate
        android:fromDegrees="90"
        android:toDegrees="90"
        android:pivotX="50%"
        android:pivotY="50%" >
        <shape
            android:shape="line"
            android:top="1dip" >
            <stroke
                android:width="1dip"
                 />
        </shape>
    </rotate>
</item>
user4679242
źródło
6
Jest to zdecydowanie lepsza (lub najlepsza) odpowiedź, ponieważ podczas gdy odpowiedź @ commonsware jest wystarczająca dla normalnych pionowych linii. Jeśli nie chcemy tworzyć linii przerywanych (powiedzmy na przykład), jest to jedyna odpowiedź, która działałaby poprawnie.
Subin Sebastian
16
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
  android:shape="rectangle" >
    <stroke android:width="1dp" android:color="@color/white" />
    <size android:width="2dp" />
</shape>

Pracuje dla mnie . Umieść go jako tło widoku z fill_parent lub o stałym rozmiarze w wysokości dp

logcat
źródło
11

Wymyśliłem inne rozwiązanie. Pomysł polega na tym, aby najpierw wypełnić element do rysowania kolorem, który chcesz, aby linia była, a następnie ponownie wypełnić cały obszar kolorem tła, używając wypełnienia po lewej lub prawej stronie. Oczywiście działa to tylko w przypadku pionowej linii po lewej lub prawej stronie twojego rysunku.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@color/divider_color" />
    <item android:left="6dp" android:drawable="@color/background_color" />
</layer-list>
Eric Kok
źródło
Potrzebowałem tła z obramowaniami po lewej, prawej, na dole i to zadziałało, dzięki!
Andrii Chernenko
Wspaniale, dzięki temu udało mi się stworzyć zgrabne separatory w moim LinearLayout ( showDividers="middle"). Aby uzyskać dzielnik 2dp, musiałem określić android:left="3dp"tutaj.
Jonik
Wskazówka: aby uczynić to rysowanym bardziej użytecznym, używaj @android:color/transparentzamiast twardego kodowania @color/background_color.
Jonik
Właściwie dla moich potrzeb w zakresie przegród pionowych to rozwiązanie jest jeszcze prostsze . :)
Jonik
@Jonik Jasne, ale działa to tylko z widokiem o stałej wysokości, a nie z wrap_content.
Eric Kok
10

Myślę, że to najprostsze rozwiązanie:

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

    <item
        android:gravity="center">
        <shape android:shape="rectangle">
            <size android:width="1dp" />
            <solid android:color="#0000FF" />
        </shape>
    </item>

</layer-list>
a.ch.
źródło
Wspaniale. Dodaj android:heightdo, sizejeśli chcesz kontrolować również ten wymiar.
Giulio Piancastelli
4

Musiałem dodawać widoki dynamicznie / programowo, więc dodanie dodatkowego widoku byłoby uciążliwe. Wysokość mojego widoku wynosiła WRAP_CONTENT, więc nie mogłem użyć rozwiązania prostokąta. Znalazłem tutaj wpis na blogu o rozszerzaniu TextView, nadpisywaniu onDraw () i malowaniu w linii, więc zaimplementowałem to i działa dobrze. Zobacz mój kod poniżej:

public class NoteTextView extends TextView {
    public NoteTextView(Context context) {
       super(context);
    }
    private Paint paint = new Paint();
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        paint.setColor(Color.parseColor("#F00000FF"));
        paint.setStrokeWidth(0);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawLine(0, 0, 0, getHeight(), paint);
    }
}

Potrzebowałem pionowej linii po lewej stronie, ale parametry linii rysowania są drawLine(startX, startY, stopX, stopY, paint)takie, aby można było narysować dowolną linię prostą w dowolnym kierunku w widoku. Wtedy w mojej działalności mam NoteTextView note = new NoteTextView(this); nadzieję, że to pomaga.

willlma
źródło
3

to bardzo proste ... aby dodać pionową linię w android xml ...

<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_marginTop="5dp"
android:rotation="90"
android:background="@android:color/darker_gray"/>
user3130068
źródło
Działa to świetnie, gdy nie możesz użyć fill_parent jako wysokości, ponieważ wysokość nadrzędna jest ustawiona na wrap_content.
Sergey Aldoukhov
2

Zależy od tego, gdzie chcesz mieć pionową linię, ale jeśli chcesz na przykład obramowanie pionowe, możesz ustawić widok nadrzędny z niestandardowym rysunkiem w tle. Następnie możesz zdefiniować rysowalny w następujący sposób:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <shape
            android:shape="rectangle">
            <stroke android:width="1dp" android:color="#000000" />
            <solid android:color="#00ffffff" />

        </shape>
    </item>

    <item android:right="1dp">
        <shape android:shape="rectangle">
            <solid android:color="#00ffffff" />
        </shape>
    </item>

</layer-list>

Ten przykład utworzy cienką czarną linię 1 dp po prawej stronie widoku, która będzie miała to rysowalne jako tło.

Lukas1
źródło
2
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:bottom="-3dp"
        android:left="-3dp"
        android:top="-3dp">

        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimary" />
            <stroke
                android:width="2dp"
                android:color="#1fc78c" />
        </shape>

    </item>

</layer-list>
AnupamChugh
źródło
2

Wygląda na to, że nikt nie wspomniał o tej opcji:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@color/white" android:width="1dp"/>
</layer-list>
Sergey Neskoromny
źródło
1

Możesz użyć kształtu, ale zamiast linii nadaj mu prostokąt.

android:shape="rectangle">
<stroke
    android:width="5dp"
    android:color="#ff000000"
    android:dashGap="10px"
    android:dashWidth="30px" />

i w swoim układzie użyj tego ...

<ImageView
    android:layout_width="7dp"
    android:layout_height="match_parent"
    android:src="@drawable/dashline"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layerType="software"/>

Być może będziesz musiał pobawić się szerokością, w zależności od rozmiaru kresek, aby umieścić ją w jednej linii.

Mam nadzieję, że to pomoże

Boxlady
źródło
1
add this in your styles.xml

        <style name="Divider">
            <item name="android:layout_width">1dip</item>
            <item name="android:layout_height">match_parent</item>
            <item name="android:background">@color/divider_color</item>
        </style>

        <style name="Divider_invisible">
            <item name="android:layout_width">1dip</item>
            <item name="android:layout_height">match_parent</item>
        </style>

then wrap this style in a linear layout where you want the vertical line, I used the vertical line as a column divider in my table. 

     <TableLayout
                android:id="@+id/table"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:stretchColumns="*" >

                <TableRow
                    android:id="@+id/tableRow1"
                    android:layout_width="fill_parent"
                    android:layout_height="match_parent"
                    android:background="#92C94A" >

                    <TextView
                        android:id="@+id/textView11"
                        android:paddingBottom="10dp"
                        android:paddingLeft="5dp"
                        android:paddingRight="5dp"
                        android:paddingTop="10dp" />
    //...................................................................    

                    <LinearLayout
                        android:layout_width="1dp"
                        android:layout_height="match_parent" >

                        <View style="@style/Divider_invisible" />
                    </LinearLayout>
        //...................................................................
                    <TextView
                        android:id="@+id/textView12"
                        android:paddingBottom="10dp"
                        android:paddingLeft="5dp"
                        android:paddingRight="5dp"
                        android:paddingTop="10dp"
                        android:text="@string/main_wo_colon"
                        android:textColor="@color/white"
                        android:textSize="16sp" />
  //...............................................................  
                    <LinearLayout
                        android:layout_width="1dp"
                        android:layout_height="match_parent" >

                        <View style="@style/Divider" />
                    </LinearLayout>

    //...................................................................
                    <TextView
                        android:id="@+id/textView13"
                        android:paddingBottom="10dp"
                        android:paddingLeft="5dp"
                        android:paddingRight="5dp"
                        android:paddingTop="10dp"
                        android:text="@string/side_wo_colon"
                        android:textColor="@color/white"
                        android:textSize="16sp" />

                    <LinearLayout
                        android:layout_width="1dp"
                        android:layout_height="match_parent" >

                        <View style="@style/Divider" />
                    </LinearLayout>

                    <TextView
                        android:id="@+id/textView14"
                        android:paddingBottom="10dp"
                        android:paddingLeft="5dp"
                        android:paddingRight="5dp"
                        android:paddingTop="10dp"
                        android:text="@string/total"
                        android:textColor="@color/white"
                        android:textSize="16sp" />
                </TableRow>

                <!-- display this button in 3rd column via layout_column(zero based) -->

                <TableRow
                    android:id="@+id/tableRow2"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="#6F9C33" >

                    <TextView
                        android:id="@+id/textView21"
                        android:padding="5dp"
                        android:text="@string/servings"
                        android:textColor="@color/white"
                        android:textSize="16sp" />

                    <LinearLayout
                        android:layout_width="1dp"
                        android:layout_height="match_parent" >

                        <View style="@style/Divider" />
                    </LinearLayout>

    ..........
    .......
    ......
YasirAzgar
źródło
0

Aby utworzyć pionową linię, użyj prostokąta o szerokości 1 dp:

<shape>
    <size
        android:width="1dp"
        android:height="16dp" />
    <solid
        android:color="#c8cdd2" />
</shape>

Nie używaj stroke, użyj solid(który jest kolorem „wypełnienia”), aby określić kolor linii.

David Wasser
źródło
-1
 <View
        android:layout_width="2dp"
        android:layout_height="40dp"

        android:background="#ffffff"
        android:padding="10dp" />`
Surender Kumar
źródło