1

I want an underline below OPTINGはテキストの間にスペースを与えると私は以下のように選ぶ以下の下線をしたいが、私はこれを作成したときのCustomViewの助けは、ちょうど選ぶの下に表示されます下線ます

アンドロイドのCustomViewで下線が、私は、テキストとの間にいくつかのスペースが欲しいですline like image

カスタムビューを作成しました。カスタムビューでは、見つかった場合は文字列内で検索され、対応するテキストには下線が引かれますが、唯一必要なのはアンダーラインとテキストの間にスペースを入れることです、

私のクラスは次のとおりです。

import android.content.Context; 
import android.content.res.TypedArray; 
import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.graphics.Rect; 
import android.support.v7.widget.AppCompatTextView; 
import android.text.Layout; 
import android.util.AttributeSet; 
import android.view.Display; 
import android.view.WindowManager; 
import android.widget.TextView; 


public class UnderLine extends AppCompatTextView { 

private Rect mRect; 
private Paint mPaint; 
private int mColor; 
private float density; 
private float mStrokeWidth; 
private String stringSeach; 

public UnderLine(Context context) { 
    this(context, null, 0); 
} 

public UnderLine(Context context, AttributeSet attrs) { 
    this(context, attrs, 0); 
} 

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

private void init(Context context, AttributeSet attributeSet, int defStyle) { 

    density = context.getResources().getDisplayMetrics().density; 

    TypedArray typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.UnderLine, defStyle, 0); 
    mColor = typedArray.getColor(R.styleable.UnderLine_underlineColorr, 0xFFFF0000); 
    stringSeach = typedArray.getString(R.styleable.UnderLine_underlineTextt); 
    mStrokeWidth = typedArray.getDimension(R.styleable.UnderLine_underlineWidthh, density * 2); 
    typedArray.recycle(); 

    mRect = new Rect(); 
    mPaint = new Paint(); 
    mPaint.setStyle(Paint.Style.STROKE); 
    mPaint.setColor(mColor); //line mColor 
    mPaint.setStrokeWidth(mStrokeWidth); 
} 

public int getUnderLineColor() { 
    return mColor; 
} 

public void setUnderLineColor(int mColor) { 
    this.mColor = mColor; 
    invalidate(); 
} 

public float getUnderlineWidth() { 
    return mStrokeWidth; 
} 

public void setUnderlineWidth(float mStrokeWidth) { 
    this.mStrokeWidth = mStrokeWidth; 
    invalidate(); 
} 

@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight()+110); 
} 

@Override 
protected void onDraw(Canvas canvas) { 
    TextView parentTextView = this; 
    Rect parentTextViewRect = new Rect(); 

    String targetWord = stringSeach.toLowerCase(); 
    int startOffsetOfClickedText = this.getText().toString().toLowerCase().indexOf(targetWord); 
    int endOffsetOfClickedText = startOffsetOfClickedText + targetWord.length(); 

    // Initialize values for the computing of clickedText position 
    Layout textViewLayout = parentTextView.getLayout(); 

    double startXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal((int)startOffsetOfClickedText); 
    double endXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal((int)endOffsetOfClickedText); 

    // Get the rectangle of the clicked text 
    int currentLineStartOffset = textViewLayout.getLineForOffset((int)startOffsetOfClickedText); 
    int currentLineEndOffset = textViewLayout.getLineForOffset((int)endOffsetOfClickedText); 
    boolean keywordIsInMultiLine = currentLineStartOffset != currentLineEndOffset; 
    textViewLayout.getLineBounds(currentLineStartOffset, parentTextViewRect); 

    // Update the rectangle position to his real position on screen 
    int[] parentTextViewLocation = {0,0}; 
    parentTextView.getLocationOnScreen(parentTextViewLocation); 

    double parentTextViewTopAndBottomOffset = (
      //parentTextViewLocation[1] - 
      parentTextView.getScrollY() + 
        parentTextView.getCompoundPaddingTop() 
    ); 

    parentTextViewRect.top += parentTextViewTopAndBottomOffset; 
    parentTextViewRect.bottom += parentTextViewTopAndBottomOffset; 

    // In the case of multi line text, we have to choose what rectangle take 
    if (keywordIsInMultiLine){ 

     WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); 
     Display display = wm.getDefaultDisplay(); 

     int screenHeight = display.getHeight(); 
     int dyTop = parentTextViewRect.top; 
     int dyBottom = screenHeight - parentTextViewRect.bottom; 
     boolean onTop = dyTop > dyBottom; 

     if (onTop){ 
      endXCoordinatesOfClickedText = textViewLayout.getLineRight(currentLineStartOffset); 
     } 
     else{ 
      parentTextViewRect = new Rect(); 
      textViewLayout.getLineBounds(currentLineEndOffset, parentTextViewRect); 
      parentTextViewRect.top += parentTextViewTopAndBottomOffset; 
      parentTextViewRect.bottom += parentTextViewTopAndBottomOffset; 
      startXCoordinatesOfClickedText = textViewLayout.getLineLeft(currentLineEndOffset); 
     } 

    } 

    parentTextViewRect.left += (
      parentTextViewLocation[0] + 
        startXCoordinatesOfClickedText + 
        parentTextView.getCompoundPaddingLeft() - 
        parentTextView.getScrollX() 
    ); 
    parentTextViewRect.right = (int) (
      parentTextViewRect.left + 
        endXCoordinatesOfClickedText - 
        startXCoordinatesOfClickedText 
    ); 


    canvas.drawLine(parentTextViewRect.left,parentTextViewRect.bottom+mStrokeWidth, parentTextViewRect.right, 
      parentTextViewRect.bottom+mStrokeWidth, mPaint); 
    super.onDraw(canvas); 
} 

}

