简体   繁体   English

动态在水平LinearLayout中添加TextViews

[英]Adding TextViews inside horizontal LinearLayout dynamically

Click here to see the image 点击这里查看图片

In the profile page of my application, I want to have an interest section as shown in the image. 在我的应用程序的配置文件页面中,我想要一个感兴趣的部分,如图所示。 The user has a list of interest under his profile. 用户在其个人资料下有一个兴趣列表。 I want to show his/her interests inside a horizontal LinearLayout. 我想在水平LinearLayout中显示他/她的兴趣。 I have created an array of TextViews and add them dynamically inside the parent LinearLayout, but I do not want to add the TextViews when there is no more space. 我已经创建了一个TextViews数组,并在父级LinearLayout中动态添加它们,但是当没有更多空间时,我不想添加TextViews。 Instead, I want to add a TextView showing the number of remaining interests. 相反,我想添加一个TextView来显示剩余兴趣的数量。

As shown in the picture (use the image link), the user had 24 interests, 4 of them fit horizontally on the same line and last TextView(+20) shows the number of remaining interests on the same line. 如图所示(使用图像链接),用户有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;
    }

You can add views dynamically but first you need a reference to the parent view to which you want to add a view. 您可以动态添加视图,但首先需要引用要向其添加视图的父视图。

You can do this by just using findViewById. 您可以只使用findViewById来做到这一点。 Assuming it's a linear layout, 假设它是线性布局,

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

And that's it! 就是这样! To change properties about the TextView, you can use TextView getters and setters. 若要更改有关TextView的属性,可以使用TextView getter和setter。 If you want to change the margin, padding or height of width of the TextView, use LayoutParams 如果要更改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;

There are tons of problems using this method, such as setting height and width in pixels instead of dps. 使用此方法存在很多问题,例如以像素而不是dps设置高度和宽度。 And writing a lot of code when you could have done it in xml. 当您可以在xml中完成代码时,请编写大量代码。 You can however make this much easier by creating an xml file in your res/layout and then inflating it and finally adding it to the parent. 但是,通过在res / layout中创建一个xml文件,然后对其进行充气并最终将其添加到父级,可以使此过程变得更加容易。

You can do this by - 您可以通过-

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

Finally addressing your problem about adding only enough views that the linearLayout doesn't go beyond the screen width. 最后解决您的问题,即仅添加足够的视图以使linearLayout不会超出屏幕宽度。

The easiest solution is, to loop through the interest list and in every iteration of the loop, measure the combined width of the TextViews created and then checking whether it exceeds the width of the linearLayout. 最简单的解决方案是遍历兴趣列表,并在循环的每次迭代中,测量创建的TextView的组合宽度,然后检查其是否超过linearLayout的宽度。

It would look similar to this - 看起来与此类似-

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);
    }
}

However, the above solution may or may not work depending on when it is executed. 但是,根据何时执行上述解决方案,它可能会起作用,也可能不会起作用。 So post the activity code along with the xml file so that I can better answer your question. 因此,将活动代码与xml文件一起发布,以便我更好地回答您的问题。

The interestWidth and parentWidth are initially 0 because they have not been laid out when getWidth is called. interestWidth和parentWidth最初为0,因为在调用getWidth时尚未布置它们。

get width for dynamically created textViews 获取动态创建的textViews的宽度

The above link helped me getting width of dynamically created textViews from interestList. 上面的链接帮助我从interestList获取动态创建的textViews的宽度。

And by using ViewTreeObserver on interestLinearLayout I was able to get the width of LinearLayout after it was laid out. 通过在interestLinearLayout上使用ViewTreeObserver,我可以在布置LinearLayout后获得它的宽度。

Finally, the above code should be modified as below to add textViews from JAVA inside a LinearLayout. 最后,应修改以下代码,以在LinearLayout中从JAVA添加textViews。

       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;
                }
            }
        });

To create a LinearLayout, 要创建LinearLayout,

LinearLayout layout = new LinearLayout(MainActivity.this);

To set background color of a layout, 要设置布局的背景色,

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

To set width and height of the layout, 要设置版式的宽度和高度,

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

The orientation, 方向,

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

Then create a textview, 然后创建一个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);

Add the view to the parent, 将视图添加到父级,

layout.addView(textView);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM