Создание горизонтальных и вертикальных пунктирных линий в Android

Я хочу рисовать горизонтальные и вертикальные пунктирные линии в Android, используя формы.

Я хочу нарисовать так

enter image description here

Для горизонтальной линии

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="line" >

    <stroke
        android:dashGap="6px"
        android:dashWidth="6px"
        android:color="#C7B299" />

</shape>

Для вертикальной линии

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="line" >
<size
     android:height="400dp"/>
    <stroke
        android:dashGap="6px"
        android:dashWidth="6px"
        android:color="#C7B299" />

</shape>

Но вертикальная пунктирная линия, на которой не отображаются мои выходные данные, показывает

enter image description here

Как нарисовать вертикальную линию.

31
задан 28.04.2020, 19:00

7 ответов

Я нашел решение

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

    <shape android:shape="line" >
        <stroke
            android:dashGap="6px"
            android:dashWidth="6px"
            android:color="#C7B299" />
    </shape>

</rotate>

ИЛИ

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="90"
    android:toDegrees="90"
    android:drawable="@drawable/horizontal_line"/>
43
ответ дан 28.04.2020, 19:03
  • 1
    I' d использование PYTHONIOENCODING; иначе io.TextIOWrapper могла бы быть лучшая альтернатива, чем codecs для обработки новых строк правильно. – jfs 31.10.2019, 08:58

Я думаю, что я нашел «более чистое» решение этой проблемы, создав собственный вид, содержащий определенный код для рисования пунктирных линий (как в вертикальной, так и горизонтальной ориентации), и набор атрибутов, чтобы было очень легко использовать его из макетов XML. Основное преимущество этого подхода перед методом «повернутой линии» состоит в том, что вы можете установить размер представления пунктирной линии, как обычно, без необходимости беспокоиться о том, как представление будет вести себя после поворота (как только вращение применяется ко всему пунктирному виду линии, а не только к рисуемой линии).

Итак, пошаговое решение:

  1. Создайте файл «/res/values/attrs.xml» со ​​следующим содержимым:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
    <declare-styleable name="DividerView">
        <attr name="color" format="color" />
        <attr name="dashLength" format="dimension" />
        <attr name="dashGap" format="dimension" />
        <attr name="dashThickness" format="dimension" />
        <attr name="orientation" format="enum">
            <enum name="horizontal" value="0" />
            <enum name="vertical" value="1" />
        </attr>
    </declare-styleable>
    
    </resources>
    

Это создает атрибуты для управления пользовательским представлением. Примечание. Если указанный выше файл уже существует в вашем проекте, просто скопируйте / вставьте блок «Declare-Stylable» внутри существующего блока «Resources».

  1. Создайте класс DividerView и вставьте содержимое ниже:

    public class DividerView extends View {
    static public int ORIENTATION_HORIZONTAL = 0;
    static public int ORIENTATION_VERTICAL = 1;
    private Paint mPaint;
    private int orientation;
    
    public DividerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        int dashGap, dashLength, dashThickness;
        int color;
    
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.DividerView, 0, 0);
    
        try {
            dashGap = a.getDimensionPixelSize(R.styleable.DividerView_dashGap, 5);
            dashLength = a.getDimensionPixelSize(R.styleable.DividerView_dashLength, 5);
            dashThickness = a.getDimensionPixelSize(R.styleable.DividerView_dashThickness, 3);
            color = a.getColor(R.styleable.DividerView_color, 0xff000000);
            orientation = a.getInt(R.styleable.DividerView_orientation, ORIENTATION_HORIZONTAL);
        } finally {
            a.recycle();
        }
    
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(color);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(dashThickness);
        mPaint.setPathEffect(new DashPathEffect(new float[] { dashLength, dashGap, }, 0));
    }
    
    public DividerView(Context context) {
        this(context, null);
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        if (orientation == ORIENTATION_HORIZONTAL) {
            float center = getHeight() * .5f; 
            canvas.drawLine(0, center, getWidth(), center, mPaint);
        } else {
            float center = getWidth() * .5f; 
            canvas.drawLine(center, 0, center, getHeight(), mPaint);
        }
    }
    }
    
  2. Чтобы использовать автоматическое заполнение атрибутов в файлах макета, добавьте следующее определение пространства имен в самом верхнем контейнере:

    xmlns:custom="http://schemas.android.com/apk/res/com.example"
    

Замените com.example именем вашего пакета. Вы также можете изменить custom на любой префикс, который лучше соответствует вашим потребностям. Примечание. Может потребоваться перезапустить Eclipse, чтобы автоматически завершить работу после изменений в файле attrs.xml.

  1. И, наконец, создайте свои пунктирные линии, вставив следующий элемент в макет, как и любой другой вид:

    <com.example.DividerView
        android:layout_width="1dp"
        android:layout_height="fill_parent"
        android:layerType="software" 
        custom:color="@color/grey"
        custom:orientation="vertical"
        custom:dashLength="1dp"
        custom:dashGap="1dp"
        custom:dashThickness="1dp" />
    

