代码之家  ›  专栏  ›  技术社区  ›  Navaneeth Sen

可能有一个弯曲的走廊

  •  9
  • Navaneeth Sen  · 技术社区  · 16 年前

    是否可以更改Android Gallery的默认排列? 我的意思是,我们可以使画廊在一个弯曲的路径,其中的图像将沿着弯曲的路径,同时它拥有所有的Android画廊的属性?

    如果可能的话,请告诉我你的想法。欢迎提出任何意见。

    谢谢和问候, 森

    2 回复  |  直到 16 年前
        1
  •  12
  •   khendricks    15 年前

    将为每个需要绘制的子对象调用drawChild。

    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
    
        final int left = child.getLeft();
    
        int adjustedXOrigin = left - (getWidth() / 2) + (child.getWidth()/2);
    
        int newtop = (int) (ellipseYOffset - Math.sqrt( ellipseMinor2 * (1 - ((Math.pow(adjustedXOrigin, 2)) / ellipseMajor2))));
        newtop -= (child.getHeight() / 2);
    
        if( newtop >= 0 )
        {
            child.layout(left, newtop, left + child.getWidth(), newtop + child.getHeight());
            return super.drawChild(canvas, child, drawingTime);
        }
    
        return true;
    }
    

    在onLayout中,我计算椭圆偏移量。这将使中间选定的视图在视图中垂直居中,而不管椭圆大小如何。

    ellipseYOffset = getMeasuredHeight() + (ellipseMinor - (getMeasuredHeight() / 2));
    

    “if(newtop>=0)”部分是因为视图是在奇怪的地方随机绘制的。这就停止了。

    编辑:完整代码

    有一些动画的东西你不需要,我只是复制和粘贴我的类。

    public class Carousel extends Gallery {
    
    private static final float INITIAL_MINOR_RATIO = 0.75f;
    private static final float INITIAL_MAJOR_RATIO = 1.0f;
    
    private int mEllipseMajor;
    private int mEllipseMinor;
    private int mEllipseMajor2;
    private int mEllipseMinor2;
    private int mEllipseYOffset;
    
    private Animation mGalleryAlphaOut;
    private Animation mGalleryAlphaIn;
    
    private OnAnimationEndListener mFadeInEndListener;
    private OnAnimationEndListener mFadeOutEndListener;
    
    private boolean mCustomEllipseDim = false;
    
    private boolean mInfinite = true;
    
    private int mXOff = 0;
    
    private AnimationListener mFadeInAnimationListener = new AnimationListener() {
        public void onAnimationStart(Animation animation) {}
        public void onAnimationRepeat(Animation animation) {}
        public void onAnimationEnd(Animation animation) {
            if( mFadeInEndListener != null )
            {
                mFadeInEndListener.onAnimationEnd();
            }
        }
    };
    
    private AnimationListener mFadeOutAnimationListener = new AnimationListener() {
        public void onAnimationStart(Animation animation) {}
        public void onAnimationRepeat(Animation animation) {}
        public void onAnimationEnd(Animation animation) {
            if( mFadeOutEndListener != null )
            {
                mFadeOutEndListener.onAnimationEnd();
            }
        }
    };
    
    public Carousel(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }
    
    public Carousel(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    
    public Carousel(Context context) {
        super(context);
        init();
    }
    
    private void init()
    {
        setHorizontalFadingEdgeEnabled(false);
        setCallbackDuringFling(true);
        setUnselectedAlpha(1.0f);
        setHapticFeedbackEnabled(false);
    
        int dur = getResources().getInteger(R.integer.transition_dur);
    
        mGalleryAlphaOut = AnimationUtils.loadAnimation(getContext(), android.R.anim.fade_out);
        mGalleryAlphaOut.setFillAfter(true);
        mGalleryAlphaOut.setDuration(dur);
        mGalleryAlphaOut.setAnimationListener(mFadeOutAnimationListener);
        mGalleryAlphaIn = AnimationUtils.loadAnimation(getContext(), android.R.anim.fade_in);
        mGalleryAlphaIn.setFillAfter(true);
        mGalleryAlphaIn.setDuration(dur);
        mGalleryAlphaIn.setAnimationListener(mFadeInAnimationListener);
    }
    
    public int getEllipseMajor() {
        return mEllipseMajor;
    }
    
    public void setEllipseMajor(int ellipseMajor) {
        if( ellipseMajor == 0 )
        {
            mCustomEllipseDim = false;
        }
        this.mEllipseMajor = ellipseMajor;
    }
    
    public int getEllipseMinor() {
        return mEllipseMinor;
    }
    
    public void setEllipseMinor(int ellipseMinor) {
        if( ellipseMinor == 0 )
        {
            mCustomEllipseDim = false;
        }
        this.mEllipseMinor = ellipseMinor;
    }
    
    @Override
    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
        final int left = child.getLeft();
        final int childWidth = child.getWidth();
        final int childHeight = child.getHeight();
    
        int adjustedXOrigin = left - mXOff + (childWidth>>1);
    
        int newtop = (int) (mEllipseYOffset - Math.sqrt( mEllipseMinor2 * (1 - ((Math.pow(adjustedXOrigin, 2)) / mEllipseMajor2))));
        newtop -= (childHeight>>1);
    
        if( newtop >= 0 )
        {
            child.layout(left, newtop, left + childWidth, newtop + childHeight);
            return super.drawChild(canvas, child, drawingTime);
        }
        return true;
    }
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if( !mCustomEllipseDim )
        {
            mEllipseMajor = (int) (getMeasuredWidth() * INITIAL_MAJOR_RATIO + 0.5f);
            mEllipseMinor = (int) (getMeasuredHeight() * INITIAL_MINOR_RATIO + 0.5f);
            mEllipseMajor2 = (int) Math.pow( mEllipseMajor, 2 );
            mEllipseMinor2 = (int) Math.pow( mEllipseMinor, 2 );
        }
        mEllipseYOffset = getMeasuredHeight() + (mEllipseMinor - (getMeasuredHeight() / 2));
    
        mXOff = (getWidth() / 2);
    }
    
    @Override
    public void setAdapter(SpinnerAdapter adapter) {
        super.setAdapter(adapter);
        if( mInfinite )
        {
            resetPosition();
        }
    }
    
    public void resetPosition()
    {
        int pos = Integer.MAX_VALUE / 2;
        if( getAdapter() != null && getAdapter().getClass() == CarouselAdapter.class )
        {
            int size = ((CarouselAdapter)getAdapter()).getList().size();
            if( size > 2 )
                pos = pos - (pos % ((CarouselAdapter)getAdapter()).getList().size());
            else
                pos = 0;
            setSelection(pos);
        }
    }
    
    public OnAnimationEndListener getFadeInEndListener() {
        return mFadeInEndListener;
    }
    
    public void setFadeInEndListener(OnAnimationEndListener fadeInEndListener) {
        this.mFadeInEndListener = fadeInEndListener;
    }
    
    public OnAnimationEndListener getFadeOutEndListener() {
        return mFadeOutEndListener;
    }
    
    public void setFadeOutEndListener(OnAnimationEndListener fadeOutEndListener) {
        this.mFadeOutEndListener = fadeOutEndListener;
    }
    
    public void fadeIn()
    {
        startAnimation(mGalleryAlphaIn);
    }
    
    public void fadeOut()
    {
        startAnimation(mGalleryAlphaOut);
    }
    
    public interface OnAnimationEndListener
    {
        public abstract void onAnimationEnd();
    }
    
    //This disables the effect of a vehicle becoming focused when it is clicked.
    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        if( getAdapter() != null )
        {
            if( pointToPosition((int)e.getX(), (int)e.getY()) != getSelectedItemPosition() )
                return true;
            else
                return super.onSingleTapUp(e);
        }
        else
            return true;
    }
    }
    
        2
  •  6
  •   Abi    16 年前

    我认为安卓没有提供改变画廊水平排列的条款。尽管我们可以让它垂直。如果你想要一个弯曲的画廊类型的看法,我认为有可能从头开始

    谢谢 Abi公司