在这种情况下如何以预定方式将Button扩展为LinearLayout?

时间:2017-07-25 15:08:09

标签: android

我的任务是生成几个固定宽度和高度的按钮。我决定将这些按钮存储在某个ArrayList中,以备将来使用。我就是这样做的:

 for(int i = 1 ; i<=n; i++)
{
 Button place = new Button(this.context) ;

      place.setTextColor(ContextCompat.getColor
     (this.context,R.color.background_color));

    place.setTypeface(typefaceForPlaces);

    place.setId(i+0);

    place.setBackgroundResource(R.drawable.real_place_background);

    place.setLayoutParams(new 
    LinearLayout.LayoutParams(65,65));

    places.add(place);

}

但问题在这里 place.setLayoutParams(newLinearLayout.LayoutParams(65,65));

此处,宽度和高度以像素为单位。但我需要dp。我知道代码 将dp转换为像素,但我不认为这是一个很好的解决方案。现在,我有一个想法,创建一些布局并存储我的按钮的形状。这是我的名为place_button.xml的布局:

    <?xml version="1.0" encoding="utf-8"?>
   <Button 
    xmlns:android="http://schemas.android.com/apk/res/android"    
    android:id="@+id/button_id"
    android:layout_width="50dp" 
    android:layout_height="50dp"
    android:background="@drawable/real_place_background"
    android:textColor="#202020">
    </Button>

我创建了一些View并将该按钮膨胀到此视图。在那之后,我通过它的id得到了上面的按钮并将其保存到另一个按钮,因为我需要很多这样的按钮。然后我需要更改新按钮的ID。但我得到了以下错误:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.incubic.abay.clasico/com.incubic.abay.clasico.GameActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setId(int)' on a null object reference

以下是我的代码:

 private void generatePlaces() {
        View place_view = LayoutInflater.from(getContext()).inflate(R.layout.place_button,null);
        for(int i = 1 ; i<=n; i++)
        {

            Button place = (Button)place_view.findViewById(R.id.button_id);
            place.setId(i+0);
            place.setTypeface(typefaceForPlaces);
            places.add(place) ;
           }
    }

一切都发生在Fragment中。在generatePlaces之后调用onViewCreated方法。如何解决我的问题?

2 个答案:

答案 0 :(得分:1)

由于缺少Button ID

,您可能会遇到问题
<?xml version="1.0" encoding="utf-8"?>
<Button
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/button_id"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@drawable/real_place_background"
        android:textColor="#202020"/>

<强>更新

当你做通货膨胀时,你已经得到了按钮视图,不需要做findViewById。

总的来说,我不认为在你的案例中夸大一个观点是一个好方法。更好地创建按钮:

private void generatePlaces()
{
    for (int i = 1; i <= n; i++)
    {
        Button place = new Button(this.context);

        place.setTextColor(ContextCompat.getColor(this.context, R.color.background_color));
        place.setTypeface(typefaceForPlaces);
        place.setId(i + 0);
        place.setBackgroundResource(R.drawable.real_place_background);
        place.setLayoutParams(new LinearLayout.LayoutParams(dpToPx(50), dpToPx(50)));

        places.add(place);

    }
}

private int dpToPx(int dp)
{
    return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}

答案 1 :(得分:1)

我认为这是因为你更改了按钮的//stored properties var totalWidthPerRow = CGFloat(0) var rowCounts = 0 let spaceBetweenCell = CGFloat(10) // whatever the space between each cell is func collectionView(_collectionView:UICollectionView,layoutcollectionViewLayout:UICollectionViewLayout,sizeForItemAt indexPath: IndexPath) -> CGSize { let collectionViewWidth = view.frame.width let dynamicCellWidth = //whatever you calculate the width totalWidthPerRow += dynamicCellWidth + spaceBetweenCell if (totalWidthPerRow > collectionViewWidth) { rowCounts += 1 totalWidthPerRow = dynamicCellWidth + spaceBetweenCell } return CGSizeMake(dynamicCellWidth , CGFloat(30)) } ,在下一次迭代中你会得到一个空指针异常。我会完全以编程方式创建按钮视图,而不是从xml创建,然后将它们附加到父视图。或者查看listviews之类的内容。

我会说你的早期方法,并参考this question转换为DP。