You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Android的adView始终显示在ListView最后一项下方?

问题解答

当前布局能否实现需求?

不能。当前activity_results里的ListView和adView被放在独立的ConstraintLayout中,而这个ConstraintLayout与ViewPager同级且都设置了match_parent高度,会直接覆盖ViewPager;而content_results是ViewPager对应页面的列表项布局,两者完全没有关联,自然无法让adView跟随ListView最后一项的底部。

你尝试的app:layout_constraintBottom_toTopOf无效,是因为ListView高度设为wrap_content,且整体布局层级错误,约束没有在正确的上下文生效。

布局中的基础错误

  • 冗余嵌套:最外层的RelativeLayout完全多余,内部直接是CoordinatorLayout,没有用到任何RelativeLayout的属性,徒增布局层级。
  • 布局重叠:ViewPager和ConstraintLayout都设置了match_parent高度,且都添加了app:layout_behavior="@string/appbar_scrolling_view_behavior",导致两者重叠,ConstraintLayout会覆盖ViewPager,使得ViewPager的页面无法正常显示。
  • 属性混用无效:adView中使用了android:layout_alignParentBottom="true"(这是RelativeLayout的属性),但它的父布局是ConstraintLayout,该属性完全无效。
  • 属性不规范:content_results.xml中使用的fill_parent可替换为match_parent,fill_parent是旧API写法,match_parent更符合当前Android开发规范。

正确实现adView跟随ListView最后一项底部的方法

推荐两种可行方案:

方案1:将adView作为ListView的最后一项(推荐)

在ListView的Adapter中,把广告项作为列表的最后一条数据:

  1. 创建广告项布局(比如item_ad.xml),内容就是AdView。
  2. 在Adapter的getCount()方法中,返回原数据数量+1。
  3. 在getView()方法中,判断当前position是否为最后一项,若是则加载广告布局,否则加载正常的content_results布局。

示例Adapter核心代码(ListView版本):

@Override
public int getCount() {
    return originalData.size() + 1; // 原数据数量+1条广告
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (position == originalData.size()) {
        // 加载广告布局
        if (convertView == null) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_ad, parent, false);
            AdView adView = convertView.findViewById(R.id.adView);
            // 初始化广告加载
            AdRequest adRequest = new AdRequest.Builder().build();
            adView.loadAd(adRequest);
        }
        return convertView;
    } else {
        // 加载正常列表项布局
        if (convertView == null || !(convertView.getTag() instanceof NormalViewHolder)) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_results, parent, false);
            NormalViewHolder holder = new NormalViewHolder(convertView);
            convertView.setTag(holder);
        }
        NormalViewHolder holder = (NormalViewHolder) convertView.getTag();
        // 绑定数据
        YourData data = originalData.get(position);
        holder.abc.setText(data.getAbc());
        holder.def.setText(data.getDef());
        holder.ghi.setText(data.getGhi());
        return convertView;
    }
}

static class NormalViewHolder {
    TextView abc;
    TextView def;
    TextView ghi;

    NormalViewHolder(View itemView) {
        abc = itemView.findViewById(R.id.abc);
        def = itemView.findViewById(R.id.def);
        ghi = itemView.findViewById(R.id.ghi);
    }
}

方案2:用LinearLayout包裹ListView和adView(适合数据量少的场景)

如果ListView数据量不大,可将两者放在垂直方向的LinearLayout中,给ListView设置android:layout_weight="1"让其占满剩余空间,adView固定在底部:

<!-- 此布局放在ViewPager对应的Fragment中 -->
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

    <com.google.android.gms.ads.AdView
        android:id="@+id/adView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        ads:adSize="SMART_BANNER"
        ads:adUnitId="@string/banner_ad_unit_id"/>
</LinearLayout>

注意:这种方式下,滚动ListView时adView会固定在屏幕底部,而非跟随最后一项下方被带出屏幕;如果需要adView在列表最后一项的下方,方案1更合适。

修正后的activity_results布局

去掉冗余的RelativeLayout和错误的ConstraintLayout,保留正确的CoordinatorLayout结构:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.test.test.ResultsActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay"
            app:titleTextAppearance="@style/ToolbarTitle" />

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabMaxWidth="0dp">

            <com.google.android.material.tabs.TabItem
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/tab_text_1" />

            <com.google.android.material.tabs.TabItem
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/tab_text_2" />
        </com.google.android.material.tabs.TabLayout>

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

内容的提问来源于stack exchange,提问作者Zac1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 04:55:33