仿Twitter登陆移动背景效果

有使用Twitter客户端的朋友应该有发现在登录的时候,屏幕上方和下方的云朵图片是不断移动着的,再加上Twitter那支可爱的小鸟在不停的动着,给人的感觉就好像是小鸟在飞翔一样,感觉效果很不错。

我也试着实现了一下,发现使用自定义的Drawable加上线程,还是比较容易实现的。下面是自定义Drawable的代码,注释已经写的很详细了。这里是使用了三张图片,使用一张图就更简单了,大家完全可以举一反三,实现自己的动画图片效果。

package com.liuzhichao.dynamicdrawable;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.drawable.Drawable;
import android.util.DisplayMetrics;
import android.view.View;

public class DynamicDrawable extends Drawable implements Runnable {

    private static Bitmap mBottomBgBitmap;   //底部大图  
    private static Bitmap mBottomFgBitmap;   // 底部小图 
    private static Bitmap mTopBitmap;      //顶部云图片

    private final int dispalyWidth;       //手机屏幕宽度
    private final int dispalyHeight;     //手机屏幕高度
    private float mBottomBgTop;             //顶部大图显示的位置
    private float mBottomFgTop;            //顶部小图显示的位置    

    private int startX;                //顶部云图片和底部大图移动偏移变量
    private int mBottomFgStartX;       //底部小图移动偏移变量
    private View mView;

    public DynamicDrawable(Activity activity, View mView) {
        this.mView = mView;

        if (mTopBitmap == null) {
            mTopBitmap = BitmapFactory.decodeResource(activity.getResources(),
                    R.drawable.cloud_top_bg);
        }
        if (mBottomBgBitmap == null) {
            mBottomBgBitmap = BitmapFactory.decodeResource(
                    activity.getResources(), R.drawable.cloud_bottom_bg);
        }
        if (mBottomFgBitmap == null) {
            mBottomFgBitmap = BitmapFactory.decodeResource(
                    activity.getResources(), R.drawable.cloud_bottom_fg);
        }

        //获取屏幕高度和宽度
        DisplayMetrics dm = new DisplayMetrics();
        dm = activity.getResources().getDisplayMetrics();
        this.dispalyHeight = dm.heightPixels;
        this.dispalyWidth = dm.widthPixels;

        //顶部图片显示的位置  = 屏幕高度 - 图片自身高 - 标题高度
        this.mBottomBgTop = dispalyHeight - mBottomBgBitmap.getHeight() - 100;
        this.mBottomFgTop = dispalyHeight - mBottomFgBitmap.getHeight() - 100;

        //开始移动图片线程
        new Thread(this).start();
    }

    @Override
    public void draw(Canvas canvas) {
        // drawBitmap (Bitmap bitmap, float left, float top, Paint paint)
        canvas.drawBitmap(mTopBitmap, startX, 0, null);
        canvas.drawBitmap(mBottomBgBitmap, startX, mBottomBgTop, null);
        canvas.drawBitmap(mBottomFgBitmap, mBottomFgStartX, mBottomFgTop, null);
    }

    @Override
    public int getOpacity() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public void setAlpha(int arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void setColorFilter(ColorFilter arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            //900 是图片的长度
            //如果移动偏量已经大于图片的长度 - 屏幕宽度,则说明已经移动到了图片的末端,如果继续移动,则会显示空白
            //所以将startX重新赋予0,让图片重新开始移动
            //但是这样过渡效果会比较明显,再切换的那一刹那,会明显感觉图片变化较大
            if (startX + (900 - dispalyWidth) == 0) {
                startX = 0;
            } else {
                startX -= 1;
            }

            //底部小图的移动,
            // -=2 是让小图移动的比大图快,造成不同的视觉效果
            if (mBottomFgStartX + (900 - dispalyWidth) == 0) {
                mBottomFgStartX = 0;
            } else {
                mBottomFgStartX -= 2;
            }
            try {
                //每 1/10秒移动一次
                Thread.sleep(100L);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            //刷新界面
            mView.postInvalidate();
        }

    }

}

然后在需要背景图的地方,直接setBackgroundDrawable就可以了,下面的background是整个布局文件的id。

private View background;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        background = findViewById(android.R.id.background);
        background.setBackgroundDrawable(new DynamicDrawable(this, background));
    }

布局文件也还是贴出来吧:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@android:id/background" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:padding="@dimen/padding_medium"
        android:text="@string/hello_world"
        tools:context=".MainActivity" />

</RelativeLayout>

还是截张图吧,虽然看不到动画效果。

技术分享

 

本文转自:http://liuzhichao.com/p/659.html

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。