Autore Topic: Problema animazione slide in ViewPager  (Letto 282 volte)

Offline Pepozzo

  • Nuovo arrivato
  • *
  • Post: 8
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus
  • Sistema operativo:
    Windows 7
Problema animazione slide in ViewPager
« il: 23 Aprile 2015, 10:36:59 CEST »
0
Sto costruendo un ViewPager popolato in maniera dinamica e ho inserito due pulsanti che al click/tap eseguono lo slide verso la "slide" successiva.

Sto utilizzando il codice base preso da questo esempio di Google: Using ViewPager for Screen Slides | Android Developers

Nel mio caso lo slider era "diretto/secco", senza l’effetto del movimento tra una slide e l'altra. Per questo motivo ho customizzato il ViewPager nel seguente modo:
customDurationViewPager.java
Codice (Java): [Seleziona]
public class CustomDurationViewPager extends ViewPager {

    public CustomDurationViewPager(Context context) {
        super(context);
        postInitViewPager();
    }

    public CustomDurationViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        postInitViewPager();
    }

    private CustomDurationScroller mScroller = null;

    /**
     * Override the Scroller instance with our own class so we can change the
     * duration
     */

    private void postInitViewPager() {
        try
        {
            Field scroller = ViewPager.class.getDeclaredField("mScroller");
            scroller.setAccessible(true);
            Field interpolator = ViewPager.class.getDeclaredField("sInterpolator");
            interpolator.setAccessible(true);

            mScroller = new CustomDurationScroller(getContext(),
                    (Interpolator) interpolator.get(null));
            scroller.set(this, mScroller);
        }
        catch (Exception e) {
        }
    }
   
   

    /**
     * Set the factor by which the duration will change
     */

    public void setScrollDurationFactor(double scrollFactor)  {
        mScroller.setScrollDurationFactor(scrollFactor);
    }

}
customDurationScroller.java
Codice (Java): [Seleziona]
public class CustomDurationScroller extends Scroller {

    private double mScrollFactor = 1;

    public CustomDurationScroller(Context context) {
        super(context);
    }

    public CustomDurationScroller(Context context, Interpolator interpolator) {
        super(context, interpolator);
    }

    @SuppressLint("NewApi")
    public CustomDurationScroller(Context context, Interpolator interpolator, boolean flywheel) {
        super(context, interpolator, flywheel);
    }

    /**
     * Set the factor by which the duration will change
     */

    public void setScrollDurationFactor(double scrollFactor) {
        mScrollFactor = scrollFactor;
    }

    @Override
    public void startScroll(int startX, int startY, int dx, int dy, int duration) {
        super.startScroll(startX, startY, dx, dy, (int) (duration * mScrollFactor));
    }

}
e li ho implementati nelle mie activity in questo modo.
Codice (Java): [Seleziona]
public class ActBeer extends Fragment {
       
        // __Varibili Globali__  //
        Context ctx;
       

        private TwoWayGridView gwBeer;
        private AdapterGridView adapter;
       
        public CustomDurationViewPager mPager;
        public View view;
       
        String[ ] GRID_DATA = new String[] {"Beer", "Wine", "Sptritz" ,"Mojito", "Cuba Libre", "Gin Lemon",
                                                                                "Gin Tonic", "Lady Killer", "Uragano", "Sex On The Beach", "Caipiroska",
                                                                                "Black Mojito", "Martini Royale", "Margarita", "Black Russian" , "Bloody Mary",
                                                                                "Caipirinha", "Daiquiri", "Long Island", "Manhattan", "Negroni", "Pina Colada",
                                                                                "Tequila Sunrise", "Rossini", "White Russian", "Adios Motherfucker", "Japanese",
                                                                                "Americano", "Paradise", "Kamikaze", "Orgasm", "Screwdriver", "Irish coffee",
                                                                                "Gin Fizz", "Cosmopolitan"};
       
       
        //onCREATE VIEW
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
               
                ctx = getActivity().getApplicationContext();//Recupero il Context
                view = (RelativeLayout)inflater.inflate(R.layout.activity_beer,container,false);
                               
                //Recupero GridView e Page Adapter
                gwBeer = (TwoWayGridView) view.findViewById(R.id.beer_gridview);
                //mPager = (ViewPager) view.findViewById(R.id.beer_viewpager);
                mPager = (CustomDurationViewPager) view.findViewById(R.id.beer_viewpager);
               
                //Visualizzo il Primo e Nascondo il Secondo
                gwBeer.setVisibility(View.VISIBLE);
        mPager.setVisibility(View.GONE);
               
                //Converto la Lista in Array
                String[] gwArr = new String[GW_DATA.size()];
                gwArr = GW_DATA.toArray(gwArr);
                       
               
               
