之前有同事用格瓦拉买电影票,自己下了一个看了看,App整体做的比较炫酷,看到一个效果挺不错,又在自己的能力范围之内,就模仿一下。下面是效果图:
就是一连串的电影胶片不停的向某一方向滑动,思路:
取两张背景图,同时向一个方向滑动,当超出屏幕范围时重新调整两张图的横坐标即可。
代码如下:
/**
* @description 仿格瓦拉App背景自动移动View
* @author rzq
* @date 2015年9月29日
*/
public class AutomaticMoveView extends View
{
/**
* 默认常量
*/
private static final int DIRECTION = 1;
private static final int SPEED = 5;
private static final float ALPHA = 0.5f;
/**
* 公共变量
*/
private Context mContext;
private DisplayMetrics dm;
private int screenWidth;
/**
* 背景移动方向
*/
private MoveDirection mDirection;
/**
* 循环移动的背景
*/
private Bitmap mBackgroundOne, mBackgroundTwo;
/**
* 遮罩层透明度百分比
*/
private float mAlpha;
/**
* 循环移动的速度
*/
private float mSpeed;
/**
* 两张轮播图的的横坐标
*/
private float x1, x2;
private int mBgOneWidth, mBgOneHeight;
private int mBgTwoWidth;
private Handler mHandler = new Handler()
{
public void handleMessage(Message msg)
{
x1 += mSpeed;
x2 += mSpeed;
switch (mDirection)
{
case RIGHT:
if (x1 >= screenWidth)
{
x1 = x2 - mBgOneWidth;
}
if (x2 >= screenWidth)
{
x2 = x1 - mBgTwoWidth;
}
break;
case LEFT:
if (x1 <= -mBgOneWidth)
{
x1 = x2 + mBgTwoWidth;
}
if (x2 <= -mBgTwoWidth)
{
x2 = x1 + mBgOneWidth;
}
break;
}
invalidate();
mHandler.sendEmptyMessageDelayed(0, 100);
};
};
public AutomaticMoveView(Context context, AttributeSet attrs)
{
super(context, attrs);
mContext = context;
TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.AutomicMove);
Drawable drawableOne = a.getDrawable(R.styleable.AutomicMove_auto_background_one);
Drawable drawableTwo = a.getDrawable(R.styleable.AutomicMove_auto_background_two);
if (drawableOne instanceof BitmapDrawable && drawableTwo instanceof BitmapDrawable)
{
mBackgroundOne = ((BitmapDrawable) drawableOne).getBitmap();
mBackgroundTwo = ((BitmapDrawable) drawableTwo).getBitmap();
}
mDirection = a.getInt(R.styleable.AutomicMove_auto_direction, DIRECTION) == DIRECTION ? MoveDirection.LEFT
: MoveDirection.RIGHT;
mSpeed = a.getDimension(R.styleable.AutomicMove_auto_speed, SPEED);
mAlpha = a.getFloat(R.styleable.AutomicMove_auto_alpha, ALPHA);
a.recycle();
init();
}
private void init()
{
dm = new DisplayMetrics();
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(dm);
screenWidth = dm.widthPixels;
mBgOneWidth = mBackgroundOne.getWidth();
mBgOneHeight = mBackgroundOne.getHeight();
mBgTwoWidth = mBackgroundTwo.getWidth();
switch (mDirection)
{
case RIGHT:
x1 = screenWidth - mBgOneWidth;
x2 = screenWidth - mBgOneWidth - mBgTwoWidth;
break;
case LEFT:
mSpeed *= -1;
x1 = 0;
x2 = mBgOneWidth;
break;
}
mHandler.sendEmptyMessageDelayed(0, 0);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
/**
* 指定View的宽度为屏幕宽度,高度为背景高度。
*/
int viewHeight = mBgOneHeight + getPaddingTop() + getPaddingBottom();
setMeasuredDimension(screenWidth, viewHeight);
}
@Override
protected void onDraw(Canvas canvas)
{
/**
* 绘制两张背景图
*/
canvas.drawBitmap(mBackgroundOne, x1, 0, null);
canvas.drawBitmap(mBackgroundTwo, x2, 0, null);
/**
* 绘制遮罩层
*/
canvas.drawARGB((int) (mAlpha * 255), 0, 0, 0);
}
@Override
protected void onDetachedFromWindow()
{
super.onDetachedFromWindow();
mBackgroundOne = null;
mBackgroundTwo = null;
}
/**
* 背景移动方向枚举
*/
public enum MoveDirection
{
LEFT, RIGHT;
}
}
代码也不复杂,变量的作用都注释好了。有需要的可以参考。