안드로이드에서 점선 / 파선을 어떻게 만듭니 까?


254

점선을 만들려고합니다. 나는 이것을 실선으로 지금 사용하고 있습니다 :

LinearLayout divider = new LinearLayout( this );
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.FILL_PARENT, 2 );
divider.setLayoutParams( params );
divider.setBackgroundColor( getResources().getColor( R.color.grey ) );

나는 이와 같은 것이 필요하지만 단단하지 않고 점선입니다. 투명한 레이아웃과 솔리드 레이아웃 사이에서 수백 개의 레이아웃을 번갈아 사용하지 않으려 고합니다.

답변:


515

자바 코드없이 :

드로어 블 /dotted.xml :

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

    <stroke
       android:color="#C7B299"
       android:dashWidth="10px"
       android:dashGap="10px"
       android:width="1dp"/>
</shape>

view.xml :

<ImageView
    android:layout_width="match_parent"
    android:layout_height="5dp"
    android:src="@drawable/dotted"
    android:layerType="software" />

21
Eclipse에서 그래픽 레이아웃에 간격이 표시되는 동안 전화에 공백이없는 이유를 이해하지 못합니다.
단테

73
신경 쓰지 마라. 여기서 해결책을 찾았다 : stackoverflow.com/questions/10843402/… 레이어 유형을 소프트웨어로 설정 하십시오 : android : layerType = "software"
Dante

7
를 사용할 때 알려진 버그canvas.drawLine()있습니다. 하드웨어 가속을 비활성화하는 대안으로 canvas.drawPath대신 사용할 수 있습니다 .
hgoebl

10
dp 대신에 사용하십시오 px .
S.M_Emamian

7
Android 6.0.1 및 4.4.4에서 모두 작동하는지 확인했습니다. 주목해야 할 두 가지 : 1) 드로어 블을 배경으로 한 View는 ImageView가 필요합니다. 2) android:layerType="software"ImageView에서 설정해야합니다.
Jonik

206

페인트 효과에 패스 효과가 설정됩니다

Paint fgPaintSel = new Paint();
fgPaintSel.setARGB(255, 0, 0,0);
fgPaintSel.setStyle(Style.STROKE);
fgPaintSel.setPathEffect(new DashPathEffect(new float[] {10,20}, 0));

int [] 배열에 더 많은 숫자를 제공하여 모든 종류의 점선 패턴을 만들 수 있으며 대시와 간격의 비율을 지정합니다. 이것은 간단하고 똑같이 파선입니다.


왜 이것이 나를 위해 지금합니까? stackoverflow.com/questions/12401311/…
Chris.Zou

생성자에서 새로운 float [] {5,10,15,20} 시도
실리콘

4
나는 안드로이드 개발에서 약간 새로운 것입니다. 방금 만든 선형 레이아웃에 점선 효과가있는 페인트 개체를 어떻게 추가하는지 묻고 싶습니까?
DirkJan

이 코드를 직접 복사하여 붙여 넣었지만 아무 일도 일어나지 않았습니다. 작동하도록 추가 코드를 작성해야합니까?
Jason

50

XML을 사용하여 점선 만들기
드로어 블 폴더에 xml을 만들고 점선 테두리를 설정하려는 항목에 해당 배경을 제공하십시오.

XML 배경 "dashed_border"만들기 :

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <shape>
            <solid android:color="#ffffff" />
            <stroke
                android:dashGap="5dp"
                android:dashWidth="5dp"
                android:width="1dp"
                android:color="#0000FF" />
            <padding
                android:bottom="5dp"
                android:left="5dp"
                android:right="5dp"
                android:top="5dp" />
        </shape>
    </item>
</layer-list>

해당 배경을 항목에 추가 :

<Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/dashed_border"/>

모서리에 반경이 필요한 경우 <corners android:radius="5dp" />모양에 추가 하십시오. 자세한 내용은 stackoverflow.com/a/41940609/1000551 을 참조하십시오
Vadim Kotov

