2016-04-11 23 views
10

CustomViewPager'ımın başında bir Atlıkarınca gibi davranan bir animasyon oluşturmayı başarabilirim. İşte burada, eşyalarım soldan geldi ve 3 saniyede sağa gider. Mesele şu ki sadece görüntüleyici görüşümü son noktadan uzaklaştırabiliyor mu diye merak ettiğim bir çeviri.Başlangıçta bir animasyon başlatma CustomViewPager

Bunu yapmak için bir yol görüyor musunuz? Saygılar.

Düzenleme: Başka bir şey deniyorum ve özel ScrollToAnimation'ı oluşturdum. İstediğimi yaratmayı başarabiliyorum ama hareket pürüzsüz değil bana yardım edebilirsin. Benim yeni kodu:

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: Burada

bir ekran görüntüsü ne istediğimi anlamaya yardımcı olur. Aslında böyle bir özel viewpager vardır:

  • Ben animasyonu öğesini başlatmak

    uzakta şunlardır:

    enter image description here

    istediğim animasyon takip olduğunu.

  • Ardından, soldan sağa (veya tersine) gelirler ve seçili öğeye dururlar, ancak öğeler kaydırıldığında ölçek etkisine sahip olmak isterim. Ben Düz değil Geçerli öğeyi ayarladığınızda
  • Burada, bir özel adaptör

Sorunum ölçeklendirme etkisi sayesinde yaratmak olduğunu başarılı bir fikriniz var mı? İşte kod adaptör

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

daha basit yoludur, şimdiki öğenin geçerli konumunu değiştirmek olmadan her şeyi yenilemek olacaktır, bu mümkün mü? Herhangi bir geçiş yapmadan demek istiyorum çünkü gördüğünüz gibi çeviriye zaten sahip oldum ve mevcut öğeyi belirlediğimde, kaydırma ile kaydırmayla bir sonuç çıkıyor.

+1

Lütfen sorunuz hakkında ayrıntılı bilgi veriniz. Gerçekte nerede olduğumu anlamak zor. –

+1

Güncel animasyonumu geliştirmek istiyorum. İşte benim animasyonum, sağdan sola doğru bir çeviri. Parmağım sayesinde viewpager'ı kaydırıyormuş gibi pürüzsüz bir kaydırma yapmak istiyorum. Örneğin, aynı sonucu, ViewPager sınıfından scollTo yöntemini kullanıyor olsaydım, hala belirsizse özür dilerim. – zed13

+1

