水平向线性布局动态添加等权重的TextViews

huangapple go评论62阅读模式
英文:

Horizontally Add TextViews to Equally Weighted Linear Layout Dynamically

问题

我正在学习Android,为此我想动态地将TextView添加到线性布局中,每个TextView具有相等的权重,例如:

textview1 textview2(依此类推)

但是,如果只有一个TextView,它应该填充父布局,即应该使用match parent;如果有两个项,则它们应该各自填充父布局的一半!

这是我在RecyclerView中用于动态填充线性布局的方法:

private void populateResourcesItems(ArrayList<ResourcesItem> resources, int position, RecyclerViewHolder recyclerViewHolder) {
    recyclerViewHolder.resourceItemsLayout.removeAllViews();
    for (int its = 0; its < resources.size(); its++) {
        PackagesViewItem packagesViewItem = new PackagesViewItem(context);
        if (hasValue(resources.get(its).getResourceName())) {
            packagesViewItem.getResourcesItem().setText(resources.get(its).getResourceName());
            packagesViewItem.getResourcesItem().setSelected(true);
        }
        
        // 将视图项布局添加到适配器容器
        recyclerViewHolder.resourceItemsLayout.addView(packagesViewItem);
    }
}

这是在RecyclerView布局中的LinearLayout:

<LinearLayout
    android:weightSum="1"
    android:background="@color/colorPrimary"
    android:id="@+id/resourceItemsLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@id/subscribeButton"
    android:layout_below="@+id/resourcesTitle"
    android:layout_marginStart="@dimen/_20sdp"
    android:layout_marginTop="@dimen/_5sdp"
    android:layout_marginEnd="@dimen/_20sdp"
    android:layout_marginBottom="@dimen/_20sdp"
    android:orientation="horizontal" />

这是用于填充视图的类:

public class PackagesViewItem extends FrameLayout {
    
    private LinearLayout resourcesViewItemLayout;
    private TextView resourcesItem;
    
    @SuppressLint("InflateParams")
    public PackagesViewItem(@NonNull Context context) {
        super(context);
        resourcesViewItemLayout = (LinearLayout) LayoutInflater.from(context).inflate(
            R.layout.layout_packages_view_item, null);
        
        resourcesItem = (TextView) resourcesViewItemLayout.findViewById(R.id.resourcesItem);
        this.addView(resourcesViewItemLayout);
    }
    
    // 省略其他方法
}

视图项类的布局如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/resourcesViewItemLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@color/packagesTabTextColorUnselected">
        
        <TextView
            android:id="@+id/resourcesItem"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fontFamily="@font/opensans_regular"
            android:gravity="center"
            android:includeFontPadding="false"
            android:text="@string/mobile_bundles_resources"
            android:textColor="@color/colorPrimary"
            android:textSize="@dimen/_12ssp"
            android:visibility="visible" />
    </LinearLayout>
    
</LinearLayout>

问题是,当只有一个TextView时,它不会填充父布局,如图所示。

我想要实现类似这些框:

水平向线性布局动态添加等权重的TextViews

英文:

I am learning Android to my own for this I want to dynamically add textviews to the linear layout with equal weights for expample:

textview1 textview2 (so on)

but if there is only one textview it should fill the parent that is it should be match parent and if there are two items then they should half fill the parent for each item!

so this is my populating method inside the recycler view to dynamically populate the linear layout with text views:

private void populateResourcesItems(ArrayList&lt;ResourcesItem&gt; resources, int position, RecyclerViewHolder recyclerViewHolder) {
        recyclerViewHolder.resourceItemsLayout.removeAllViews();
        for (int its = 0; its &lt; resources.size(); its++) {
            PackagesViewItem packagesViewItem = new PackagesViewItem(context);
            if (hasValue(resources.get(its).getResourceName())) {
                packagesViewItem.getResourcesItem().setText(resources.get(its).getResourceName());
                packagesViewItem.getResourcesItem().setSelected(true);
            }

            //add the view item layout to adapter container
            recyclerViewHolder.resourceItemsLayout.addView(packagesViewItem);
        }//for end
    }//populateResourcesItems ends

and this is my linear layout inside the recycler view layout:

            &lt;LinearLayout
            android:weightSum=&quot;1&quot;
            android:background=&quot;@color/colorPrimary&quot;
            android:id=&quot;@+id/resourceItemsLayout&quot;
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;match_parent&quot;
            android:layout_above=&quot;@id/subscribeButton&quot;
            android:layout_below=&quot;@+id/resourcesTitle&quot;
            android:layout_marginStart=&quot;@dimen/_20sdp&quot;
            android:layout_marginTop=&quot;@dimen/_5sdp&quot;
            android:layout_marginEnd=&quot;@dimen/_20sdp&quot;
            android:layout_marginBottom=&quot;@dimen/_20sdp&quot;
            android:orientation=&quot;horizontal&quot; /&gt;