단일 항목에는 레이어 목록이 필요하지 않다고 생각합니다. <shape>을 루트 요소로 사용했으며 동일하게 작동합니다.
big_m

37

xml (view_line_dotted.xml)을 만듭니다.

<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="#ffff0017"
                    android:dashGap="3dp"
                    android:dashWidth="1dp" />

                <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:background="@drawable/view_line_dotted" />

설명해 주시겠습니까?
skywall

1
<item android:bottom="-1dp" android:left="-1dp" android:right="-1dp" >수평선 1dp 두께를 원한다면 단서는 입니다.
CoolMind

대박. 거의 나를 위해 상자 밖으로 작동합니다. 내가 필요한 유일한 변경 사항은 획 태그를 변경하는 것입니다. 2dp 너비 및 4dp dashGap.
Sufian

API <21 인 장치의 android:layerType="software"경우보기에 추가 하거나 쓰십시오 view.setLayerType(View.LAYER_TYPE_SOFTWARE, null)( stackoverflow.com/questions/10843402/… 참조 ).
CoolMind

24

점선을 그릴 때 내가 한 일은 drawable dash_line.xml 을 정의하는 것입니다 .

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="line" >
<stroke
    android:dashGap="3dp"
    android:dashWidth="2dp"
    android:width="1dp"
    android:color="@color/black" />
</shape>

그런 다음 레이아웃에서 배경이 dash_line 인 뷰를 정의하십시오 . 참고 포함 할 layerType = "소프트웨어"안드로이드 , 그렇지 않으면 작동하지 않습니다.

<View
            android:layout_width="match_parent"
            android:layout_height="5dp"
            android:background="@drawable/dash_line"
            android:layerType="software" />

고마워 친구! 는 android:layerType="software"내가 찾고 있었던 것입니다! 건배!
Toochka

20

가로 및 세로 대시 선을 지원하는 대시 선을 사용자 정의했습니다. 아래 코드 :

public class DashedLineView extends View
{
private float density;
private Paint paint;
private Path path;
private PathEffect effects;

public DashedLineView(Context context)
{
    super(context);
    init(context);
}

public DashedLineView(Context context, AttributeSet attrs)
{
    super(context, attrs);
    init(context);
}

public DashedLineView(Context context, AttributeSet attrs, int defStyle)
{
    super(context, attrs, defStyle);
    init(context);
}

private void init(Context context)
{
    density = DisplayUtil.getDisplayDensity(context);
    paint = new Paint();
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(density * 4);
    //set your own color
    paint.setColor(context.getResources().getColor(R.color.XXX));
    path = new Path();
    //array is ON and OFF distances in px (4px line then 2px space)
    effects = new DashPathEffect(new float[] { 4, 2, 4, 2 }, 0);

}

@Override
protected void onDraw(Canvas canvas)
{
    // TODO Auto-generated method stub
    super.onDraw(canvas);
    paint.setPathEffect(effects);
    int measuredHeight = getMeasuredHeight();
    int measuredWidth = getMeasuredWidth();
    if (measuredHeight <= measuredWidth)
    {
        // horizontal
        path.moveTo(0, 0);
        path.lineTo(measuredWidth, 0);
        canvas.drawPath(path, paint);
    }
    else
    {
        // vertical
        path.moveTo(0, 0);
        path.lineTo(0, measuredHeight);
        canvas.drawPath(path, paint);
    }

}
}

이 방법은 xml 모양보다 선호됩니까?
IgorGanapolsky

완전한! 내가 찾던 것
Job M

9

이 클래스를 사용하면 "대시 및 밑줄"효과를 여러 줄 텍스트에 적용 할 수 있습니다. DashPathEffect를 사용하려면 TextView의 hardwareAccelerated를 해제해야합니다 (DashPathEffect 메소드는 긴 텍스트에 문제가 있음). 내 샘플 프로젝트는 https://github.com/jintoga/Dashed-Underlined-TextView/blob/master/Untitled.png 에서 찾을 수 있습니다 .

