android 关于listview item设置高度的问题解决方法

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

关于listview,做andriod开发都必须知道的,我写了一个简单的adapter,在这不考虑什么缓存机制就单单为了显示一下而已:

public class MainActivity extends Activity {
    private static final String TAG = "MainActivity" ;
    private ListView listview;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_main);
        listview = (ListView) findViewById(R.id.listview);
        listview.setAdapter(new MyAdapter());
    }
    class MyAdapter extends BaseAdapter{
        @Override
        public int getCount() {
            return 20;
        }
        @Override
        public Object getItem(int position) {
            return null;
        }
        @Override
        public long getItemId(int position) {
            return 0;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            return View.inflate(MainActivity.this,R.layout.item,null);
        }
    }
}
效果图:


如果想设置item的高度为某一个特定的值 比如为200dp,也许你会说很简单,这么做就搞定

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="300dp">
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="今天天气真好"
        android:layout_marginTop="10dp"
        android:textColor="#ff00ff"
        android:gravity="center"
        />
</LinearLayout>

但是很遗憾告诉你这样是不行的,原因在哪?

我们都知道在xml中带layout_xxx这样的最后都会封装成LayoutParam 这个是父view决定给子view的宽度和高度,我们到ListView的源码中

private View makeAndAddView(int position, int y, boolean flow, int childrenLeft,
        boolean selected) {
    View child;


    if (!mDataChanged) {
        // Try to use an existing view for this position
        child = mRecycler.getActiveView(position);
        if (child != null) {
            // Found it -- we're using an existing child
            // This just needs to be positioned
            setupChild(child, position, y, flow, childrenLeft, selected, true);

            return child;
        }
    }

    // Make a new view for this position, or convert an unused view if possible
    child = obtainView(position, mIsScrap);

    // This needs to be positioned and measured
    setupChild(child, position, y, flow, childrenLeft, selected, mIsScrap[0]);

    return child;
}
这是listview 添加和计算每个item的方法 在AbsListView中有个obtainView()方法,

View obtainView(int position, boolean[] isScrap) {
    Trace.traceBegin(Trace.TRACE_TAG_VIEW, "obtainView");

    isScrap[0] = false;

    // Check whether we have a transient state view. Attempt to re-bind the
    // data and discard the view if we fail.
    final View transientView = mRecycler.getTransientStateView(position);
    if (transientView != null) {
        final LayoutParams params = (LayoutParams) transientView.getLayoutParams();

        // If the view type hasn't changed, attempt to re-bind the data.
        if (params.viewType == mAdapter.getItemViewType(position)) {
            final View updatedView = mAdapter.getView(position, transientView, this);

            // If we failed to re-bind the data, scrap the obtained view.
            if (updatedView != transientView) {
                setItemViewLayoutParams(updatedView, position);
                mRecycler.addScrapView(updatedView, position);
            }
        }

        isScrap[0] = true;

        // Finish the temporary detach started in addScrapView().
        transientView.dispatchFinishTemporaryDetach();
        return transientView;
    }

    final View scrapView = mRecycler.getScrapView(position);
    final View child = mAdapter.getView(position, scrapView, this);
    if (scrapView != null) {
        if (child != scrapView) {
            // Failed to re-bind the data, return scrap to the heap.
            mRecycler.addScrapView(scrapView, position);
        } else {
            isScrap[0] = true;

            // Finish the temporary detach started in addScrapView().
            child.dispatchFinishTemporaryDetach();
        }
    }

    if (mCacheColorHint != 0) {
        child.setDrawingCacheBackgroundColor(mCacheColorHint);
    }

    if (child.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
        child.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
    }

    setItemViewLayoutParams(child, position);

    if (AccessibilityManager.getInstance(mContext).isEnabled()) {
        if (mAccessibilityDelegate == null) {
            mAccessibilityDelegate = new ListItemAccessibilityDelegate();
        }
        if (child.getAccessibilityDelegate() == null) {
            child.setAccessibilityDelegate(mAccessibilityDelegate);
        }
    }

    Trace.traceEnd(Trace.TRACE_TAG_VIEW);

    return child;
}
查看这个方法
setItemViewLayoutParams(child, position);

这个方法的源码:

private void setItemViewLayoutParams(View child, int position) {
    final ViewGroup.LayoutParams vlp = child.getLayoutParams();
    LayoutParams lp;
    if (vlp == null) {
        lp = (LayoutParams) generateDefaultLayoutParams();
    } else if (!checkLayoutParams(vlp)) {
        lp = (LayoutParams) generateLayoutParams(vlp);
    } else {
        lp = (LayoutParams) vlp;
    }

    if (mAdapterHasStableIds) {
        lp.itemId = mAdapter.getItemId(position);
    }
    lp.viewType = mAdapter.getItemViewType(position);
    if (lp != vlp) {
      child.setLayoutParams(lp);
    }
}
主要的逻辑在这几行代码

if (vlp == null) {
    lp = (LayoutParams) generateDefaultLayoutParams();
} else if (!checkLayoutParams(vlp)) {
    lp = (LayoutParams) generateLayoutParams(vlp);
} else {
    lp = (LayoutParams) vlp;
}
第一个if是判断这个params是否等于null,等于null的话就给它一个默认的,默认的是这个

@Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
    return new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.WRAP_CONTENT, 0);
}
接着上面的分析 第二个if判断

!checkLayoutParams(vlp)
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
    return p instanceof AbsListView.LayoutParams;
}
查看这个是不是
AbsListView.LayoutParams类型的 很显然我们没有对它做任何的事  显然不是这个类型的,那么系统会给他创建一个
@Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
    return new LayoutParams(p);
}

