在水平 LinearLayout 中动态添加 TextViews

Adding TextViews inside horizontal LinearLayout dynamically

Click here to see the image

在我的应用程序的个人资料页面中,我想要一个兴趣部分,如图所示。用户在他的个人资料下有一个兴趣列表。我想在水平 LinearLayout 中显示 his/her 兴趣。我已经创建了一个 TextViews 数组并在父 LinearLayout 中动态添加它们,但是当没有更多 space 时我不想添加 TextViews。相反,我想添加一个显示剩余兴趣数量的 TextView。

如图所示(使用图片link),用户有24个兴趣,其中4个横排在同一行,最后一个TextView(+20)显示剩余兴趣的数量同一条线。

String interestList[]={"Travel","Music","Photography","Sports","Dance","Animals","SciFi Movies"};
    int interestWidth =0, parentWidth=interestLinearLayout.getWidth();
    for(String interest: interestList) {
        TextView textView = new TextView(MainActivity.this);
        textView.setBackground(getResources().getDrawable(R.drawable.interests_bg));
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        params.setMargins(2,0,10,2);
        textView.setLayoutParams(params);
        textView.setPadding(2, 2, 2, 2);
        textView.setText(" "+interest+" ");
        textView.setTextColor(getResources().getColor(R.color.white));
        textView.setIncludeFontPadding(true);
        interestWidth += textView.getWidth();
        if(interestWidth<parentWidth) //both are 0 on first iteration of loop???
            interestLinearLayout.addView(textView);
        else
            break;
    }

您可以动态添加视图,但首先您需要引用要添加视图的父视图。

您只需使用 findViewById 即可完成此操作。假设它是线性布局,

LinearLayout parent = findViewById(R.id.parent);
// Then create a textview
TextView textView = new TextView(this);
// Add the view to the parent
parent.addView(textView);

就是这样!要更改有关 TextView 的属性,您可以使用 TextView getter 和 setter。如果要更改 TextView 的边距、填充或宽度的高度,请使用 LayoutParams

// Remember that I'm using LinearLayout.LayoutParams because  the parent of the ttextview is a  LinearLayout
LinearLayout.LayourParams params = textView.getLayoutParams();
// Remember these values are in pixels
params.height = 100;
params.width = 200;

使用这种方法有很多问题,例如以像素而不是 dps 设置高度和宽度。并在 xml 中可以完成的情况下编写大量代码。但是,您可以通过在 res/layout 中创建一个 xml 文件,然后对其进行扩充并最终将其添加到父文件中来简化此过程。

您可以通过 -

// First get the layout inflater
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
TextView textView = inflater.inflate(R.layout.myTextView, null);
linearLayout.addView(textView);

终于解决了关于仅添加足够的视图以使 linearLayout 不超出屏幕宽度的问题。

最简单的解决方案是,循环遍历兴趣列表,并在循环的每次迭代中,测量创建的 TextView 的组合宽度,然后检查它是否超过 linearLayout 的宽度。

它看起来类似于这个 -

int combinedWidth = 0;
int linearLayoutWidth = linearLayout.getMeasuredWidth();
for(String interest : interests){
    TextView view = inflater.inflate(R.layout.textview, null);
    combinedWidth += textView.getMeasuredWidth();
    view.setText(interest);
    if(combinedWidth > linearLayoutWidth){
        // No need to add more views
        break;
    }else{
        linearLayout.addView(textView);
    }
}

但是,上述解决方案可能有效也可能无效,具体取决于执行时间。所以 post activity 代码和 xml 文件,这样我可以更好地回答你的问题。

要创建一个 LinearLayout,

LinearLayout layout = new LinearLayout(MainActivity.this);

要设置布局的背景颜色,

layout.setBackgroundColor(Color.parseColor("#135517"));

设置布局的宽度和高度,

    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams
                    (LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(15, 5, 5, 5);
layout.setLayoutParams(params);

方位,

layout.setOrientation(LinearLayout.HORIZONTAL);          
layout.setHorizontalGravity(Gravity.CENTER_HORIZONTAL);
layout.setPadding(10, 10, 5, 5);

然后创建一个textview,

    TextView textView = new TextView(this);
textView.setLayoutParams(params);
        textView.setPadding(2, 2, 2, 2);
        textView.setText(" "your" ");
        textView.setTextColor(getResources().getColor(R.color.white));
        textView.setIncludeFontPadding(true);

将视图添加到父视图,

layout.addView(textView);

interestWidth和parentWidth初始为0,因为调用getWidth时还没有布局

get width for dynamically created textViews

以上 link 帮助我从 interestList 获取动态创建的 textView 的宽度。

并且通过在 interestLinearLayout 上使用 ViewTreeObserver,我能够在布局后获得 LinearLayout 的宽度。

最后,上面的代码应该修改如下,在 LinearLayout 中添加来自 JAVA 的 textView。

       final LinearLayout interestLinearLayout = findViewById(R.id.interests);
       interestLinearLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                interestLinearLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                String interestList[]={"Travel","Music","Photography","Sports","Dance","Animals","SciFi Movies"};
                int interestWidth =0;
                int parentWidth = interestLinearLayout.getWidth(); // got width inside view tree observer for linearlayout
                for(String interest: interestList) {
                    TextView textView = new TextView(MainActivity.this);
                    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                    params.setMargins(2,0,10,2);
                    textView.setLayoutParams(params);
                    textView.setPadding(2, 2, 2, 2);
                    textView.setText(interest);
                    textView.setIncludeFontPadding(true);
                    textView.measure(0,0); //using approach mentioned in link to get width of text views
                    interestWidth += textView.getMeasuredWidth(); 
                    if(interestWidth<parentWidth)
                        interestLinearLayout.addView(textView);
                    else
                        break;
                }
            }
        });