Problème de rendu personnalisé ViewPager sur certains périphériques:

J'ai développé une sorte de mécanisme de roulement pour choisir le personnel dans la demande. C'est un poteau de vue personnalisé qui permet de présenter plus d'un élément à l'écran à chaque fois (3 dans mon cas) et entouré d'ombres des deux côtés.

Voici comment il devrait ressembler et fonctionne comme ça sur des appareils tels que Nexus 5 , Nexus 4 , Galaxy S3 :

  • Déclenchement d'un fichier audio lorsque l'appel est répondu
  • Android Studio Gradle Problème: OutOfMemoryError: espace PermGen
  • Comment intégrer l'authentification FireBase avec les terminaux Google Search Engine
  • Comment ajouter une bordure autour de TableLayout?
  • Initialisation de l'application Android
  • Proguard.cfg Missing
  • Entrez la description de l'image ici

    Mais sur certains appareils comme ( Sony Xperia et différents types de Motorola ), le rendu semble mauvais, voici le résultat:

    Entrez la description de l'image ici

    En ce qui concerne le code, j'ai parrainé cet article par @Commonsware :

    Http://commonsware.com/blog/2012/08/20/multiple-view-viewpager-options.html

    Et la troisième option, quel code vous pouvez trouver ici .

    Voici mon code pertinent:

    PagerContainer:

    public class PagerContainer extends FrameLayout implements ViewPager.OnPageChangeListener { private ViewPager mPager; boolean mNeedsRedraw = false; public PagerContainer(Context context) { super(context); init(); } public PagerContainer(Context context, AttributeSet attrs) { super(context, attrs); init(); } public PagerContainer(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { //Disable clipping of children so non-selected pages are visible setClipChildren(false); //Child clipping doesn't work with hardware acceleration in Android 3.x/4.x //You need to set this value here if using hardware acceleration in an // application targeted at these releases. if (Build.VERSION.SDK_INT >= 11 && Build.VERSION.SDK_INT < 19) { setLayerType(View.LAYER_TYPE_SOFTWARE, null); } } @Override protected void onFinishInflate() { try { mPager = (ViewPager) getChildAt(0); mPager.setOnPageChangeListener(this); } catch (Exception e) { throw new IllegalStateException("The root child of PagerContainer must be a ViewPager"); } } public ViewPager getViewPager() { return mPager; } private Point mCenter = new Point(); private Point mInitialTouch = new Point(); @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { mCenter.x = w / 2; mCenter.y = h / 2; } @Override public boolean onTouchEvent(MotionEvent ev) { //We capture any touches not already handled by the ViewPager // to implement scrolling from a touch outside the pager bounds. switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mInitialTouch.x = (int)ev.getX(); mInitialTouch.y = (int)ev.getY(); default: ev.offsetLocation(mCenter.x - mInitialTouch.x, mCenter.y - mInitialTouch.y); break; } return mPager.dispatchTouchEvent(ev); } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { //Force the container to redraw on scrolling. //Without this the outer pages render initially and then stay static if (mNeedsRedraw) invalidate(); } @Override public void onPageSelected(int position) { invalidate(); } @Override public void onPageScrollStateChanged(int state) { mNeedsRedraw = (state != ViewPager.SCROLL_STATE_IDLE); } } 

    Init part:

      //Size View Pager: //======================================== pagerSize = mContainerSize.getViewPager(); adapter = new MySizePagerAdapter(); pagerSize.setAdapter(adapter); //Necessary or the pager will only have one extra page to show make this at least however many pages you can see pagerSize.setOffscreenPageLimit(adapter.getCount()); //A little space between pages pagerSize.setPageMargin(15); //If hardware acceleration is enabled, you should also remove clipping on the pager for its children. pagerSize.setClipChildren(false); 

    Une recherche plus poussée m'a amené à comprendre que ce problème a quelque chose à voir avec l'accélération matérielle ou l'absence de celle-ci dans certains appareils. Mais la désactivation via le code ne m'a pas aidé non plus.

    Quelqu'un a-t-il rencontré ce problème et sait comment le réparer?

    Merci d'avance.

  • VFY: impossible à résoudre la méthode statique 10876: Android
  • OnItemClickListener et OnClickListener ne fonctionnent pas pour ListView
  • Utilisation de Proguard avec Android sans obscurcissement
  • Erreur de base de données indéfinie dans phonegap android?
  • Supprimez le filtre de EditText dans Android?
  • @Override annotation error (android prefs)
  • 2 Solutions collect form web for “Problème de rendu personnalisé ViewPager sur certains périphériques:”

    J'essayerais de définir le type de couche du ViewPager et les enfants à l'exécution du logiciel, au lieu de la disposition du cadre parent.

    Vous pouvez également consulter cette publication sur le blog: http://udinic.wordpress.com/2013/09/16/viewpager-and-hardware-acceleration/

    J'ai fini par utiliser une autre implémentation d'un ViewPager qui m'a donné le même résultat, mais le problème de rendu n'a pas été vu là-bas, c'est le code:

      private class MyTypePagerAdapter extends PagerAdapter { @Override public Object instantiateItem(ViewGroup container, int position) { TextView view = new TextView(getActivity()); view.setText(mTempBeverageList.get(position).getName().toUpperCase()); if (!wasTypeChanged && (!isLocaleHebrew && position == 1)) { view.setTypeface(null, Typeface.BOLD); view.setTextSize(19); } else { view.setTextSize(16); } view.setSingleLine(); view.setGravity(Gravity.CENTER); view.setTextColor(getResources().getColor(R.color.cups_black)); view.setBackgroundColor(getResources().getColor(R.color.cups_cyan)); container.addView(view); return view; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View)object); } @Override public int getCount() { return mTempBeverageList.size(); } @Override public float getPageWidth(int position) { return (0.33333f); } @Override public boolean isViewFromObject(View view, Object object) { return (view == object); } } 

    Et la partie d'initialisation:

     pagerType= (ViewPager) view.findViewById(R.id.pagerType); pagerType.setAdapter(new MyTypePagerAdapter()); pagerType.setOffscreenPageLimit(6); 
    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.