2016-06-19 26 views
6

Ich habe ein seltsames "Problem" oder vielleicht ist es ein "Feature" und ich weiß einfach nicht, wann immer ein NativeAdExpress in mein RecyclerView geladen wird Ein Teil der NativeAd ist sichtbar, es zwingt den RecyclerView zu scrollen, bis die Native Anzeige vollständig sichtbar wird. Dieses Verhalten führt dazu, dass die Liste beim Scrollen weiter springt.NativeAdsExpress forciert RecyclerView, um das NativeAd vollständig sichtbar zu machen, wenn es zum ersten Mal geladen wird

Mein Plan ist vor allem:

Activity> AppBar mit Tabs und ViewPager> Jeder Seite in dem Pager enthält PullToRefresh und im Innern gibt es eine RecyclerView, Die RecyclerView hat 2 Arten von Gegenständen (Artikel und NativeAdExpress).

UPDATE: Meine Vermutung auf, warum dies geschieht ist vor allem, weil native Anzeigen in einer Webansicht machen auszudrücken, und diese webview Fokus erhält dann dies bewirkt, dass der RecyclerView, um es zu bewegen, aber das ist nur eine Vermutung

UPDATE 2: Offenbar ist dies ein Problem in Support Lib. 24.0.0, das ist die Kosten des Seins zu up2date :(

Heres meiner Voll XML/Layouts

<?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> 

wo "app_bar_main.xml" ist wie folgt:

<?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> 

und schließlich Ich habe 2 Ansichtstypen Artikel und NativeAdExpress:

Der NativeAdExpress ViewHolder ist wie folgt:

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; 
     } 
    } 
} 

und Anzeigen sind erstellen Sie eine benutzerdefinierte Adapter wie folgt:

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; 
    } 

Antwort

12

Ich verstand nicht, wo man tatsächlich ein RecyclerView in Ihrem Code implementieren, aber hier ist sowieso vielleicht etwas, das in Ihrem Fall funktionieren könnte.

Ich hatte ein ähnliches Problem mit einer GridView immer den Fokus während einer Fragment ersten Laden, es war auch automatisch scrollen direkt auf die GridView.

Nach vielen Tests, hörte ich endlich dieses Verhalten mit dieser Zeile auf dem übergeordnete Layout der GridView:

android:descendantFocusability="blocksDescendants" 

Diese Linie bedeutet im Grunde, dass alle Nachkommen aus dem übergeordneten Layout nicht mehr konzentrieren werden erhalten . Sie können es auf Ihrem RecyclerView übergeordneten Layout ausprobieren.

+1

Vielen Dank das hat den Job, obwohl ich sagen muss, dass dieses Problem im Allgemeinen nur "einige" Version von Android-Support-lib betrifft. z.B. 23.4.0 ist nicht betroffen, während 23.2.x und 23.3.0 und 24.0.0 von diesem Problem betroffen sind !! – Shehabix

0

hatte ich ein ähnliches Problem mit RecyclerView Scrollen, nicht speziell auf NativeAdExpress ... aber es scheint diesen24.0.0 Zusammenhang ein Problem mit der Android Support-Bibliothek. Die android: demcendantFocusability = "blocksDescendants" funktionierte nicht für mich. Aber Downgrade auf Android Support-Bibliothek23.4.0 machte es wieder zu arbeiten.

1

Ich weiß nicht, ob es ein Problem ist, aber das sieht aus wie RecyclerView änderte sein Verhalten irgendwo von Support-Bibliothek 23.4.0 bis 24.2.0.

Anstatt defecendantFocusability = beforeDescendents standardmäßig zu verwenden, wird standardmäßig afterDescendents verwendet, wodurch der Fokus für die untergeordneten Elemente bereitgestellt wird, anstatt sie selbst zu übernehmen.

Wenn ein Kind den Fokus nimmt, scrollt es, um es sichtbar zu machen.

Ich reparierte es durch Hinzufügen von android: demcendantFocusability = "beforeDescendants" zum RecyclerView, um das vorherige Verhalten wiederherzustellen, wo es den Fokus selbst behält.