來復原動的背景在Android在Android 可謂是很常見了,今天自己寫了一個,有參考别人的代碼,修複了記憶體洩露問題,marqueeImage會根據view大小和背景圖的大小選則是橫向滾動還是豎着滾動,如果寫的有什麼不足或者漏洞歡迎批評指正,如果覺得寫的好的話,支付寶走一波哈哈,自己寫的一些view 也會繼續更新 謝謝大家 嘿嘿
拷貝下面的代碼和attr.xml檔案到項目中就可以用了
public class MarqueeImageView extends View {
private static final String TAG = "MarqueeImageView";
//region
private Thread thread = new Thread(
new Runnable() {
@Override
public void run() {
while (start) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendEmptyMessage(0x123);
}
}
}
);
//endregion
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0x123:
invalidate();//重繪
break;
}
}
};
private boolean start = true;//用來記錄是否滾動
enum DirectionEnum {
left, right,up,down//方向枚舉
}
enum Orientation{
horizontal, vertical//水準,垂直
}
private Bitmap background = null;
private int nowX = 0, nowY = 0;
private int backWidth, backHeight;//背景圖寬,高
private int time = 40;
private int MViewHeight = 0,MViewWidth = 0;
private Orientation orientation;//方向
private int speed;//速度
private DirectionEnum direction = DirectionEnum.left;//向左
public MarqueeImageView(Context context) {
super(context);
}
public MarqueeImageView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
getAttr(attrs);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
MViewHeight = h;
MViewWidth = w;
init();
}
public void init() {
int h = background.getHeight();
int w = background.getWidth();
Log.d(TAG, "init: h" + h);
Log.d(TAG, "init: w" + w);
Log.d(TAG, "init: (float)(w/MViewWidth) " + (float)(w/MViewWidth));
//水準滾動
if ((float)(w/MViewWidth) > (float)(h/MViewHeight)){
orientation = Orientation.horizontal;
int imageW = (int) ((float) MViewHeight/ h * w);
Log.d(TAG, "init: imageW" + imageW);
background = Bitmap.createScaledBitmap(background, imageW, MViewHeight, true);
backWidth = background.getWidth();//背景寬
Log.d(TAG, "start: backWidth" + backWidth);
}
else {
orientation = Orientation.vertical;//那就垂直滾動吧
int imageH = (int) ((float)MViewWidth/w * h);
Log.d(TAG, "init: imageH " + imageH);
background = Bitmap.createScaledBitmap(background, MViewWidth, imageH, true);
backHeight = background.getHeight();//背景圖寬
Log.d(TAG, "init: backHeight " + backHeight);
}
start();//調用下這個方法
}
public void start() {
start = true;
handler.sendEmptyMessage(0x123);
thread.start();
}
private void getAttr(AttributeSet attrs) {
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.MarqueeImageView);
speed = typedArray.getInteger(R.styleable.MarqueeImageView_speed, 1);
time = typedArray.getInteger(R.styleable.MarqueeImageView_time, 40);
int resourceId = typedArray.getResourceId(R.styleable.MarqueeImageView_image, R.drawable.marquee_task);
background = BitmapFactory.decodeResource(getResources(), resourceId);
typedArray.recycle();
}
@Override
protected void onDraw(Canvas canvas) {
if (background == null) //如果背景圖為空直接傳回
return;
//如果是水準滾動
if (orientation == Orientation.horizontal){
if (nowX <= 0) {
nowX += speed;
direction = DirectionEnum.left;//向左移動
}
else if (nowX >= backWidth - MViewWidth - speed) {
nowX -= speed;
direction = DirectionEnum.right;//左邊走到頭開始向又走
}
else {
if (direction == DirectionEnum.right) {
nowX -= speed;
} else {
nowX += speed;
}
}
}
else{
if (nowY <= 0) {
nowY += speed;
direction = DirectionEnum.up;//向上
} else if (nowY >= backHeight - MViewHeight - speed) {
nowY -= speed;//減去速度
direction = DirectionEnum.down;//向下移動
} else {
if (direction == DirectionEnum.up)//如果方向是向上
nowY += speed;
else
nowY -= speed;
}
}
//當水準滾動時,nowY為0, 垂直滾動時nowX為0
Bitmap bitmap = Bitmap.createBitmap(background, nowX, nowY, MViewWidth, MViewHeight);
canvas.drawBitmap(bitmap, 0, 0, null);
Log.d(TAG, "onDraw: ");
}
//從視窗分離出來
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
Log.d(TAG, "onDetachedFromWindow: ");
start = false;//線程就不要執行了
}
}
attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MarqueeImageView">
<attr name="speed" format="integer">
</attr>
<!--背景圖-->
<attr name="image" format="reference"></attr>
<attr name="time" format="integer"></attr>
</declare-styleable>
</resources>
MarqueeImageView 如果不指定的話預設會有一個背景圖名稱為 marquee_task.jpg,記得放在drawable檔案夾内
如果你覺得寫的好的話,支付包走一波喽,嘿嘿