public class DashedUnderlineSpan implements LineBackgroundSpan, LineHeightSpan {

    private Paint paint;
    private TextView textView;
    private float offsetY;
    private float spacingExtra;

    public DashedUnderlineSpan(TextView textView, int color, float thickness, float dashPath,
                               float offsetY, float spacingExtra) {
        this.paint = new Paint();
        this.paint.setColor(color);
        this.paint.setStyle(Paint.Style.STROKE);
        this.paint.setPathEffect(new DashPathEffect(new float[] { dashPath, dashPath }, 0));
        this.paint.setStrokeWidth(thickness);
        this.textView = textView;
        this.offsetY = offsetY;
        this.spacingExtra = spacingExtra;
    }

    @Override
    public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v,
                             Paint.FontMetricsInt fm) {
        fm.ascent -= spacingExtra;
        fm.top -= spacingExtra;
        fm.descent += spacingExtra;
        fm.bottom += spacingExtra;
    }

    @Override
    public void drawBackground(Canvas canvas, Paint p, int left, int right, int top, int baseline,
                               int bottom, CharSequence text, int start, int end, int lnum) {
        int lineNum = textView.getLineCount();
        for (int i = 0; i < lineNum; i++) {
            Layout layout = textView.getLayout();
            canvas.drawLine(layout.getLineLeft(i), layout.getLineBottom(i) - spacingExtra + offsetY,
                    layout.getLineRight(i), layout.getLineBottom(i) - spacingExtra + offsetY,
                    this.paint);
        }
    }
}

결과:

점선 밑줄


8

수직선을 찾고 있다면이 드로어 블을 사용하십시오.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:top="-8dp"
        android:bottom="-8dp"
        android:left="-8dp">
        <shape>
            <solid android:color="@android:color/transparent"/>
            <stroke
                android:width="4dp"
                android:color="#ffffff"
                android:dashGap="4dp"
                android:dashWidth="4dp"/>
        </shape>
    </item>
</layer-list>

음의 상단 하단 및 왼쪽 값은 단일 점선을 남기고 원하지 않는 모양의 측면을 제거합니다.

그렇게보기에 사용하십시오.

<View
android:layout_width="4dp"
android:layout_height="match_parent"
android:background="@drawable/dash_line_vertical"
android:layerType="software" />

4

아래는 레이아웃의 배경으로 사용했습니다.

<?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:dashWidth="10px"
   android:dashGap="10px"
    android:color="android:@color/black" 
   />
</shape>

android:shape="rectangle"줄 대신?
IgorGanapolsky

4

EditText에 대해 점선 점선을 만들었습니다. 여기 요 새 XML을 작성하십시오. 예 : dashed_border.xml 여기 코드 :

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
    android:bottom="1dp"
    android:left="-2dp"
    android:right="-2dp"
    android:top="-2dp">
    <shape android:shape="rectangle">
        <stroke
            android:width="2dp"
            android:color="#000000"
            android:dashGap="3dp"
            android:dashWidth="1dp" />

        <solid android:color="#00FFFFFF" />

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

예를 들어 EditText에서 새 xml 파일을 사용하십시오.

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/dashed_border"/>

건배! :)



3

Dotted Background가 완벽하게 작동하는 최고의 솔루션

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
  <stroke
    android:dashGap="3dp"
    android:dashWidth="2dp"
    android:width="1dp"
    android:color="@color/colorBlack" />
</shape>

3

Canvas의 Dotted 효과의 경우이 속성을 paint 객체로 설정하십시오.

paint.setPathEffect(new DashPathEffect(new float[] {0,30}, 0));

렌더가 자신에게 적합 할 때 값 30을 변경하십시오. 각 점 사이의 "거리"를 나타냅니다.

여기에 이미지 설명을 입력하십시오


2

나를 위해 일한 유일한 방법은 그것이 가장 간단한 방법이라고 생각합니다.

    Paint paintDash = new Paint();
    paintDash.setARGB(255, 0, 0, 0);
    paintDash.setStyle(Paint.Style.STROKE);
    paintDash.setPathEffect(new DashPathEffect(new float[]{10f,10f}, 0));
    paintDash.setStrokeWidth(2);
    Path pathDashLine = new Path();

