1

当我TextView的 s 中的字符串增长并溢出时,我遇到了问题,有时会隐藏另一个文本TextView或开始消失。

我希望它像这样工作(我知道这看起来很像摆动FlowLayout,但不完全是因为它的对齐方式不固定,一个组件左对齐,另一个右对齐):

 -------------------------------------
|[TextView0]               [TextView1]|
 -------------------------------------

当文本增长时:

    TextView0 grows:                        TextView1 grows:
 -------------------------------------    -------------------------------------
|[TextView0 TextView0 TextView0]      |  |[TextView0]                          |
|                          [TextView1]|  |      [TextView1 TextView1 TextView1]|
 -------------------------------------    -------------------------------------
  • 是否可以使用现有布局(可能使用布局组合)来完成?
  • 如果我确实需要构建一个新布局,我想要一个工作示例。

我已经尝试过ReleativeLayoutLinearLayout从未成功过:

  1. RelativeLayout

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
    
        <TextView
            android:id="@+id/TextView0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:text="TextView0" />
    
        <TextView
            android:id="@+id/TextView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:text="TextView1" />
    </RelativeLayout>
    

    当文本开始重叠时,我试图用TextView0being来修复toLeftOf="TextView1"。但在那种情况下TextView0消失了。

  2. LinearLayout

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
    
        <TextView
            android:id="@+id/TextView0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView0" />
    
        <TextView
            android:id="@+id/TextView1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="right"
            android:text="TextView1" />
    </LinearLayout>
    

    这里TextViews 开始干扰,当TextView0得到全宽时TextView1消失(它的宽度趋近于零)。

4

3 回答 3

1

Android-FlowLayout的最佳库之一,
它简单、易于使用且很棒。

于 2013-09-16T15:33:37.767 回答
0

为此,我尝试创建一个布局。

它就像我在原始问题中讨论的那样工作,但如果你做得更好,请随时更新答案!

public class KeyValueLayout extends ViewGroup {

    public KeyValueLayout(Context context) {
        super(context);
    }

    public KeyValueLayout(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
    }

    public KeyValueLayout(Context context, AttributeSet attributeSet, 
                          int defStyle) {
        super(context, attributeSet, defStyle);
    }

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

        int paddRight = getPaddingRight();
        int paddLeft = getPaddingLeft();
        int paddBottom = getPaddingBottom();
        int paddWidth = paddRight + paddLeft;

        int sizeWidth  = MeasureSpec.getSize(widthMeasureSpec) - paddWidth;
        int sizeHeight = MeasureSpec.getSize(heightMeasureSpec) - paddWidth;

        int modeWidth  = MeasureSpec.getMode(widthMeasureSpec);
        int modeHeight = MeasureSpec.getMode(heightMeasureSpec);

        int modeW = modeWidth == MeasureSpec.EXACTLY 
                        ? MeasureSpec.AT_MOST : modeWidth;
        int modeH = modeHeight == MeasureSpec.EXACTLY 
                        ? MeasureSpec.AT_MOST : modeHeight;

        // where the next view should be placed
        int lineYPosition = 0;

        for (int i = 0; i < getChildCount(); ) {

            View key = getChildAt(i++);

            key.measure(
                    MeasureSpec.makeMeasureSpec(sizeWidth, modeW),
                    MeasureSpec.makeMeasureSpec(sizeHeight, modeH)
            );

            LayoutParams keyLp = (LayoutParams) key.getLayoutParams();
            keyLp.setPosition(paddLeft, lineYPosition);

            if (i >= getChildCount()) 
                break;

            View val = getChildAt(i++);

            val.measure(
                    MeasureSpec.makeMeasureSpec(sizeWidth, modeW),
                    MeasureSpec.makeMeasureSpec(sizeHeight, modeH)
            );

            LayoutParams valLp = (LayoutParams) val.getLayoutParams();

            int valXPosition = paddLeft + sizeWidth - val.getMeasuredWidth();

            // check if both fit on the same line
            if (key.getMeasuredWidth() + val.getMeasuredWidth() <= sizeWidth) {

                valLp.setPosition(valXPosition, lineYPosition);

                lineYPosition += Math.max(key.getMeasuredHeight(), 
                                          val.getMeasuredHeight());
            } else {

                // not enough room, make some space 
                lineYPosition += key.getMeasuredHeight();

                valLp.setPosition(valXPosition, lineYPosition);

                lineYPosition += val.getMeasuredHeight();
            }
        }

        int controlMaxLength = sizeWidth + paddRight; 
        int controlMaxThickness = lineYPosition + paddBottom;

        int resolvedWidth = resolveSize(controlMaxLength, widthMeasureSpec);
        int resolvedHeight =resolveSize(controlMaxThickness,heightMeasureSpec);
        this.setMeasuredDimension(resolvedWidth, resolvedHeight);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            LayoutParams lp = (LayoutParams) child.getLayoutParams();
            child.layout(lp.x, lp.y, 
                         lp.x + child.getMeasuredWidth(), 
                         lp.y + child.getMeasuredHeight());
        }
    }

    @Override
    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
        return p instanceof LayoutParams;
    }

    @Override
    protected LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams(LayoutParams.WRAP_CONTENT, 
                                LayoutParams.WRAP_CONTENT);
    }

    @Override
    public LayoutParams generateLayoutParams(AttributeSet attributeSet) {
        return new LayoutParams(getContext(), attributeSet);
    }

    @Override
    protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
        return new LayoutParams(p);
    }

    public static class LayoutParams extends ViewGroup.LayoutParams {

        private int x;
        private int y;

        public LayoutParams(Context context, AttributeSet attributeSet) {
            super(context, attributeSet);
        }

        public LayoutParams(int width, int height) {
            super(width, height);
        }

        public LayoutParams(ViewGroup.LayoutParams layoutParams) {
            super(layoutParams);
        }

        public void setPosition(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
}

示例用法:

<nu.wen.android.layout.KeyValueLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/example_string_long"
        android:textStyle="bold" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/example_string_short" />
</nu.wen.android.layout.KeyValueLayout>
于 2014-04-04T23:52:19.397 回答
0

简短的回答是“是”——因为它只是软件,任何事情都可以做:)。但是,我认为您无法使用任何标准布局来实现它。

所以我最好的选择是你创建自己的 View 类,然后以你想要的任何方式布局。您可能想阅读此(如果您还没有)作为起点:

http://developer.android.com/training/custom-views/create-view.html

于 2013-09-16T14:43:37.930 回答