here is my class to popuplate the views inside the framelayout:

public class PackagesViewItem extends FrameLayout {

    private LinearLayout resourcesViewItemLayout;
    private TextView resourcesItem;

    @SuppressLint(&quot;InflateParams&quot;)
    public PackagesViewItem(@NonNull Context context) {
        super(context);
        resourcesViewItemLayout = (LinearLayout) LayoutInflater.from(context).inflate(
                R.layout.layout_packages_view_item, null);

        resourcesItem = (TextView) resourcesViewItemLayout.findViewById(R.id.resourcesItem);
        this.addView(resourcesViewItemLayout);
    }//constructor ends

    public LinearLayout getResourcesViewItemLayout() {
        return resourcesViewItemLayout;
    }

    public void setResourcesViewItemLayout(LinearLayout resourcesViewItemLayout) {
        this.resourcesViewItemLayout = resourcesViewItemLayout;
    }

    public TextView getResourcesItem() {
        return resourcesItem;
    }

    public void setResourcesItem(TextView resourcesItem) {
        this.resourcesItem = resourcesItem;
    }
}//class ends

and the layout for this view item class is:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:id=&quot;@+id/resourcesViewItemLayout&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:orientation=&quot;horizontal&quot;&gt;

    &lt;LinearLayout
        android:layout_width=&quot;0dp&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_weight=&quot;1&quot;
        android:background=&quot;@color/packagesTabTextColorUnselected&quot;&gt;

        &lt;TextView
            android:id=&quot;@+id/resourcesItem&quot;
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:fontFamily=&quot;@font/opensans_regular&quot;
            android:gravity=&quot;center&quot;
            android:includeFontPadding=&quot;false&quot;
            android:text=&quot;@string/mobile_bundles_resources&quot;
            android:textColor=&quot;@color/colorPrimary&quot;
            android:textSize=&quot;@dimen/_12ssp&quot;
            android:visibility=&quot;visible&quot; /&gt;
    &lt;/LinearLayout&gt;

&lt;/LinearLayout&gt;

the problem is that it when the item is single textview is not filling the parent see here:

水平向线性布局动态添加等权重的TextViews

I want to achieve like these boxes:

水平向线性布局动态添加等权重的TextViews

答案1

得分: 2

从您的LinearLayout中删除android:weightSum="1",并定义以下LinearLayout.LayoutParams

val linearLayout: LinearLayout = findViewById(R.id.layout)
val lp = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT)
lp.weight = 1f

然后,将其应用于布局中添加的视图:

val textView: TextView = TextView(context)
textView.setText("Text1")
textView.height = ...
//...

val textView2: TextView = TextView(context)
textView2.setText("Text2")
textView2.height = ...
//....

linearLayout.addView(textView, lp)
linearLayout.addView(textView2, lp)
英文:

Remove in your LinearLayout android:weightSum=&quot;1&quot; and define this LinearLayout.LayoutParams:

    val linearLayout : LinearLayout = findViewById(R.id.layout)
    val lp = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT)
    lp.weight = 1f

Then just apply to the views added in the layout:

    val textView : TextView = TextView(context)
    textView.setText(&quot;Text1&quot;)
    textView.height = ...
    //...

    val textView2 : TextView = TextView(context)
    textView2.setText(&quot;Text2&quot;)
    textView2.height = ...
    //....

    linearLayout.addView(textView, lp)
    linearLayout.addView(textView2, lp)

答案2

得分: 0

在您的代码中存在许多问题,但问题是关于不必要的边距,所以...

不要设置它们

android:layout_marginStart="@dimen/_20sdp"
android:layout_marginTop="@dimen/_5sdp"
android:layout_marginEnd="@dimen/_20sdp"
android:layout_marginBottom="@dimen/_20sdp"

同时移除android:weightSum="1",并且像Gabriele Mariotti建议的那样为创建的TextView设置权重。

英文:

there are plenty of problems in your code, but question is about unneeded margins so...

don't set them

        android:layout_marginStart=&quot;@dimen/_20sdp&quot;
        android:layout_marginTop=&quot;@dimen/_5sdp&quot;
        android:layout_marginEnd=&quot;@dimen/_20sdp&quot;
        android:layout_marginBottom=&quot;@dimen/_20sdp&quot;

also remove android:weightSum=&quot;1&quot; and set weight for created TextViews just like Gabriele Mariotti suggested

huangapple
  • 本文由 发表于 2020年10月14日 16:58:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/64349884.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定