我有一个ListView
,我添加了一个页脚。我试图以编程方式获取包括页脚在内的整个ListView
的高度,为此,我编写了下面发布的代码。
我现在遇到的问题是,当我运行代码时 在API级别大于18的任何设备上,代码工作正常。但如果设备的API级别为18或更低,应用程序崩溃,我收到以下发布的logcat错误。
经过调查和调试后,我发现,当我处理API级别等于18或更低的设备时,如果代码部分中的for循环标题为" {{1},则会发生错误。 }}"到达列表中的最后一个页脚。因此,我决定将相同的代码分成两部分。第一部分包含一个for循环,循环遍历列表中除页脚之外的所有项目,然后我添加了一个代码,该代码仅计算页脚高度 一个想法是页脚的高度有多大。所以代码如下:
calcLisVieHeight
当我运行上面的代码而没有负责计算页脚高度的代码时,App工作正常但是当我激活包含页脚高度的代码时它会崩溃生成下面的logcat消息
请让我知道为什么不能计算页脚的高度以及如何正确计算
calcLisVieHeight :
int desiredWidth = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int desiredHeight = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
for (int i = 0; i < listView.getCount() - 1; i++) {
View childView = listView.getAdapter().getView(i, null, listView);
if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
childView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
}
childView.measure(desiredWidth, desiredHeight);
height += childView.getMeasuredHeight();
Log.v(TAG, "height: " + height);
}
////////////////////calc footer height////////////////////////
View childView = listView.getAdapter().getView(listView.getCount() - 1, null, listView);
int heightFooter = 0;
if (android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2) {
childView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
}
childView.measure(desiredWidth, desiredHeight);
height += childView.getMeasuredHeight();
heightFooter = childView.getMeasuredHeight();
Log.v(TAG, "height: " + height);
Log.v(TAG, "heightFooter: " + heightFooter);
//dividers height
height += listView.getDividerHeight() * listView.getCount() + childView.getHeight();
logcat的:
switch (viewId) {
case R.id.versicherungsListeActivity2mod_lisVie_versDetails:
heightInPix = this.mLayoutDimsCtrl.calcLisVieHeight(listView);
if (heightInPix != -1) {
RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, heightInPix);
param.addRule(RelativeLayout.BELOW, ruleSubject);
container.setLayoutParams(param);
listView.requestLayout();
}
break;
...
...
...
public int calcLisVieHeight(final ListView listView) {
......
......
int desiredWidth = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int desiredHeight = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
for (int i = 0; i < listView.getCount(); i++) {
View childView = listView.getAdapter().getView(i, null, listView);
if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
childView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
}
childView.measure(desiredWidth, desiredHeight);
height += childView.getMeasuredHeight();
Log.v(TAG, "height: " + height);
}
//dividers height
height += listView.getDividerHeight() * listView.getCount() + childView.getHeight();
......
......
}
答案 0 :(得分:0)
使用此类作为CustomListView来实现您的目的。希望它对你有用。
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;
public class MyListView extends ListView {
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightSpec;
if (getLayoutParams().height == LayoutParams.WRAP_CONTENT) {
// The great Android "hackatlon", the love, the magic.
// The two leftmost bits in the height measure spec have
// a special meaning, hence we can't use them to describe height.
heightSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
} else {
// Any other height should be respected as is.
heightSpec = heightMeasureSpec;
}
super.onMeasure(widthMeasureSpec, heightSpec);
}
}
`
答案 1 :(得分:0)
也许我错了,但恕我直言,阅读你的代码,你应该做到以下几点:
在for loop
内以及应用中的任何位置,您必须访问footer
(列表中的最后一项index = length -1
),然后检查api lvl
。
if(currentIndex == footerIndex && currentApiLVL <= 18) //obv replace with the correct code, I don't have a compiler atm
{
myFooterView.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.WRAP_CONTENT, AbsListView.LayoutParams.WRAP_CONTENT));
} else {
myFooterView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
}
所以,如果项目是页脚(最后一项),则必须检查第一个 ;如果版本是,则必须 &lt; = 18 。在这种情况下,并且仅在这种情况下(两个条件)你必须将params设置为AbsListView
而不是RelativeLayout
。
也许没有,但我希望这可以帮到你。请尝试我的代码并告诉我这是否有帮助:)