Надеюсь, это поможет!

36
ответ дан 28.04.2020, 19:01
  • 1
    Это полностью изменяет поведение sys.stdout. Эти StreamWriter возвращенный codecs.getwriter больше не с буфером строки, например. – Sebastian 31.10.2019, 08:58

Это работает для меня:

vertical_line.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <solid android:color="@android:color/transparent"/>
    <stroke
        android:width="1px"
        android:color="#60000000"
        android:dashGap="5px"
        android:dashWidth="5px" />
</shape>

В макете:

<View
        android:layout_width="1dp"
        android:layout_height="match_parent"
        android:layout_centerHorizontal="true"
        android:background="@drawable/vertical_line" />
14
ответ дан 28.04.2020, 19:01
  • 1
    Это работало на меня для контакта с ошибкой, вызванной путем импорта модуля, который я не мог изменить. На симпатичной ванили система Linux, которая приняла значение по умолчанию к LC_ALL = C, моя программа, генерировала 'ascii' code can't encode character .... ordinal not in range(128), когда код от импортированного модуля пытался распечатать что-то. Я не мог полагаться на пользователей своей программы, изменяющей LC_ALL на ' en_US.UTF-8'. этот взлом решил его. Я знаю it' s ужасный подход, но я не мог найти другое решение. – mhucka 31.10.2019, 08:56

Для вертикальной линии:

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

Для горизонтальной линии:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android">
    <shape
        android:shape="line">
        <stroke
            android:width="2dp"
            android:color="@color/accent_color"
            android:dashWidth="3dp"
            android:dashGap="2dp" />
    </shape>
</rotate>
-2
ответ дан 28.04.2020, 19:02
  • 1
    Еще одно доказательство, что использование stdout для коммуникации процесса является большой ошибкой. Я понимаю, что у Вас не может быть выбора, чем использовать CGI в этом случае хотя так that' s не Ваш отказ.:-) – Lennart Regebro 31.10.2019, 09:00

Если вид имеет ширину 1 дп, то простого поворота горизонтальной линии недостаточно. Длина вертикальной линии будет равна 1 dp, поскольку она сначала рисуется горизонтально, а затем поворачивается. Вот хитрость, чтобы решить эту проблему:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:left="-300dp"
        android:right="-300dp">
        <rotate
            android:drawable="@drawable/dash_line_divider_horizontal"
            android:fromDegrees="90"
            android:toDegrees="90"/>
    </item>
</layer-list>
26
ответ дан 28.04.2020, 19:04
  • 1
    Повышение ползунков главным образом, потому что PYTHONIOENCODING=utf-8 решенный моя проблема, после многих часов поиска. – theeggman85 31.10.2019, 08:57

Это хорошо решает проблему. Создайте Drawable line_dash.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:bottom="-1dp"
        android:left="-1dp"
        android:right="-1dp"
        android:top="0dp">

        <shape android:shape="rectangle">
            <stroke
                android:width="1dp"
                android:color="@color/grey_20"
                android:dashGap="3dp"
                android:dashWidth="3dp" />

            <solid android:color="@android:color/transparent" />

            <padding
                android:bottom="10dp"
                android:left="10dp"
                android:right="10dp"
                android:top="10dp" />
        </shape>
    </item>
</layer-list>

Используйте это так

 <View
       android:layout_width="match_parent"
       android:layout_height="1dp"
       android:layout_margin="@dimen/spacing_middle"
       android:background="@drawable/line_dash" />
1
ответ дан 28.04.2020, 19:05
  • 1
    Этот комментарий должен быть обновлен, относительно 3,3 и предстоящие 3,4 релиза Python.Спасибо – soshial 31.10.2019, 08:56
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
        android:fromDegrees="90"
        android:toDegrees="90">
    <shape android:shape="line">
        <stroke
                android:color="@color/darkGray"
                android:width="1dp"
                android:dashGap="4dp"
                android:dashWidth="2dp"/>
    </shape>
</rotate>

<View
                android:layerType="software"
                android:background="@drawable/bg_vertical_dash_gray_1dp"
                android:layout_width="@dimen/_15sdp"
                android:layout_height="@dimen/_30sdp"/>

Ключом для работы приведенного выше кода является использование android:layerType="software". Для получения дополнительной информации, проверьте эту ссылку.

0
ответ дан 28.04.2020, 19:05
  • 1
    Мой контекст выполнял сценарий Python как CGI под Apache, где значение по умолчанию производило кодирующий wasn' t, в чем я нуждался (мне был нужен UTF-8). Я думаю it' s лучше для сценария, чтобы гарантировать, что его вывод находится в корректном кодировании, вместо того, чтобы полагаться на внешние настройки (такие как переменные среды как PYTHONIOENCODING). – Greg Hewgill 31.10.2019, 09:00

Теги

Похожие вопросы