2016-06-19 53 views
6

Mam dziwny "problem" lub może to być "funkcja" i po prostu nie wiem, kiedy NativeAdExpress jest załadowany w moim RecyclerView, jeśli tylko część NativeAd jest widoczna, zmusza RecyclerView do przewijania do momentu, w którym reklama natywna stanie się w pełni widoczna. Takie zachowanie powoduje, że lista wciąż przeskakuje podczas przewijania.NativeAdsExpress wymusza RecyclerView to Scroll, aby NativeAd był w pełni widoczny po pierwszym załadowaniu

Mój układ jest głównie:

aktywny> AppBar z kartami i ViewPager> każdej strony w Pager zawiera PullToRefresh i wewnątrz niego istnieje RecyclerView, RecyclerView ma 2 rodzaje przedmiotów (artykuł i NativeAdExpress).

UPDATE: Zgaduję, dlaczego tak się dzieje się tak głównie dlatego reklamy natywne wyrazić renderowanie w WebView, a to WebView odbiera skupić to ta powoduje RecyclerView aby przewinąć do niego, ale to tylko przypuszczenie

AKTUALIZACJA 2: Wygląda na to, że problem dotyczy usługi Support Lib. 24.0.0, to koszt jest zbyt up2date :(

Herezje to mój Pełna XML/Układy

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

gdzie "app_bar_main.xml" przedstawia się następująco:

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

i wreszcie Mam 2 typy widoku pozycji i NativeAdExpress:

NativeAdExpress ViewHolder jest następujący:

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

i reklamy są tworzyć za pomocą adaptera niestandardowego następująco:

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

Odpowiedz

12

I nie rozumiem, gdzie rzeczywiście wdrożyć RecyclerView w kodzie, ale tutaj jest i tak być może coś, co może działać w Twoim przypadku.

Miałem podobny problem z GridView, zawsze uzyskując fokus podczas pierwszego obciążenia Fragment, a także automatycznie przewijano w dół do GridView.

Po wielu próbach w końcu zatrzymał się ten problem z tym jednym wierszu na układ dominującej GridView:

android:descendantFocusability="blocksDescendants" 

Linia ta w zasadzie oznacza, że ​​wszyscy potomkowie z układu nadrzędnego nie będzie się skupić już . Możesz go wypróbować na swoim układzie rodzica RecyclerView.

+1

Wielkie dzięki to zadanie, chociaż muszę powiedzieć, że ten problem ogólnie dotyczy tylko "jakiejś" wersji lib wsparcia dla Androida. na przykład 23.4.0 nie ma wpływu na ten problem, podczas gdy 23.2.x i 23.3.0 i 24.0.0 są dotknięte tym problemem !! – Shehabix

0

Miałem podobny problem z RecyclerView przewijania, a nie konkretnie NativeAdExpress ... ale nie wydaje się być problem z biblioteką Android Wsparcia24.0.0 z tym związanych. The android: descendantFocusability = "blocks Descendants" nie działa dla mnie. Ale zmiana do biblioteki pomocy technicznej Android23.4.0 sprawiła, że ​​zaczął działać ponownie.

1

Nie wiem, czy jest to numer, ale wygląda na to, że RecyclerView zmienił swoje zachowanie gdzieś z biblioteki wsparcia 23.4.0 na 24.2.0.

Teraz zamiast domyślnego dla potomka Fokusowalności = przed Descendants, domyślnie jest to poszukaństwo, co powoduje, że oferuje skupienie swoim dzieciom, zamiast brać je dla siebie.

Gdy dziecko zacznie się skupiać, będzie przewijane, aby było widoczne.

Naprawiłem to, dodając: Android: descendantFocusability = "beforeDescendants" do RecyclerView, aby odzyskać poprzednie zachowanie, w którym utrzymuje samo skupienie.