私は実装しているこの例をモデルにした ViewPager を持っていますViewPager.PageTransformer
:
public class DepthPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f;
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
view.setAlpha(1);
view.setTranslationX(0);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) { // (0,1]
view.setAlpha(1 - position);
view.setTranslationX(view.getWidth() * -position);
float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
view.setAlpha(0);
}
}
}
上記のリンクに示されているDepth Page Transformerアニメーションに示されているように、うまく機能します。
ただし、現在の動作方法では、右側のビューは常に左側のビューの下にあります。右にスクロールすると、下からのビューが表示されます。左にスクロールすると、現在のビューが新しいビューの下に移動し、新しいビューが上にスライドします。
私がやりたいのは、現在のビューを常に上にして、新しいビュー (左または右) を後ろ/下から表示することです。
追加してみました
view.bringToFront();
ブロックに追加しif(position <= 0)
ますが、何も変わりません。私も追加しようとしました
view.bringToFront();
view.invalidate();
と
view.bringToFront();
((View)view.getParent()).invalidate();
すべて役に立たない。これらは、私が見つけることができる同様の SO 投稿で採用されているのと同じアプローチですが、それらはすべて、機能するという回答とコメントを受け入れています。しかし、私のものはそうではありません!
スワイプの方向に関係なく、現在のビューを常に一番上のビューにするにはどうすればよいですか?
編集 1 - 追加の詳細
コメントで述べたように、同じアニメーションを両方向に動かすには、右にスワイプするか左にスワイプするかを知る必要があります。
ViewPager には3 つのビューしかなく、この投稿VerticalViewPager
に基づいてとして表示されます。
PageTransformer 内には、次のものがあります。
@Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
view.setAlpha(0);
}
else if(position <= 0){
if(view == first){
view.setAlpha(1 - Math.abs(position));
view.setTranslationX(view.getWidth() * -position);
view.setTranslationY(0);
float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
}else if(view == second){
view.setAlpha(1);
view.setTranslationX(view.getWidth() * -position);
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
}else if(view == third){
// Never happen
}
}
else if (position <= 1) { // [0,1]
if(view == first){
// Never happen
}else if(view == second){
view.setAlpha(1);
view.setTranslationX(view.getWidth() * -position);
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
}else if(view == third){
view.setAlpha(1 - position);
view.setTranslationX(view.getWidth() * -position);
view.setTranslationY(0);
float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
}
} else { // (1,+Infinity]
view.setAlpha(0);
}
}
ここfirst
で、second
とはPagerAdapter 内でthird
型および設定されます。View
@Override
public View instantiateItem(ViewGroup container, int position) {
if(position == 0){
... stuff ...
vvp.first = img;
... stuff ...
}else if(position == 1){
... stuff ...
vvp.second = img;
... stuff ...
}else if(position == 2){
... stuff ...
vvp.third = img;
... stuff ...
}
}
一緒に少しハックされていますが、うまく機能し、私が探している機能を正確に取得します. 機能していないことを除いbringToFront
て。transformPage
しかし、元の投稿のコードを使用しても、この編集のより包括的なバージョンを使用しても機能しません。
second
常に一番上に表示する方法 (つまり、3 つの中央のビュー)を作成する方法がまだわかりません。ジェネリックも試しました
second.bringToFront();
メソッドの先頭にありますが、まだ何もありません。
編集2
試してみview.setZ()
ましたが、次のエラーが発生しました。
java.lang.NoSuchMethodError: android.view.View.setZ
だから、その選択肢もアウトです。
編集 3 - 解決策
この問題に対する私の解決策については、以下の回答を参照してください (を使用getChildDrawingOrder
)。
そうは言っても、私はまだbringToFront
仕事に取り掛かることができず、あなたがそれを理解できれば、喜んであなたの答えを選択されたものとして選択します.
よろしくお願いします。