                //Gridview - la Istanzio e gli Setto l'Adapter
                adapter = new AdapterGridView (ctx, gwArr);
                gwBeer.setAdapter(adapter);
                gwBeer.setSelector(R.drawable.selector_empty);//Colore TRASPARENTE al click di un elemento della Gridview
               
               
                //Click di un elemento della Gridview
                gwBeer.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(TwoWayAdapterView<?> parent, View v, int position, long id) {
                //Toast.makeText(ctx,((TextView) v.findViewById(R.id.gw_txt_nome)).getText(), Toast.LENGTH_SHORT).show();
               
                //Nascondo la GridView
                gwBeer.setVisibility(View.GONE);
               
                //Mostro il Pager
                mPager.setVisibility(View.VISIBLE);
                inizializePager(((TextView) v.findViewById(R.id.gw_txt_nome)).getText().toString());
               
            }
        });

                return view;
               
        }//Fine onCreate
       

       
       
       
        //_-_ FUNZIONE per INIZIALIZZARE il VIEWPAGER _-_//
        public void inizializePager(String nome) {
               
                PagerAdapter mPagerAdapter = new DetailSlidePagerAdapter2(getFragmentManager(), GRID_DATA);
        mPager.setAdapter(mPagerAdapter);
        mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            public void onPageSelected(int position) {
            }
        });    
       
        //Cerco l'INDICE della Posizione Corrente
        int index = 0;
        for (int i=0; i<GRID_DATA.length; i++) {
            if (GRID_DATA[i].equals(nome)) {
                index = i;
                break;
            }
        }
        mPager.setCurrentItem(index);//Setto l'elemento corrente
        }
       
       
       
        //_-_ CLASSE per il PAGE ADAPTER _-_//
    private class DetailSlidePagerAdapter2 extends FragmentStatePagerAdapter {
       
        public DetailSlidePagerAdapter2(FragmentManager fm, String[] GRID_DATA) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            return FrgDetailSlideScreen.create(position, GRID_DATA[position], view, mPager);
        }

        @Override
        public int getCount() {
            return GRID_DATA.length;
        }
    }

}
FrgDetailsSlideScreen.java
Codice (Java): [Seleziona]
public class FrgDetailSlideScreen extends Fragment {
           
                //The argument key for the page number this fragment represents.
            public static final String ARG_PAGE = "page";
            public static final String DRINK_NAME = "nome";
            public static final String VIEW = "vista";
           
            //The fragment's page number, which is set to the argument value for {@link #ARG_PAGE}.
            private int mPageNumber;
            private String mDrinkName;
           
            public static View vw;
            //public static CustomDurationViewPager pgr;
            public static CustomDurationViewPager pgr;

            public ActBeer frgBeer = new ActBeer();

            //Factory method for this fragment class. Constructs a new fragment for the given page number
            public static FrgDetailSlideScreen create(int pageNumber, String nomeDrink, View view, CustomDurationViewPager mPager) {
               
                FrgDetailSlideScreen fragment = new FrgDetailSlideScreen();
                Bundle args = new Bundle();
                args.putInt(ARG_PAGE, pageNumber);
                args.putString(DRINK_NAME, nomeDrink);
                vw = view;
                pgr = mPager;
                fragment.setArguments(args);
                return fragment;
            }

           
            public FrgDetailSlideScreen() {
            }

           
            @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                mPageNumber = getArguments().getInt(ARG_PAGE);
                mDrinkName = getArguments().getString(DRINK_NAME);
            }

           
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
               
                //Recupero il Cotext, e le varibiali salvate in BUNDLE
                Context ctx = getActivity().getApplicationContext();
               
                //Setto il Layout della singola pagina dello Slider.
                ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_detailslidescreen, container, false);

                //Setto il NOME del Prodotto
                ((TextView) rootView.findViewById(R.id.details_txtNome)).setText(mDrinkName);
               
               
                //Faccio un IF per decidere il nome dell'IMMAGINE
                String imgName = "icon_gw7";
               
               
                Drawable drawable = getResources().getDrawable(getResources().getIdentifier(imgName, "drawable", ctx.getPackageName()));
               
                //Setto l'IMMAGINE all'ImageView
                ((ImageView) rootView.findViewById(R.id.details_imgImage)).setImageDrawable(drawable);
               
               
                //Setto lo SCROLL per la TexView delle Curiosità
                ((TextView) rootView.findViewById(R.id.details_txtCuriosita)).setMovementMethod(new ScrollingMovementMethod());
               
               
               
                //Associo il CLICK all'ImageView di FRECCIA NEXT
                ImageView imgNext = ((ImageView) rootView.findViewById(R.id.details_imgArrowRight));
                imgNext.setOnClickListener(new View.OnClickListener() {
                                public void onClick(View v) {
                                        pgr.setScrollDurationFactor(12);
                                        pgr.setCurrentItem(pgr.getCurrentItem() + 1, true);
                                        pgr.setScrollDurationFactor(1);
                                }
                        });
               
              //Associo il CLICK all'ImageView di FRECCIA PREV
                ImageView imgPrev = ((ImageView) rootView.findViewById(R.id.details_imgArrowLeft));
                imgPrev.setOnClickListener(new View.OnClickListener() {
                                public void onClick(View v) {
                                        pgr.setScrollDurationFactor(12);
                                        pgr.setCurrentItem(pgr.getCurrentItem() - 1, true);
                                        pgr.setScrollDurationFactor(1);
                                }
                        });
               
               
               
               
               
                return rootView;
            }

           
           
            // Returns the page number represented by this fragment object.
            public int getPageNumber() {
                return mPageNumber;
            }
        }
Con questa implementazione si vede l’effetto del movimento, tuttavia l’effetto parte da metà schermo e non è fluido come nell’esempio di Google.

NB: ho implementato le classi customdurationviewpager e customdurationscroller anche nel progetto di google ricreando una situazione come nella mia app. lì tutto funziona correttamente e fluidamente.

A cosa può essere dovuto il fatto che l'animazione parte da metà schermo (e quindi risulta "scattosa") e non dal bordo estremo come mi capita con l'esempio di Google?

PS: API level minimo: 14

Grazie in anticipo per le eventuali risposte