如何确定GridView的高度,是否可以更改?

时间:2013-09-10 07:05:11

标签: android gridview

我有一对垂直排列的GridView,它们由适配器填充按钮。我可以让GridViews填充父视图的宽度,但我不能让第二个GridView填充父视图的高度。

似乎GridViews的高度是固定的,无法更改。如果GridViews有足够的空间,他们就不会填充父级。如果没有足够的空间,它们将进入滚动模式 - 滚动模式无法关闭。

我不确定,但GridView似乎使用固定高度的子按钮视图,我无法弄清楚按钮(行)高度是如何确定的,或者我如何更改它或强制GridView填充父高度。

这里是GridViews的XML:

            <LinearLayout
                android:id="@+id/keypads"
                android:background="@color/keypad_background_color"
                android:layout_height="match_parent"
                android:layout_width="match_parent"
                android:isScrollContainer="false"
                android:orientation="vertical" >
            <GridView
                android:id="@+id/grdMeasButtons"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:numColumns="4"
                android:scrollbars="none"
                android:isScrollContainer="false"
                android:stretchMode="columnWidth" />

            <GridView
                android:id="@+id/grdNumButtons"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:numColumns="3"
                android:isScrollContainer="false"
                android:scrollbars="none"
                android:stretchMode="columnWidth" />
            </LinearLayout>

请注意,我的原始版本为每个GridView设置高度为0px,重量比为1:2以设置GridViews的高度关系。这也不会填充父母,如果其中一个视图的权重太小,则会进入滚动模式。 &#34; isScrollContainer&#34;属性并没有关闭它。

这是适配器中的getView()方法:

    // create a new ButtonView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
    Button btn;
    if ((convertView == null) || !initializing) { // if it's not recycled, initialize some
                                // attributes

        btn = new Button(mContext);
        KeypadButton keypadButton = mButtons[position];

        switch(keypadButton.mCategory)
        {
        case NUMBER:
            btn.setBackgroundResource(R.drawable.keypadnumber);
            break;
        case DECIMAL:
            btn.setBackgroundResource(R.drawable.keypadnumber);
            break;
        case CLEAR:
            btn.setBackgroundResource(R.drawable.keypadnumber);
            break;
        case WEIGHT:    
        case VOLUME:
            switch (unitState[position]) {
            case SELECTED:
                btn.setEnabled(true);
                btn.setBackgroundResource(R.drawable.keypad_measure_selected);
                btn.setTextColor(mContext.getResources().getColor(R.color.units_text_enabled));
                break;
            case ENABLED:
                btn.setEnabled(true);
                btn.setBackgroundResource(R.drawable.keypad_measure_not_selected);
                btn.setTextColor(mContext.getResources().getColor(R.color.units_text_enabled));
                break;
            case DISABLED:
                btn.setEnabled(false);
                btn.setBackgroundResource(R.drawable.keypad_measure_not_selected);
                btn.setTextColor(mContext.getResources().getColor(R.color.units_text_disabled));
                break;
            default:
                break;
            }
            break;
        case DUMMY:
            break;
        default:
            btn.setBackgroundResource(R.drawable.keypadnumber);
            break;
        }
        // Set OnClickListener of the button to mOnButtonClick
        if(keypadButton != KeypadButton.DUMMY)
            btn.setOnClickListener(mOnButtonClick);
        else
            btn.setClickable(false);
        // Set CalculatorButton enumeration as tag of the button so that we
        // will use this information from our main view to identify what to do
        btn.setTag(keypadButton);
    } else {
        btn = (Button) convertView;
    }

    btn.setText(mButtons[position].getText());
    return btn;
}

(不要担心unitState数组。它解决了另一个问题。)

即使视图正在被回收,按钮的高度(和宽度)也为零,设置它也没有效果。

在填充GridView之前,可以在布局参数中设置GridViews或按钮的高度或填充属性吗?

3 个答案:

答案 0 :(得分:0)

// Just replace your second GridView With This One
<GridView
        android:id="@+id/grdNumButtons"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:isScrollContainer="false"
        android:numColumns="3"
        android:scrollbars="none"
        android:stretchMode="columnWidth" />

答案 1 :(得分:0)

如果GridView未填充到父级,则必须在getView()方法中以编程方式计算设备高度。计算设备的高度后,将GridView的layoutParams设置为匹配父级或填充父级,它将解决您的问题。

答案 2 :(得分:0)

pratik提出的解决方案在正确的轨道上,但在适配器中设置GridViews的大小与在XML中使用GridViews上的“fill_parent”或加权高度没有什么不同。当然,GridViews设置为正确的高度,但按钮总是相同的大小。因此,如果GridView的按钮不够大,则GridView会滚动。没用键盘。

我怀疑,问题是按钮大小。我仍然不知道Android如何确定按钮高度,但它似乎是固定的 - 即,它不依赖于按钮宽度,按钮宽度经过适当调整以适合GridView宽度。我猜这是GridView中的一个错误。它似乎也是一个错误,你不能在GridView中关闭滚动。

无论如何,解决方案是针对每个GridView适配器中的getView()将按钮高度设置为使它们完全适合分配给GridView的高度的值。我实际上在发布之前尝试过,但使用了构造:

btn.setHeight(数);

而不是在按钮的布局参数中设置高度。这是因为我没有意识到在布局完成之后按钮高度才会被设置。另外,我没有考虑获得可用的屏幕高度,因此我可以计算与设备无关的高度。很抱歉不熟悉这些东西。

我花了很多时间尝试使用包含GridViews的LinearLayout的高度,这将减少我需要针对不同设备大小调整的常量数量。但是由于布局完成的时间和标签片段的实现方式的奇怪性,这变得非常混乱(是的,我尝试设置一个OnGlobalLayoutListener)。最重要的是,这种方法存在一些时间问题。结果是键盘区域将消失一两秒,并在片段被销毁并重新创建后被标记到视图中时重新绘制。它可能已经完成,但我没有时间弄明白。

无论如何,这里是代码的相关补充。首先,我在MainActivity中添加了以下方法:

    // Method to get the usable screen height and width, which will then be available through their getters and setters

private void setUsableScreenDimensions() {
    DisplayMetrics dm = getResources().getDisplayMetrics();
    float screen_w = dm.widthPixels;
    float screen_h = dm.heightPixels;

    int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resId > 0) {
        screen_h -= getResources().getDimensionPixelSize(resId);
    }
    TypedValue typedValue = new TypedValue();
    if(getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)){
        screen_h -= getResources().getDimensionPixelSize(typedValue.resourceId);
    }       
    screenWidth = (double) screen_w;
    screenHeight = (double) screen_h;
}

然后我将此代码添加到适配器构造函数:

    double keypadParentHeight = (MainActivity.getScreenHeight() * Constants.KEYPAD_PARENT_HEIGHT_PERCENTAGE);
    double rowHeight = keypadParentHeight / Constants.NUMBER_OF_KEYPAD_ROWS;        
    buttonHeight = (int) (rowHeight * Constants.BUTTON_HEIGHT_FACTOR);

最后,getView中的按钮高度因此设置:

LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, buttonHeight);
LayoutParams params = params;

实际代码稍微复杂一些,因为有两组具有不同权重(1:2)的键(两个GridView),因此按钮大小不同。此外,相同的键盘由三个不同的片段绘制,具有不同大小的父级LinearLayouts。但是这一切都归结为适配器中的一些额外常量和一些条件语句。