9

Android でのクロスフェードに関して多くの質問がありますが、それらにはすべてアニメーションが含まれています。私の質問は、ViewPager の OnPageChangeListener を使用したクロスフェードについてです。

無制限の数のビューを持つことができる ViewPager がありますが、実際には約 6 または 7 ビューを使用します。そこにはあまり進んでいません。

ViewPager の各ビューには背景ビットマップがあり、ビューの残りの部分と一緒にスクロールするのではなく、固定して次の (または前の) ビューの背景とクロスフェードする必要があります。

これを実現するために、背景を分離して ArrayList に追加し、後でそれらを ImageViews に割り当てました。しかし、アクティビティが多数の ImageView で終わる可能性を危険にさらしたくないので、次の構造を考えました。

<FrameLayout 
    android:id="@+id/backgroundContainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/bottomImage"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:scaleType="center" />

    <ImageView
        android:id="@+id/middleImage"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:scaleType="center" />

    <ImageView
        android:id="@+id/topImage"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:scaleType="center" />

</FrameLayout>

次に、OnPageChangeListenerViewPager に a が割り当てられ、背景が ImageViews に割り当てられます。

@Override
public void onPageSelected(int position) {
    MyLog.i(TAG, "PAGE SELECTED: " + position);

    if(position == 0) {
        _bottomBackground.setImageBitmap(null);
        _topBackground.setImageBitmap(_backgroundStack.get(position+1));
    } else if (position == NUM_ITEMS-1) {
        _bottomBackground.setImageBitmap(_backgroundStack.get(position-1));
        _topBackground.setImageBitmap(null);
    } else {
        _bottomBackground.setImageBitmap(_backgroundStack.get(position-1));
        _topBackground.setImageBitmap(_backgroundStack.get(position+1));
    }

    _middleBackground.setImageBitmap(_backgroundStack.get(position));            

    // Make the top front background transparent 
    _topBackground.setAlpha(0f);
    _currentBackgroundPosition = position;
}

背景を交換したいだけなら、これでうまくいきます。ユーザーがViewPagerをスワイプしている間、背景が互いにクロスフェードするようにします。前方スクロールのフェードは機能していますが、後方スクロールのフェードがどういうわけか良い結果をもたらさない理由がわかりません。後方スクロール中に、中央の背景が下部の背景にフェードインする必要があります。

私は何かが欠けているのではないかと心配しています。下の背景のアルファを変更することはありませんが、ログの結果は常にgetAlpha()中央の背景とまったく同じ値を示します。

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    if(_currentBackgroundPosition == position) {
        // scroll forward
        _topBackground.setAlpha(positionOffset)
    } else {
        //scroll backward
        _middleBackground.setAlpha(positionOffset);               
    }

    MyLog.i(TAG, "Bottom BackgroundAlpha: " + _bottomBackground.getAlpha());
    MyLog.i(TAG, "Middle BackgroundAlpha: " + _middleBackground.getAlpha());
    MyLog.i(TAG, "Top BackgroundAlpha: " + _topBackground.getAlpha());
}

そして待って!修正方法が本当にわからないことがもう1つあります。前方スクロールフェードは機能していますが。バックグラウンドで非常に短いちらつきがあります。これは、メソッドの設定方法が原因で発生していると思いonPageSelectedます。

この動作を作成/修正する別の方法はありますか?

4

1 に答える 1