次のように次のようにattrs.xmlは私がのCustomViewで初心者です、と私はこれを作成していた、

<UnderLine 
    style="@style/textView" 
    android:gravity="top|center" 
    app:underlineColorr="@color/signup_bottom_darkWhite" 
    app:underlineWidthh="2dp" 
    app:underlineTextt="OPTING" 
    android:text="ON FREE PARKING + DISCOUNTED RATES \n BY OPTING IN"/> 

<declare-styleable name="UnderLine" > 
    <attr name="underlineWidthh" format="dimension" /> 
    <attr name="underlineColorr" format="color" /> 
    <attr name="underlineTextt" format="string" /> 
</declare-styleable> 

サンプルレイアウトですstackoverflowのいくつかの答えの助けを借りて。これを行うには他の方法を示唆しないでください。

Anyhelpは大歓迎です。

答えて

1
次のように私は、私自身の見解を開発していた

package com.example.reprator.underlinetextview; 

import android.content.Context; 
import android.content.res.TypedArray; 
import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.graphics.Rect; 
import android.support.v7.widget.AppCompatTextView; 
import android.text.Layout; 
import android.util.AttributeSet; 

public class UnderlinedTextView extends AppCompatTextView { 

private Rect mRect; 
private Paint mPaint; 
private int mColor; 
private float mStrokeWidth; 
private float mMarginTop; 
private boolean isAllSelected; 
private int lineNumber; 
private int selectTextEachLine; 

public UnderlinedTextView(Context context) { 
    this(context, null, 0); 
} 

public UnderlinedTextView(Context context, AttributeSet attrs) { 
    this(context, attrs, 0); 
} 

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

private void init(Context context, AttributeSet attributeSet, int defStyle) { 

    float density = context.getResources().getDisplayMetrics().density; 

    TypedArray typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.UnderlinedTextView, defStyle, 0); 
    mColor = typedArray.getColor(R.styleable.UnderlinedTextView_underlineColor, 0xFFFF0000); 
    mStrokeWidth = typedArray.getDimension(R.styleable.UnderlinedTextView_underlineWidth, density * 2); 
    mMarginTop = typedArray.getDimension(R.styleable.UnderlinedTextView_underlineMarginTop, density * 2); 
    isAllSelected = typedArray.getBoolean(R.styleable.UnderlinedTextView_underlineIsAll, false); 
    lineNumber = typedArray.getInteger(R.styleable.UnderlinedTextView_underlineNoLine, 1); 
    selectTextEachLine = typedArray.getInteger(R.styleable.UnderlinedTextView_underlineTextEachLine, 3); 
    typedArray.recycle(); 

    mRect = new Rect(); 
    mPaint = new Paint(); 
    mPaint.setStyle(Paint.Style.STROKE); 
    mPaint.setColor(mColor); //line mColor 
    mPaint.setStrokeWidth(mStrokeWidth); 
} 

public int getUnderLineColor() { 
    return mColor; 
} 

public void setUnderLineColor(int mColor) { 
    this.mColor = mColor; 
    invalidate(); 
} 

public float getUnderlineWidth() { 
    return mStrokeWidth; 
} 

public void setUnderlineWidth(float mStrokeWidth) { 
    this.mStrokeWidth = mStrokeWidth; 
    invalidate(); 
} 

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

    int h = (int) (getMeasuredHeight() + mMarginTop); 
    setMeasuredDimension(widthMeasureSpec, h); 
} 

@Override 
protected void onDraw(Canvas canvas) { 

    final Layout layout = getLayout(); 
    float x_start, x_stop; 
    int firstCharInLine, lastCharInLine; 

    int limit = isAllSelected ? getLineCount() : lineNumber; 
    for (int i = 0; i < limit; i++) { 
     int baseline = getLineBounds(i, mRect); 
     firstCharInLine = layout.getLineStart(i); 
     lastCharInLine = layout.getLineEnd(i); 

     int textHighlight = isAllSelected ? lastCharInLine - 1 : (firstCharInLine + selectTextEachLine); 
     x_start = layout.getPrimaryHorizontal(firstCharInLine); 
     x_stop = layout.getPrimaryHorizontal(textHighlight); 

     float y = baseline + mStrokeWidth + mMarginTop; 
     canvas.drawLine(x_start, y, x_stop, y, mPaint); 
    } 

    super.onDraw(canvas); 
} 

}

と私のattars.xml次のように、

<declare-styleable name="UnderlinedTextView"> 
    <attr name="underlineWidth" format="dimension" /> 
    <attr name="underlineMarginTop" format="dimension" /> 
    <attr name="underlineColor" format="color" /> 
    <attr name="underlineText" format="string" /> 
    <attr name="underlineIsAll" format="boolean" /> 
    <attr name="underlineNoLine" format="integer" /> 
    <attr name="underlineTextEachLine" format="integer" /> 
</declare-styleable> 
+0

あり、それはある程度正しいです –

関連する問題