jjzjj

android - NativeAdsExpress 强制 RecyclerView 滚动以使 NativeAd 在首次加载时完全可见

coder 2023-11-29 原文

我有一个奇怪的“问题”,或者它可能是一个“功能”,我只是不知道,每当 NativeAdExpress 加载到我的 RecyclerView 中时,如果只有部分 NativeAd 可见,它会强制 RecyclerView 滚动直到原生广告变得完全可见,此行为会导致列表在我滚动时不断跳跃。

我的布局主要是:

Activity > AppBar with Tabs and ViewPager > Pager 中的每个 Page 都包含 PullToRefresh 并且在其中有一个 RecyclerView, RecyclerView 有两种类型的项目(Article 和 NativeAdExpress)。

更新:我对发生这种情况的原因的猜测主要是因为原生广告在 webview 中呈现,并且此 webview 获得焦点然后这导致 RecyclerView 滚动到它,但这只是一个猜测

更新 2:显然这是支持库中的一个问题。 24.0.0,这就是过于更新的代价:(

这是我的完整 XML/布局

<?xml version="1.0" encoding="utf-8"?>
<my.package.custom.views.CustomDrawerLayout
    android:id="@+id/drawer_layout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    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"
    android:fitsSystemWindows="true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:openDrawer="end">

    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        style="@style/AlertDialog.AppCompat.Light"
        fontPath="fonts/fonts/DroidKufi-Regular.ttf"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:fitsSystemWindows="true"
        app:elevation="5px"
        app:headerLayout="@layout/nav_header"
        app:itemIconTint="@color/colorPrimary"
        app:itemTextColor="@color/contentColor"
        app:actionLayout="@layout/nav_item_layout"
        app:menu="@menu/drawer_menu"
        app:theme="@style/NavDrawerStyle"
        tools:openDrawer="end"
        />

</my.package.custom.views.CustomDrawerLayout>

其中“app_bar_main.xml”如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    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"
    android:fitsSystemWindows="true"
    tools:context=".ui.activities.ArticlesListActivity">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="end">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="52dp"
            android:background="?attr/colorPrimary"
            android:gravity="end"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center_vertical"
                android:orientation="horizontal"
                android:paddingEnd="14dp"
                android:paddingStart="14dp">

                <android.support.v7.widget.AppCompatImageButton
                    android:id="@+id/ivCustomDrawable"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentEnd="true"
                    android:layout_alignParentRight="true"
                    android:layout_centerVertical="true"
                    android:background="@color/transparent"
                    android:tint="@color/white"
                    />

                <TextView
                    android:id="@+id/view_title"
                    android:visibility="gone"
                    style="@style/SectionTitle"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    />

                <android.support.v7.widget.AppCompatSpinner
                    android:id="@+id/sources_spinner"
                    android:gravity="center"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentLeft="true"
                    android:transitionName="@string/transition_splash_logo"
                    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                    tools:targetApi="lollipop"/>
            </RelativeLayout>

        </android.support.v7.widget.Toolbar>

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            style="@style/TabsStyle"
            android:layout_width="match_parent"
            android:layout_height="42dp"
            android:layout_gravity="bottom"
            android:layout_marginTop="0dp"
            android:transitionGroup="true"
            app:tabContentStart="0dp"
            app:tabGravity="fill"
            app:tabIndicatorColor="@color/white"
            app:tabIndicatorHeight="3dp"
            app:tabMode="scrollable"
            app:tabPaddingBottom="0dp"
            app:tabPaddingTop="0dp"
            app:tabTextAppearance="@style/TextAppearance.RegularTextFont"
            />

    </android.support.design.widget.AppBarLayout>

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            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"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            tools:context=".ui.activities.ArticlesListActivity"
            tools:showIn="@layout/activity_newsitem_list">

       <android.support.v4.view.ViewPager
         android:id="@+id/viewpager"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
        />
    </RelativeLayout>
</android.support.design.widget.CoordinatorLayout>

最后我有 2 个 View 类型 Item 和 NativeAdExpress:

NativeAdExpress ViewHolder 如下:

public class NativeExpressAdViewHolder extends BaseCardAdViewHolder {
    private final NativeExpressAdView view;
    private boolean loaded = false;
    private AdListener adListener;
    private WeakReference<Context> context;

    public NativeExpressAdViewHolder(View itemView, String adId, Context context) {
        super(itemView);
        view = new NativeExpressAdView(context);
        view.setAdUnitId(adId);
        ((LinearLayout) itemView.findViewById(R.id.express_ad_holder)).addView(view);
        this.context = new WeakReference<>(context);
    }

    public void loadAd(float cardWidthInDips) {
        if (!loaded && null != context.get() && !view.isLoading()) {
            int width = cardWidthInDips > 0 ? (int) cardWidthInDips : 330;
            if (view.getAdSize() == null) {
                view.setAdSize(new AdSize(width, 330));
                view.setAdListener(new AdListener() {
                    @Override
                    public void onAdLoaded() {
                        super.onAdLoaded();
                        loaded = true;
                        if (adListener != null) {
                            adListener.onAdLoaded();
                        }
                    }

                    @Override
                    public void onAdFailedToLoad(int i) {
                        super.onAdFailedToLoad(i);
                        if (adListener != null) {
                            adListener.onAdFailedToLoad(i);
                        }
                    }

                    @Override
                    public void onAdOpened() {
                        super.onAdOpened();
                        if (adListener != null) {
                            adListener.onAdOpened();
                        }
                    }
                });
            }
            new Handler(context.get().getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    view.loadAd(new AdRequest.Builder().build());
                }
            });
        }
    }

    public NativeExpressAdView getView() {
        return view;
    }

    public void setAdListener(AdListener adListener) {
        this.adListener = adListener;
    }

    @Override
    public void destroyAd() {
        if (view != null) {
            view.destroy();
            loaded = false;
        }
    }
}

