设置TextView以填充所有其他区域,使用XML -Android离开ImageView Space

时间:2016-04-28 22:52:54

标签: android xml listview view

enter image description here

我正在尝试使用两个TextView和一个ImageView设置完全相同的布局。任何人都可以帮我用android XML

设置这样的视图

1 个答案:

答案 0 :(得分:1)

您可以使用DynamicLayout和SpannableStringBuilder而不是TextView来完成它。

首先,您需要知道ImageView的界限,如果将DynamicLayout和ImageView放在自定义的ViewGroup中会更容易,因为这会将它们放在相同的坐标空间中。

second ,使用方法 getLineForVertical 根据Bound rect的顶值获取DynamicLayout中的第一行。并使用DynamicLayout方法获取与Bound rect的左值最接近的偏移量< strong> getOffsetForHorizo​​ntal ,然后在偏移后插入一个空格字符,并创建一个ImageSpan,其中一个空的drawable的宽度为Bound rect的宽度,并将ImageSpan放在SpannableStringBuilder中,并使span开始于offset并以偏移+ 1。

第三次,行++并重复第二步,直到getLineTop(line)值大于Bound rect的底部。

我为你写了一个演示,你可以在里面移动Rectangle来看看DynamicLayout如何为Rectangle重新布局,但是确保你不要将矩形移到DynamicLayout之外,它会崩溃。我没有解决这个原因,它只是一个演示。

public class DynamicRichText extends View {

private DynamicLayout mLayout;
private Point mCirclePosition;
private int mCircleRadius;
private Rect mRect;
private TextPaint mTextPaint;

private int latestFirstLine;
private int latestLastLine;
private int latestOffsetStart;
private int latestOffsetEnd;

private SpannableStringBuilder mText;

public DynamicRichText(Context context){
    this(context, null);
}

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

public DynamicRichText(Context context, AttributeSet attrs, int defStyle){
    super(context, attrs, defStyle);

    mText = new SpannableStringBuilder("abcdefghijklmnopqrstuvwxyz" +
            "abcdefghijklmnopqrstuvwxyz" +
            "abcdefghijklmnopqrstuvwxyz" +
            "abcdefghijklmnopqrstuvwxyz" +
            "abcdefghijklmnopqrstuvwxyz" +
            "abcdefghijklmnopqrstuvwxyz" +
            "abcdefghijklmnopqrstuvwxyz" +
            "abcdefghijklmnopqrstuvwxyz" +
            "abcdefghijklmnopqrstuvwxyz" +
            "abcdefghijklmnopqrstuvwxyz" +
            "abcdefghijklmnopqrstuvwxyz" +
            "abcdefghijklmnopqrstuvwxyz" +
            "abcdefghijklmnopqrstuvwxyz" +
            "abcdefghijklmnopqrstuvwxyz" +
            "abcdefghijklmnopqrstuvwxyz" +
            "abcdefghijklmnopqrstuvwxyz");

    mRect = new Rect();
    mCirclePosition = new Point();
    mCircleRadius = 120;
    mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
    mTextPaint.setTextSize(80);
    mTextPaint.setColor(0xFF0099CC);
}

@Override
public boolean onTouchEvent(MotionEvent event){
    if(event.getActionMasked() == MotionEvent.ACTION_MOVE){
        mCirclePosition.x = (int) event.getX();
        mCirclePosition.y = (int) event.getY();
        mRect.left = mCirclePosition.x - mCircleRadius;
        mRect.right = mCirclePosition.x + mCircleRadius;
        mRect.top = mCirclePosition.y - mCircleRadius;
        mRect.bottom = mCirclePosition.y + mCircleRadius;

        resolveLayout();

        invalidate();

    }

    return true;
}

private void resolveLayout(){

    Object[] spans = mText.getSpans(latestOffsetStart, latestOffsetEnd, Object.class);
    for(int i = 0; i < spans.length; i++){
        int start = mText.getSpanStart(spans[i]);
        if(spans[i] instanceof ImageSpan) mText.delete(start, start + 1);
        mText.removeSpan(spans[i]);

    }

    int line = mLayout.getLineForVertical(mRect.top);

    int offsetStart = mLayout.getOffsetForHorizontal(line, mRect.left) - 1;
    latestOffsetStart = offsetStart;
    while(mLayout.getLineTop(line) < mRect.bottom){
        offsetStart = mLayout.getOffsetForHorizontal(line, mRect.left) - 1;
        int lineHeight = mLayout.getLineBottom(line) - mLayout.getLineTop(line);

        mText.insert(offsetStart, " ");

        ColorDrawable emptyDrawable = new ColorDrawable(0x0);
        emptyDrawable.setBounds(0, 0, mRect.width() + (int) mTextPaint.getTextSize(), lineHeight);
        ImageSpan emptySpan = new ImageSpan(emptyDrawable);
        mText.setSpan(emptySpan, offsetStart, offsetStart + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);


        line++;
    }

    latestOffsetEnd = offsetStart + 1;

}

@Override
public void onSizeChanged(int w, int h, int oldw, int oldh){
    mCirclePosition = new Point(w / 2, h / 2);
    mLayout = new DynamicLayout(mText, mText, mTextPaint, w, Layout.Alignment.ALIGN_NORMAL, 1, 0, false);
}

@Override
public void onDraw(Canvas canvas){
    mTextPaint.setColor(0xFF000000);
    canvas.drawRect(mRect, mTextPaint);
    mTextPaint.setColor(0xFF0099CC);
    mLayout.draw(canvas);
}
}

如果您将其更改为扩展ViewGroup或其他布局窗口小部件。并根据ImageView的bound创建Rect。您可以在xml中使用此小部件