android.widget.AbsListView子类实战套路

java.lang.Object
↳ android.view.View
↳ android.view.ViewGroup
↳ android.widget.AdapterView

需求一:动态设置ListView和GridView高度

场景1:有时我们不想写一个固定高度让其滚动,而想根据子项的数目自动适配控件的高度。
场景2:两个滚动控件互相嵌套。由于嵌套后计算listview的高度出现问题导致的。比如在ScrollView中嵌套ListView空间,无法正确的计算ListView的大小,所以你们就只看到一行。
- 算法分析
- ListView
要计算ListView的高度,很简单啊。首先,得知道有多少条数据,循环计算每一条item的高度,把他们相加就得出了总的高度。

```
//为listview动态设置高度(有多少条目就显示多少条目) 
public void setListViewHeight(ListView listView) { 
    //获取listView的adapter  
    ListAdapter listAdapter = listView.getAdapter();  
    if (listAdapter == null) {  
        return;  
    } 
    int totalHeight = 0;  
    //listAdapter.getCount()返回数据项的数目  
    for (int i = 0,len = listAdapter.getCount(); i < len; i++) {  
        View listItem = listAdapter.getView(i, null, listView); 
        listItem.measure(0, 0);  
        totalHeight += listItem.getMeasuredHeight();  
    }  
    // listView.getDividerHeight()获取子项间分隔符占用的高度 
    // params.height最后得到整个ListView完整显示需要的高度  
    ViewGroup.LayoutParams params = listView.getLayoutParams();  
    params.height = totalHeight + (listView.getDividerHeight() *  (listAdapter .getCount() - 1));  
    listView.setLayoutParams(params); 
}
//使用方式,必须刷新Adapter
setListViewHeight(listView); 
listViewAdapter.notifyDataSetChanged();
```

- GridView
要计算GridView的高度,方法类似,只不过要考虑到列数。比如有12条数据,设置为5列,那么就有三行数据。只要我们得到每一行的高度,然后再相加,就是我们想要的结果。 

```
public void setGridViewHeight(GridView gridview) {  
    // 获取gridview的adapter  
    ListAdapter listAdapter = gridview.getAdapter();  
    if (listAdapter == null) {  
        return;  
    }  
    // 固定列宽,有多少列  
    int numColumns= gridview.getNumColumns(); //5  
    int totalHeight = 0;  
    // 计算每一列的高度之和 
    for (int i = 0; i < listAdapter.getCount(); i += numColumns) {  
        // 获取gridview的每一个item  
        View listItem = listAdapter.getView(i, null, gridview); 
        listItem.measure(0, 0);  
        // 获取item的高度和  
        totalHeight += listItem.getMeasuredHeight();  
    }   
    // 获取gridview的布局参数  
    ViewGroup.LayoutParams params = listView.getLayoutParams();  
    params.height = totalHeight;  
    gridview.setLayoutParams(params);  
}
//使用方式,必须刷新Adapter
setGridViewHeight(gridView); 
gridViewAdapter.notifyDataSetChanged();
```
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.hjschoolhelper210301201_1, PID: 13135 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference at com.example.hjschoolhelper210301201_1.ClubinfoAdpter.getView(ClubinfoAdpter.java:44) at android.widget.AbsListView.obtainView(AbsListView.java:2458) at android.widget.ListView.makeAndAddView(ListView.java:2067) at android.widget.ListView.fillDown(ListView.java:793) at android.widget.ListView.fillFromTop(ListView.java:855) at android.widget.ListView.layoutChildren(ListView.java:1838) at android.widget.AbsListView.onLayout(AbsListView.java:2255) at android.view.View.layout(View.java:23693) at android.view.ViewGroup.layout(ViewGroup.java:6413) at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1855) at android.view.View.layout(View.java:23693) at android.view.ViewGroup.layout(ViewGroup.java:6413) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at android.view.View.layout(View.java:23693) at android.view.ViewGroup.layout(ViewGroup.java:6413) at androidx.appcompat.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:536) at android.view.View.layout(View.java:23693) at android.view.ViewGroup.layout(ViewGroup.java:6413) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at android.view.View.layout(View.java:23693) at android.view.ViewGroup.layout(ViewGroup.java:6413) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1891) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1729) at android.widget.LinearLayout.onLayout(LinearLayout.java:1638) at android.view.View.layout(View.java:23693) at android.view.ViewGroup.layout(ViewGroup.java:6413) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at com.android.internal.policy.DecorView.onLayout(DecorView.java:799) at android.view.View.layout(View.java:23693) at android.view.ViewGroup.layout(ViewGroup.java:6413) at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:3999) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3372) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2328) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9087) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1231) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239) at android.view.Choreographer.doCallbacks(Choreographer.java:899) at android.view.Choreographer.doFrame(Choreographer.java:832) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214) at android.os.Handler.handleCallback(Handler.java:942) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7872) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
05-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值