3

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

GridViews 的高度似乎是固定的,无法更改。如果 GridView 有足够的空间,它们不会填充父级。如果没有足够的空间,它们会进入滚动模式——并且滚动模式不能被关闭。

我不确定,但 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 的权重比来设置 GridView 的高度关系。这也不会填充父级,如果其中一个视图的权重太小,它就会进入滚动模式。“isScrollContainer”属性不会关闭它。

这是来自适配器的 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 或按钮的高度或填充属性是否可以在填充 GridView 之前在 Layout 参数中设置?

4

3 回答 3

0

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

于 2013-09-10T07:26:25.510 回答
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" />
于 2013-09-10T07:11:21.587 回答
0

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

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

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

btn.setHeight(数字);

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

我花了很多时间尝试使用包含 GridView 的 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的不同片段上绘制的。但这一切都归结为适配器中的一些额外常量和一些条件语句。

于 2013-09-11T05:33:59.250 回答