广告是使用自定义适配器创建的,如下所示:

private BaseCardViewHolder createNativeExpressAdViewHolder(ViewGroup parent) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.ad_express, parent, false);
        final NativeExpressAdViewHolder viewHolder = new NativeExpressAdViewHolder(
            view,
            adManager.getNativeExpressAdId(),
            context.get()
        );
        adViewHolders.add(viewHolder);
        viewHolder.setAdListener(new AdListener() {
            @Override
            public void onAdFailedToLoad(int errorCode) {
                Log.i("ADS", "onAdFailedToLoad " + errorCode);
            }

            @Override
            public void onAdLoaded() {
                super.onAdLoaded();
                // Do something
            }
        });
        viewHolder.loadAd(cardWidthInDips);

        return viewHolder;
    }

最佳答案

我不明白您在代码中实际实现了 RecyclerView 的位置,但无论如何这里可能有适合您的情况。

我有一个类似的问题,GridView 总是在 Fragment 第一次加载期间获得焦点,它还会自动向下直接滚动到 GridView.

经过大量测试,我终于在 GridView 的父布局上用这一行停止了这种行为:

android:descendantFocusability="blocksDescendants"

这一行基本上意味着父布局的所有后代将不再获得焦点。您可以在 RecyclerView 父布局上尝试一下。

关于android - NativeAdsExpress 强制 RecyclerView 滚动以使 NativeAd 在首次加载时完全可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37909408/

有关android - NativeAdsExpress 强制 RecyclerView 滚动以使 NativeAd 在首次加载时完全可见的更多相关文章

  1. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  2. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  3. ruby - 即时确定方法的可见性 - 2

    我正在编写一个方法,它将在一个类中定义一个实例方法;类似于attr_accessor:classFoocustom_method(:foo)end我通过将custom_method函数添加到Module模块并使用define_method定义方法来实现它,效果很好。但我无法弄清楚如何考虑类(class)的可见性属性。例如,在下面的类中classFoocustom_method(:foo)privatecustom_method(:bar)end第一个生成的方法(foo)必须是公共(public)的,第二个(bar)必须是私有(private)的。我怎么做?或者,如何找到调用我的cust

  4. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  5. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  6. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  7. ruby - 如何以编程方式删除实例上的 "singleton information"以使其编码(marshal)? - 2

    我创建了一个由于“在运行时执行的单例元类定义”而无法编码的对象(这段代码的描述是否正确?)。这是通过以下代码执行的:#defineclassXthatmyusesingletonclassmetaprogrammingfeatures#throughcallofmethod:break_marshalling!classXdefbreak_marshalling!meta_class=class我该怎么做才能使对象编码正确?是否可以从对象instance_of_x的classX中“移除”单例组件?我真的需要一个建议,因为我们的一些对象需要通过Marshal.dump序列化机制进行缓存。

  8. ruby - 强制浏览器下载文件而不是打开文件 - 2

    我要下载http://foobar.com/song.mp3作为song.mp3,而不是让Chrome在其native中打开它浏览器中的播放器。我怎样才能做到这一点? 最佳答案 您只需要确保发送这些header:Content-Disposition:attachment;filename=song.mp3;Content-Type:application/octet-streamContent-Transfer-Encoding:binarysend_file方法为您完成:get'/:file'do|file|file=File.

  9. ruby-on-rails - 使用 gmaps4rails 动态加载谷歌地图标记 - 2

    如何只加载map边界内的标记gmaps4rails?当然,在平移和/或缩放后加载新的。与此直接相关的是,如何获取map的当前边界和缩放级别? 最佳答案 我是这样做的,我只在用户完成平移或缩放后替换标记,如果您需要不同的行为,请使用不同的事件监听器:在你看来(index.html.erb):{"zoom"=>15,"auto_adjust"=>false,"detect_location"=>true,"center_on_user"=>true}},false,true)%>在View的底部添加:functiongmaps4rail

  10. ruby-on-rails - 是否可以让 ActiveRecord 为使用 :joins option? 加载的行创建对象 - 2

    我需要做这样的事情classUser'User',:foreign_key=>'abuser_id'belongs_to:gameendclassGame['JOINabuse_reportsONusers.id=abuse_reports.abuser_id','JOINgamesONgames.id=abuse_reports.game_id'],:group=>'users.id',:select=>'users.*,count(distinctgames.id)ASgame_count,count(abuse_reports.id)asabuse_report_count',:

随机推荐