Sono riuscito a creare un'animazione all'inizio del mio CustomViewPager che si comporta come un carosello. Quindi qui, i miei oggetti sono venuti da sinistra e vanno a destra in 3 secondi. Il fatto è che è solo una traduzione che mi stavo chiedendo se è possibile solo far scorrere il mio viewpager da lontano alla sua posizione finale.Avvia un'animazione all'avvio di CustomViewPager
Vedete un modo per farlo? Saluti.
Modifica: Così provo qualcos'altro e ho creato il mio Custom ScrollToAnimation. Riusco a creare ciò che voglio ma il movimento non è fluido, puoi aiutarmi. Il mio nuovo codice:
import android.support.v4.view.ViewPager;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import java.util.Calendar;
public class ScrollToAnimation extends Animation {
private int currentIndex = 0, nbChilds = -1, deltaT = 0;
private float fromX, toX;
private long animationStart;
private ViewPager viewpager;
public ScrollToAnimation(ViewPager viewpager, float fromX, float toX, int duration) {
this.viewpager = viewpager;
this.fromX = fromX;
this.toX = toX;
nbChilds = viewpager.getChildCount();
deltaT = duration/nbChilds;
setDuration(duration);
animationStart = Calendar.getInstance().getTimeInMillis();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
int offset = (int) (-fromX * interpolatedTime + fromX);
viewpager.scrollTo(offset, 0);
long animationProgression = Calendar.getInstance().getTimeInMillis() - animationStart;
currentIndex = (int) (animationProgression/deltaT);
if(viewpager.getCurrentItem() != currentIndex) {
viewpager.setCurrentItem(nbChilds-currentIndex, false);
}
}
}
Il ViewPager:
import android.content.Context;
import android.graphics.Canvas;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.animation.Animation;
import android.view.animation.Interpolator;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class CarouselViewPager extends ViewPager {
private DisplayMetrics metrics;
private Animation animation;
private SpeedScroller mScroller = null;
private boolean animationNotStarted = true, leftToRight;
public CarouselViewPager(Context context) {
super(context);
postInitViewPager();
metrics = getContext().getResources().getDisplayMetrics();
}
public CarouselViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
postInitViewPager();
metrics = getContext().getResources().getDisplayMetrics();
}
private void postInitViewPager() {
try {
Class<?> viewpager = ViewPager.class;
Field scroller = viewpager.getDeclaredField("mScroller");
scroller.setAccessible(true);
Field interpolator = viewpager.getDeclaredField("sInterpolator");
interpolator.setAccessible(true);
mScroller = new SpeedScroller(getContext(), (Interpolator) interpolator.get(null));
scroller.set(this, mScroller);
} catch (Exception e) {
Log.e("postInitViewPager", e.getMessage());
}
}
public void setScrollDurationFactor(double scrollFactor) {
mScroller.setScrollDurationFactor(scrollFactor);
}
@Override
public void setCurrentItem(int item, boolean smoothScroll) {
try {
Method method = ViewPager.class.getDeclaredMethod("setCurrentItemInternal", int.class, boolean.class, boolean.class, int.class);
method.setAccessible(true);
method.invoke(this, item, true, false, 1500);
} catch (Exception e) {
e.printStackTrace();
super.setCurrentItem(item, smoothScroll);
}
}
public void startAnimation(boolean leftToRight) {
animation = new ScrollToAnimation(this, ((metrics.widthPixels/2)+200)*2, 0, 2000);
animationNotStarted = false;
this.leftToRight = leftToRight;
}
private Canvas enterAnimation(final Canvas c) {
animationNotStarted = true;
startAnimation(animation);
scrollTo(0, 0);
return c;
}
@Override
protected void onDraw(Canvas canvas) {
if (!animationNotStarted) {
canvas = enterAnimation(canvas);
}
super.onDraw(canvas);
}
}
Edit2:
Ecco uno screenshot per aiutare a capire quello che voglio. In realtà ho un viewpager personalizzato come questo:
L'animazione che voglio è il seguente:
- Quando lancio l'animazione della voce sono lontani.
- Dopo, vengono da sinistra a destra (o il contrario) e si fermano all'elemento selezionato, ma voglio avere l'effetto di scala quando gli elementi stanno scorrendo.
- riesco a creare l'effetto di scala grazie ad un adattatore personalizzato
Il mio problema, qui è quando ho impostato l'elemento corrente non è liscia, hai qualche idea? Ecco l'adattatore codice
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
public class CarouselAdapter extends FragmentPagerAdapter implements ViewPager.OnPageChangeListener {
private float scale;
private MainActivity context;
private FragmentManager fragmentManager;
private ArrayList<Entity> entities = new ArrayList<>();
private ScaledFrameLayout cur = null, next = null;
public CarouselAdapter(MainActivity context, FragmentManager fragmentManager, ArrayList<Entity> mData) {
super(fragmentManager);
this.fragmentManager = fragmentManager;
this.context = context;
this.entities = mData;
}
@Override
public Fragment getItem(int position) {
if (position == MainActivity.FIRST_PAGE) {
scale = MainActivity.BIG_SCALE;
} else {
scale = MainActivity.SMALL_SCALE;
}
Fragment fragment = CarouselFragment.newInstance(context, entities.get(position), position, scale);
return fragment;
}
@Override
public int getItemPosition(Object object) {
return super.getItemPosition(object);
}
@Override
public int getCount() {
return entities.size();
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (positionOffset >= 0f && positionOffset <= 1f) {
cur = getRootView(position);
cur.setScaleBoth(MainActivity.BIG_SCALE - MainActivity.DIFF_SCALE * positionOffset);
if (position < entities.size()-1) {
next = getRootView(position + 1);
next.setScaleBoth(MainActivity.SMALL_SCALE + MainActivity.DIFF_SCALE * positionOffset);
}
}
}
@Override
public void onPageSelected(int position) { }
@Override
public void onPageScrollStateChanged(int state) {}
private ScaledFrameLayout getRootView(int position) {
return (ScaledFrameLayout) fragmentManager.findFragmentByTag(this.getFragmentTag(position)).getView().findViewById(R.id.rootItem);
}
private String getFragmentTag(int position) {
return "android:switcher:" + context.carousel.getId() + ":" + position;
}
}
Un modo più semplicemente, sarebbe quello di cambiare la posizione corrente della voce corrente senza aggiornare tutto, è possibile? Voglio dire senza fare alcuna transizione perché come puoi vedere ho già la traduzione e quando imposto l'elemento corrente è risultato con un conflitto con il mio scrollto con l'offset.
Compilare la domanda. È difficile capire dove sei davvero bloccato –
Voglio migliorare la mia animazione corrente. Qui la mia animazione è solo una traduzione da destra a sinistra. Voglio avere una scroll scorrevole come se stessi scorrendo il viewpager grazie al mio dito. Ad esempio, voglio essere in grado di utilizzare lo stesso risultato che se stavo usando il metodo scollTo dalla classe ViewPager, scusa se non è ancora chiaro. – zed13
@ zed13: "Mi chiedevo se fosse possibile far scorrere il mio viewpager da lontano fino alla sua posizione finale." anche questo sembra una traduzione. di solito scrollTo rende solo la traduzione. ma se puoi pubblicare video di ciò che stai cercando di ottenere sarà più facile (per quanto ho visto ViewPager rende solo l'animazione di traduzione). –