这就是为什么我们在xml中设置高度无效的原因,因为它在底层已经给我们设置了,你在外面设置导致无效


解决这个问题有二种办法:

1:在xml外层套一层布局,

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >
<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="300dp">
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="今天天气真好"
        android:layout_marginTop="10dp"
        android:textColor="#ff00ff"
        android:gravity="center"
        />
</LinearLayout>
</LinearLayout>
效果图:


2:

在adapter中的getView()方法中添加这个

@Override
public View getView(int position, View convertView, ViewGroup parent) {
   View view =  View.inflate(MainActivity.this,R.layout.item,null);
    AbsListView.LayoutParams param = new AbsListView.LayoutParams(300,200);
    view.setLayoutParams(param);
    return view;
}

搞定,OK



Android 宽高相等的adapter item内容 使用一张网上的图: 很多时候,我们需要用使用这样的排列,宽高固定,然后是中间留有一定的边距,毫无疑问,这里我们需要用到gridadapter。 GridView的item是正方形,而android需要适配不同尺寸的手机,所以不能写死item高度和宽度。因为GridView是可以根据numColumns来分配item的宽度的,所以我们把item布局的高度设为与宽度一样就能实现适配了。 (一):所... 阅读详情

相关推荐

Android ListView和GridView设置Item高度

Android开发中,ListView和GridView是常用的UI控件,它们可以用来展示大量数据,并提供了灵活的布局方式。祝你在Android开发中取得成功!ListViewItem高度可以通过设置Item布局文件的高度来实现。综上所述,我们可以通过设置布局文件的高度设置GridView的列数等方式来调整ListView和GridView的Item高度。在这个示例中,我们将LinearLayout的layout_height属性设置为100dp,即可实现ListViewItem高度为100dp。

2301_79326891的博客 845

Android ListView 获取高度

public void getTotalHeightofListView(ListView listView) { ListAdapter mAdapter = (ListAdapter) listView.getAdapter(); if (mAdapter == null) { return; } int totalHeight = 0;

LiLi_ko的专栏 876

android listview和gridview设置item高度

有时候listview和gridview的Item有时候高度和宽度设置无效,那么怎么设置才有效呢 ,我采用的是下面这种方法,在适配器里面设置代码如下: @Override public View getView(int position, View convertView, ViewGroup parent) { if(position != last_p...

安卓兼职framework和app工程师的博客 680

ListView设置Item高度的几种方法

方案一:item中加图片撑大 方案二:设置字体大小或者在固定字体大小的情况下,设置padding 方案一和方案二都是通过设置内容,来使listview自适应,改变item高度 方案三:动态设置,在adapter中getview中 convertView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, m

huxing32的专栏 2201

android 关于如何设置ListViewitem高度问题解决方法

有的时候,我们在设置ListView中的item高度时,直接设置xml中的height并不能确定显示的效果确实是设置的数据,通常是在有背景图片的情况下。网上一大堆雷同帖子和(转载)文章,多数是设置item的xml中parent 的minHeight属性: 亲测了一下,有的有效而有的没有效果; 那么不妨试试这种方式: item的UI包括在两个ViewGroup内,第一

苏蔡的专栏 1009

androidlistviewitem设定高度

item的layout文件中,用android:layout_height设置item高度。 运行,高度设置无效。 解决办法: 给item设定minHeight,即可. --------------------------------------- 最近一直纠结于ListView中每个Item高度问题,在网上只找出一个方法,就是在每个item里面加入图片,也就是I

Working harder, getting stronger! 6万+

设置listitem中每个item高度

item的layout文件中,用android:layout_height设置item高度。 运行,高度设置无效。 解决办法: 给item设定minHeight,即可. --------------------------------------- 最近一直纠结于ListView中每个Item高度问题,在网上只找出一个方法,就是在每个item里面加入图

xxjvip的专栏 1413

1.android listView的每一个item布局高度不一样,自动计算listView高度

一、android listView的每一个item布局高度不一样 1.获取listView的宽度 2.给item的measure设置参数是listView的宽度就可以获取到真正每一个item高度 public void setListViewHeightBasedOnChildren(ListView listView1) {         BaseAdapter listAdap...

mengtianqq的博客 3954

如何设置listview每个item高度

据我所了解,listview每行的宽度是由 inflater填充布局中高度最大的那个控件的高度。。。     public  void setListViewHeightBasedOnChildren(ListView listView)         {                //获取ListView对应的Adapter                ListAdapter li...

weixin_34224941的博客 591

代码设置ListviewItem高度

ListViewItem高度问题 代码设置Adapter的Item高度: 方案一: 在xml里面多嵌套一次布局 &lt;android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_pa...

songzi1228的博客 1246

android中scrollview中嵌入listview 产生的滚动问题

android中使用ScrollView内嵌ListView共存会存在滚动的问题,并且ListView只显示一个半Item。 当ListView高度设定一定的值时,ListView同样地会显示对应的高度Item。 因此我们可以计算出这个ListView的总高度,再将它设置ListView中,这样就解决了之前的问题。 代码如下: public void setLis

记录 703

开发中listViewitem宽高没法设置问题

Android开发中,如果你在填充listView的时候,item高度不是按照你设定的高度来设定的,你看看是不是item最外层布局的宽高你用具体的dp来设定了,如我的这个 xml version="1.0" encoding="utf-8"?> xmlns:android="http://schemas.android.com/apk/res/android" android:l

mijiaxiaojiu的博客 872
上一篇: 数组中添加数据后并排序显示出来
下一篇: java 基础 泛型使用总结
zhoushenxian
博客等级 码龄12年 453粉丝 549原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值