그런 다음 onDraw () : (ondraw 호출 사이에서 해당 지점을 변경하면 Path가 모든 이동을 저장하면 중요한 호출 재설정)

    pathDashLine.reset();
    pathDashLine.moveTo(porigenX, porigenY);
    pathDashLine.lineTo(cursorX,cursorY);
    c.drawPath(pathDashLine, paintDash);

2

Ruidge 의 솔루션이 마음에 들었지만 XML의 제어력이 더 필요했습니다. 그래서 Kotlin으로 변경하고 속성을 추가했습니다.

1) Kotlin 클래스를 복사하십시오.

import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View

class DashedDividerView : View {
constructor(context: Context) : this(context, null, 0)
constructor(context: Context, attributeSet: AttributeSet) : this(context, attributeSet, 0)

companion object {
    const val DIRECTION_VERTICAL = 0
    const val DIRECTION_HORIZONTAL = 1
}

private var dGap = 5.25f
private var dWidth = 5.25f
private var dColor = Color.parseColor("#EE0606")
private var direction = DIRECTION_HORIZONTAL
private val paint = Paint()
private val path = Path()

constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
    context,
    attrs,
    defStyleAttr
) {
    val typedArray = context.obtainStyledAttributes(
        attrs,
        R.styleable.DashedDividerView,
        defStyleAttr,
        R.style.DashedDividerDefault
    )

    dGap = typedArray.getDimension(R.styleable.DashedDividerView_dividerDashGap, dGap)
    dWidth = typedArray.getDimension(R.styleable.DashedDividerView_dividerDashWidth, dWidth)
    dColor = typedArray.getColor(R.styleable.DashedDividerView_dividerDashColor, dColor)
    direction =
        typedArray.getInt(R.styleable.DashedDividerView_dividerDirection, DIRECTION_HORIZONTAL)

    paint.color = dColor
    paint.style = Paint.Style.STROKE
    paint.pathEffect = DashPathEffect(floatArrayOf(dWidth, dGap), 0f)
    paint.strokeWidth = dWidth

    typedArray.recycle()
}

override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)
    path.moveTo(0f, 0f)

    if (direction == DIRECTION_HORIZONTAL) {
        path.lineTo(measuredWidth.toFloat(), 0f)
    } else {
        path.lineTo(0f, measuredHeight.toFloat())
    }
    canvas.drawPath(path, paint)
}

}

2) / res 디렉토리 에 attr 파일을 작성하고 이것을 추가하십시오

 <declare-styleable name="DashedDividerView">
    <attr name="dividerDashGap" format="dimension" />
    <attr name="dividerDashWidth" format="dimension" />
    <attr name="dividerDashColor" format="reference|color" />
    <attr name="dividerDirection" format="enum">
        <enum name="vertical" value="0" />
        <enum name="horizontal" value="1" />
    </attr>
</declare-styleable>

3) 스타일 파일에 스타일 추가

 <style name="DashedDividerDefault">
    <item name="dividerDashGap">2dp</item>
    <item name="dividerDashWidth">2dp</item>
    <!-- or any color -->
    <item name="dividerDashColor">#EE0606</item>
    <item name="dividerDirection">horizontal</item>
</style>

4) 이제 기본 스타일을 사용할 수 있습니다

<!-- here will be your path to the class -->
<com.your.package.app.DashedDividerView
    android:layout_width="match_parent"
    android:layout_height="2dp"
    />

또는 XML로 속성을 설정

<com.your.package.app.DashedDividerView
    android:layout_width="match_parent"
    android:layout_height="2dp"
    app:dividerDirection="horizontal"
    app:dividerDashGap="2dp"
    app:dividerDashWidth="2dp"
    app:dividerDashColor="@color/light_gray"/>

2

