Mở rộng Gallery và ghi đè drawChild.
drawChild sẽ được gọi cho mỗi đứa trẻ cần được rút ra.
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;
}
Trong onLayout tôi tính toán ellipseYOffset. Điều này đặt giữa chế độ xem ở giữa được chọn theo chiều dọc trong chế độ xem, bất kể kích thước hình elip.
ellipseYOffset = getMeasuredHeight() + (ellipseMinor - (getMeasuredHeight()/2));
Phần "if (newtop> = 0)" là do chế độ xem được rút ngẫu nhiên ở những nơi lạ. Điều này dừng lại.
Chỉnh sửa: mã đầy đủ
Có một số hoạt ảnh mà bạn không cần, tôi vừa sao chép và dán lớp của mình.
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;
}
}
hiii bạn có thể chia sẻ mã của bạn vì vậy tôi cũng có thể thực hiện trong bộ sưu tập của tôi cong – Mahesh