@ zed13: "Görüntüleyici görüşümün kaydırılmasını son noktaya kadar yapmanın mümkün olup olmadığını merak ediyordum." Bu da bir çeviri gibi geliyor. scrollTo sadece çeviri yapar. Ancak, elde etmeye çalıştığınız şeyin videosunu yayınlayabiliyorsanız, daha kolay olacaktır (ViewPager'ın sadece çeviri animasyonunu yaptığım kadarıyla). –

cevap

1

Pürüzsüz Görüntüleyici'yi kullanmaya çalışın, hızını yapılandırabilirsiniz. İhtiyacınız olan tek şey onu 0 pozisyonuna getirip görünür hale getirip hedef pozisyona taşıyarak, hedefe sorunsuzca kaydırır, isterseniz herhangi bir animasyonu ortak görüş cihazında uygulayabilirsiniz. Ayrıca false ve kullanıcıya setPagingEnable dokunmatik

Sana Sooth kaydırma ve animasyon ile görüntü değişikliği ile imageSlider birini yapmak zorunda düşünüyorum
public class SmoothScrollViewPager extends ViewPager { 
    private boolean enabled = true; 
    public SmoothScrollViewPager(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     setMyScroller(); 
    } 

    private void setMyScroller() { 
     try { 
      Class<?> viewpager = ViewPager.class; 
      Field scroller = viewpager.getDeclaredField("mScroller"); 
      scroller.setAccessible(true); 
      scroller.set(this, new MyScroller(getContext())); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     if (this.enabled) { 
      return super.onTouchEvent(event); 
     } 

     return false; 
    } 

    public class MyScroller extends Scroller { 
     public MyScroller(Context context) { 
      super(context, new DecelerateInterpolator()); 
     } 

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

    } 

    public void setPagingEnabled(boolean enabled) { 
     this.enabled = enabled; 
    } 
} 
+1

Zaten düzgün bir kaydırıcı (SpeedScroller) var, sorun, setCurrentItem() yöntemi sayesinde geçerli seçili öğeyi değiştirmeye çalıştığım, ancak aynı zamanda scrollTo yöntemini kullandığım için görüntülenir. Peki neden setCurrentItem() kullanıyorum? Çünkü ViewPager'ın adaptörümden onPageScrolled() yöntemini çağırdı, aynı zamanda viewpager da kaydırma yapıyor. – zed13

3

bunu kaydırma olmaz edilebilir.

Android Image Github'da bulunan kaydırıcı kitaplığı şimdi kullanmak için aşağıdaki adımı izleyin.

  • 1. adım: Derecenin altındaki lib derlemesi.

    dependencies { 
    compile "com.android.support:support-v4:+" 
    compile 'com.squareup.picasso:picasso:2.3.2' 
    compile 'com.nineoldandroids:library:2.4.0' 
    compile 'com.daimajia.slider:library:[email protected]' 
    } 
    
  • 2. Adım: AndroidManifest için (gerekirse) izinleri ekleyin.xml

    <!-- if you want to load images from the internet --> 
    <uses-permission android:name="android.permission.INTERNET" /> 
    
    <!-- if you want to load images from a file OR from the internet --> 
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
    
  • Adım 3: düzene Kaydırıcısını ekleyin:

    <com.daimajia.slider.library.SliderLayout 
    android:id="@+id/slider" 
    android:layout_width="match_parent" 
    android:layout_height="200dp" 
    /> 
    

    Şimdi Burada ActivitySlideShow.class içinde Kodunu yönetmek kod olun.

public class SlideShow extends Activity { 
    ImageView mIVmenu; 
    SliderLayout sliderLayout; 
    ListView menu_list; 
    ArrayList<String> imgList = new ArrayList<String>(); 
    int position; 
    Button btnBack; 
    static int adapter_position = 0; 
    String animation_name; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.slideshow); 
     sliderLayout = (SliderLayout) findViewById(R.id.sliderlayout); 
     menu_list = (ListView) findViewById(R.id.menu_list); 
     btnBack = (Button) findViewById(R.id.btn_back_slideshow); 
     menu_list.setAdapter(adapter); 
     // get Data from Intent array list and set on array list 
     imgList = getIntent().getStringArrayListExtra("arrayList"); 
     position = getIntent().getExtras().getInt("position"); 
     animation_name = SliderLayout.Transformer.Default.toString(); 
    } 

    // call method for set images in slideshow and configure slideshow.. 
    addImagesToSlider(); 

    btnBack.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     Intent i = new Intent(SlideShow.this, MainActivity.class); 
     startActivity(i); 
     finish(); 
    } 
}); 

} 

private void addImagesToSlider() { 
    for (int i = 0; i < imgList.size(); i++) { 
    TextSliderView textSliderView = new TextSliderView(this); 
    textSliderView.description("").image(new File(imgList.get(i))).setScaleType(BaseSliderView.ScaleType.CenterInside).setOnSliderClickListener(new BaseSliderView.OnSliderClickListener() { 
     @Override 
     public void onSliderClick(BaseSliderView slider) { 
     } 
    }); 
    sliderLayout.addSlider(textSliderView); 
    } 

sliderLayout.setPresetTransformer(animation_name); 
sliderLayout.setCustomAnimation(new DescriptionAnimation()); 
sliderLayout.stopAutoCycle(); 
sliderLayout.setCurrentPosition(position); 
} 

BaseAdapter adapter = new BaseAdapter() { 
@Override 
public int getCount() { 
    return SliderLayout.Transformer.values().length; 
} 

@Override 
public Object getItem(int position) { 
    return null; 
} 

@Override 
public long getItemId(int position) { 
    return 0; 
} 

@Override 
public View getView(final int position, View convertView, ViewGroup parent) { 

    View view; 
    view = LayoutInflater.from(parent.getContext()).inflate(R.layout.slidemenu_item, parent, false); 
    TextView tv = (TextView) view.findViewById(R.id.txtslideTitle); 
    final String str = SliderLayout.Transformer.values()[position].toString(); 
    tv.setText(str); 

    view.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      sliderLayout.setPresetTransformer(str); 
      animation_name = str; 
      notifyDataSetChanged(); 

     } 
    }); 
    if (str.equals(animation_name)) { 
     adapter_position = position;       
tv.setBackgroundColor(getResources().getColor(R.color.colorAccent)); 
    } else { tv.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark)); 
    } 
    return view; 
} 
    }; 
} 
Ve fazla bilgi Bazı iç gözlem sayesinde ilerleme başarılı this

0

bakın. ViewPager sınıfının pageScrolled yöntemini çağırdım.

İlgili konular