Мне удалось создать анимацию в начале моего CustomViewPager, который действует как карусель. Так вот, мои предметы пришли слева и идут вправо через 3 секунды. Дело в том, что это просто перевод, который мне задавался вопросом, возможно ли просто сделать мой просмотрщик прокручиваться издалека до его последней позиции.
Вы видите способ сделать это? С наилучшими пожеланиями.
Изменить: Итак, я попробую что-то еще, и я создал свой собственный ScrollToAnimation. Мне удается создать то, что я хочу, но движение не является гладким, вы можете мне помочь. Мой новый код:
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);
}
}
}
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:
Вот скриншот, который поможет вам понять, чего я хочу. На самом деле у меня есть настраиваемый просмотрщик:
Мне нужна анимация:
- Когда я запускаю анимацию, элемент находится далеко.
- После этого они идут слева направо (или наоборот) и останавливаются на выбранном элементе, но я хочу иметь эффект масштаба, когда элементы прокручиваются.
- Мне удалось создать эффект масштабирования благодаря пользовательскому адаптеру
Моя проблема, вот когда я устанавливаю текущий элемент, который не является гладким, есть ли у вас какие-либо идеи? Вот код-адаптер
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;
}
}
Более простым способом было бы изменить текущую позицию текущего элемента без обновления всего, возможно ли это? Я имею в виду без какого-либо перехода, потому что, как вы видите, у меня уже есть перевод, и когда я устанавливаю текущий элемент, это приводит к конфликту с моим scrollto со смещением.