이 답변들 중 어느 것도 나를 위해 일하지 않았습니다. 이 답변의 대부분은 반투명 테두리를 제공합니다. 이를 피하려면 선호하는 색상의 다른 용기로 용기를 다시 한 번 포장해야합니다. 예를 들면 다음과 같습니다.

이것이 어떻게 보이는지

dashed_border_layout.xml

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/black"
android:background="@drawable/dashed_border_out">
<LinearLayout
    android:layout_width="150dp"
    android:layout_height="50dp"
    android:padding="5dp"
    android:background="@drawable/dashed_border_in"
    android:orientation="vertical">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is&#10;Dashed Container"
        android:textSize="16sp" />
</LinearLayout>

dashed_border_in.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
    <shape>
        <corners android:radius="10dp" />
        <solid android:color="#ffffff" />
        <stroke
            android:dashGap="5dp"
            android:dashWidth="5dp"
            android:width="3dp"
            android:color="#0000FF" />
        <padding
            android:bottom="5dp"
            android:left="5dp"
            android:right="5dp"
            android:top="5dp" />
    </shape>
</item>

dashed_border_out.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
    <shape>
        <corners android:radius="12dp" />
    </shape>
</item>


1

왜 그런지 모르겠지만 투표 답변이 저에게 효과적이지 않습니다. 나는 이런 식으로 쓰고 잘 작동합니다.
사용자 정의보기를 정의하십시오.

public class XDashedLineView extends View {

private Paint   mPaint;
private Path    mPath;
private int     vWidth;
private int     vHeight;

public XDashedLineView(Context context) {
    super(context);
    init();
}

public XDashedLineView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

public XDashedLineView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
}

private void init() {
    mPaint = new Paint();
    mPaint.setColor(Color.parseColor("#3F577C"));
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setPathEffect(new DashPathEffect(new float[] {10,10}, 0));
    mPath = new Path();
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    this.vWidth = getMeasuredWidth();
    this.vHeight = getMeasuredHeight();
    mPath.moveTo(0, this.vHeight / 2);
    mPath.quadTo(this.vWidth / 2, this.vHeight / 2, this.vWidth, this.vHeight / 2);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawPath(mPath, mPaint);
}
}

그런 다음 XML에서 사용할 수 있습니다.

        <com.YOUR_PACKAGE_NAME.XDashedLineView
        android:layout_width="690dp"
        android:layout_height="1dp"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="620dp"/>

1

이 문제를 해결하기 위해 사용자 정의보기가있는 라이브러리를 만들었으며 사용하기가 매우 간단합니다. 자세한 내용은 https://github.com/Comcast/DahDit 를 참조 하십시오 . 다음과 같이 파선을 추가 할 수 있습니다.

<com.xfinity.dahdit.DashedLine
    android:layout_width="250dp"
    android:layout_height="wrap_content"
    app:dashHeight="4dp"
    app:dashLength="8dp"
    app:minimumDashGap="3dp"
    app:layout_constraintRight_toRightOf="parent"
    android:id="@+id/horizontal_dashes"/>

공유해 주셔서 감사합니다. 유스 케이스에 맞게 수정해야하지만 이것이 바로 사용자 정의보기를 시작하는 데 필요한 것입니다. 건배.

0

tier777과 유사하게 수평선을 위한 해결책이 있습니다 :

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:top="-1dp">
        <shape android:shape="line">
            <stroke
                android:width="1dp"
                android:color="#111"
                android:dashWidth="8dp"
                android:dashGap="2dp"
                />
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>
</layer-list>

단서는 <item android:top="-1dp">입니다.

기존 장치 (<= API 21)에서 점선을 표시하려면 다음을 사용하여보기를 작성해야합니다 android:layerType="software"( Android 점선 잠재적 인 ICS 버그 참조 ).

<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="@drawable/dashed_line"
    android:layerType="software"
    />

또한 당신은하지 않고 동일한보기를 추가 할 수 있습니다 android:layerType="software"layout-v23더 나은 성능을 위해,하지만 확실히는 API (23) 모든 장치에서 작동하고 있지 않다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.