兑现我的承诺,开始了Android的学习,实现的demo目的很明确,就是对listview里面的内容点赞,然后赞的数目改变。
我先说一下将会解决的问题,没准你也遇到了
- Listview在Scrollview中无法显示完全
- 子view中的button等劫持了listview中item的clickListener
- OnClickListener接口的onClick方法中的View view参数究竟是什么
- 点赞后计数改变
每个问题都是常见问题,但是我想好好说说,所以分了三篇博客,各说一个问题。
先说Listview在Scrollview中无法显示完全。
为什么listview显示不全,因为在Scrollview在measure时计算不出Listview的大小,所以只能显示一行。
View,也就是我们的具体每一个图案,View在绘图时首先measure之后layout最后draw,简单说就是先计算大小,之后计算布局,最后就是绘画了。我们这部分涉及的是measure。View 的measure是从root开始一级一级计算自己的child,listview在Scrollview中就是他的子view。
这个问题无论是从哪里出发,解决问题的关键点都是得到ListView的高度。然后Scrollview在调用子view的measure方法就可以得到具体高度
这个问题网上很多解释,最多的是openstack中的一位大神的解释,我看过很多demo都是这种解决方式。写个工具类,然后再listview.set(adapter)之后写上Utility.setListViewHeightBasedOnChildren(listview)
public class Utility {
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = 0;
for (int i = 0, len = listAdapter.getCount(); i < len; i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
这个方法确实可以解决一部分人的问题,但是有博客说,针对中文可能会有bug,于是上面的方法需要改写一下
public static void setListViewHeightBasedOnChildrenNew(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = 0;
for (int i = 0, len = listAdapter.getCount(); i < len; i++) {
View listItem = listAdapter.getView(i, null, listView);
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(), View.MeasureSpec.AT_MOST);
listItem.measure(desiredWidth, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
可以发现主要改动的是measure方法的参数,能够显示完全了,但是还是有bug,就是感觉Scrollview滑到没有物体地方了。
所以继续查,第三种方法是写mylistview继承Listview,重写onMeasure方法。
public class MyListView extends ListView
{
public ScrollViewWithListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public