以编程方式用按钮填充屏幕

时间:2014-11-05 11:12:11

标签: android button layout

我尝试以编程方式向布局添加按钮,以便将它们自动定位在现有布局旁边,或者如果它们不合适则放在新行上。

我不确定我是否正确解释,所以会举例说明我想要实现的结果:

手机屏幕:

|[button1][button2][button3]|
|[sort][LongButton][sort]   |
|[tooLongSoGoesNextRow]...  |

到目前为止,我已设法自动将它们放在同一行中,但无法使它们跳起来#34;跳跃"如果它们不再适合当前的那一行,那就到下一行。我来自HTML,我认为这样做很容易,但要么我做错了,要么就是......

这就是我的布局目前的样子:

<LinearLayout
        android:layout_width="fill_parent"
        android:id="@+id/buttonsLayout"
        android:layout_height="wrap_content">
</LinearLayout>

我用来添加按钮的代码:

   LinearLayout layout = (LinearLayout) findViewById(R.id.buttonsLayout);

   //set the properties for button
   Button btnTag = new Button(getApplicationContext());
   btnTag.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
   btnTag.setText("WHATEVER");
   btnTag.setId(generator.nextInt());

   //add button to the layout
   layout.addView(btnTag);

这将在同一行上添加按钮,而不会相互重叠,但它们会一直相互叠加,即使它们不适合屏幕。

非常感谢任何帮助。

谢谢! 哈维尔

1 个答案:

答案 0 :(得分:4)

最终,我使用自定义ViewGroup解决了这个问题(遵循此http://hzqtc.github.io/2013/12/android-custom-layout-flowlayout.html):

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

public class FlowLayout extends ViewGroup {

    private int paddingHorizontal;
    private int paddingVertical;

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

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

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

    private void init() {
        paddingHorizontal = 0;
        paddingVertical = 0;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int childLeft = getPaddingLeft();
        int childTop = getPaddingTop();
        int lineHeight = 0;
        // 100 is a dummy number, widthMeasureSpec should always be EXACTLY for FlowLayout
        int myWidth = resolveSize(100, widthMeasureSpec);
        int wantedHeight = 0;
        for (int i = 0; i < getChildCount(); i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() == View.GONE) {
                continue;
            }
            // let the child measure itself
            child.measure(
                    getChildMeasureSpec(widthMeasureSpec, 0, child.getLayoutParams().width),
                    getChildMeasureSpec(heightMeasureSpec, 0, child.getLayoutParams().height));
            int childWidth = child.getMeasuredWidth();
            int childHeight = child.getMeasuredHeight();
            // lineheight is the height of current line, should be the height of the heightest view
            lineHeight = Math.max(childHeight, lineHeight);
            if (childWidth + childLeft + getPaddingRight() > myWidth) {
                // wrap this line
                childLeft = getPaddingLeft();
                childTop += paddingVertical + lineHeight;
                lineHeight = childHeight;
            }
            childLeft += childWidth + paddingHorizontal;
        }
        wantedHeight += childTop + lineHeight + getPaddingBottom();
        setMeasuredDimension(myWidth, resolveSize(wantedHeight, heightMeasureSpec));
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        int childLeft = getPaddingLeft();
        int childTop = getPaddingTop();
        int lineHeight = 0;
        int myWidth = right - left;
        for (int i = 0; i < getChildCount(); i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() == View.GONE) {
                continue;
            }
            int childWidth = child.getMeasuredWidth();
            int childHeight = child.getMeasuredHeight();
            lineHeight = Math.max(childHeight, lineHeight);
            if (childWidth + childLeft + getPaddingRight() > myWidth) {
                childLeft = getPaddingLeft();
                childTop += paddingVertical + lineHeight;
                lineHeight = childHeight;
            }
            child.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
            childLeft += childWidth + paddingHorizontal;
        }
    }
}

在布局中:

    <my.package.app.FlowLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/buttonsContainer"/>

以编程方式添加按钮:

            ViewGroup flowContainer = (ViewGroup) findViewById(R.id.buttonsContainer);
            Button btnTag = new Button(getApplicationContext());
            btnTag.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
            btnTag.setText("whatever");
            btnTag.setId(23425);
            flowContainer.addView(btnTag);

我希望它对某人有所帮助。现在我只是在努力添加一个垂直滚动条:)。

祝你好运, 哈维尔