我有一对垂直排列的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或按钮的高度或填充属性吗?
答案 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。但是这一切都归结为适配器中的一些额外常量和一些条件语句。