Android 超级萌的猫头鹰登录界面

  最近在网上看到了一个比较不错的登录界面,效果如下图:


  是不是很好玩;后来研究了一下,主要是通过自定义的View加上动画实现的,先看代码:

  首先是自定义View:

 public class OwlView extends View {
    private Context mContext;
    private Bitmap bm_owl;
    private Bitmap bm_owl_arm_left;
    private Bitmap bm_owl_arm_right;
    private int bm_height;
    private int moveHeight;
    private int alpha = 255;

    private int move_length = 0;
    private Paint handPaintBefore;
    private Paint handPaintAfter;

    public OwlView(Context context) {
        this(context, null);
    }

    public OwlView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public OwlView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        init();
    }

    private void init() {
        setBackgroundColor(Color.TRANSPARENT);
        getViewTreeObserver().addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        getViewTreeObserver()
                                .removeGlobalOnLayoutListener(this);
                        ViewGroup.LayoutParams lp = getLayoutParams();
                        if (lp == null)
                            return;
                        lp.width = dip2px(175);
                        lp.height = dip2px(107);
                        setLayoutParams(lp);
                        setTranslationY(dip2px(9));
                    }
                });

        bm_owl = BitmapFactory.decodeResource(getResources(),
                R.drawable.owl_login);
        bm_owl_arm_left = BitmapFactory.decodeResource(getResources(),
                R.drawable.owl_login_arm_left);
        bm_owl_arm_right = BitmapFactory.decodeResource(getResources(),
                R.drawable.owl_login_arm_right);

        bm_owl = compressBitmap(bm_owl, dip2px(115), dip2px(107), false);
        bm_owl_arm_left = compressBitmap(bm_owl_arm_left, dip2px(40),
                dip2px(65), true);
        bm_owl_arm_right = compressBitmap(bm_owl_arm_right, dip2px(40),
                dip2px(65), true);

        bm_height = bm_owl_arm_left.getHeight() / 3 * 2 - dip2px(10);

        handPaintBefore = new Paint();
        handPaintBefore.setColor(Color.parseColor("#472d20"));
        handPaintBefore.setAntiAlias(true);

        handPaintAfter = new Paint();
        handPaintAfter.setAntiAlias(true);

    }

    public void close() {
        ValueAnimator alphaVa = ValueAnimator.ofInt(0, 255).setDuration(300);
        alphaVa.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                alpha = (Integer) animation.getAnimatedValue();
                invalidate();
            }
        });
        alphaVa.start();
        ValueAnimator moveVa = ValueAnimator.ofInt(dip2px(45), 0).setDuration(
                200);
        moveVa.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                move_length = (Integer) animation.getAnimatedValue();
                invalidate();
            }
        });
        moveVa.setStartDelay(200);
        moveVa.start();
        ValueAnimator va = ValueAnimator.ofInt(bm_height, 0).setDuration(300);
        va.setInterpolator(new LinearInterpolator());
        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                moveHeight = (Integer) animation.getAnimatedValue();
                invalidate();
            }
        });
        va.start();
    }

    public void open() {
        final ValueAnimator alphaVa = ValueAnimator.ofInt(255, 0).setDuration(
                300);
        alphaVa.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                alpha = (Integer) animation.getAnimatedValue();
                invalidate();

            }
        });
        alphaVa.start();
        ValueAnimator moveVa = ValueAnimator.ofInt(0, dip2px(45)).setDuration(
                200);
        moveVa.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                move_length = (Integer) animation.getAnimatedValue();
                invalidate();
            }
        });
        moveVa.start();

        ValueAnimator va = ValueAnimator.ofInt(0, bm_height).setDuration(300);
        va.setInterpolator(new LinearInterpolator());
        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                moveHeight = (Integer) animation.getAnimatedValue();
                invalidate();
            }
        });
        va.setStartDelay(100);
        va.start();

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(
                bm_owl,
                new Rect(0, 0, bm_owl.getWidth(), bm_owl.getHeight()),
                new Rect(dip2px(30), 0, dip2px(30) + bm_owl.getWidth(), bm_owl
                        .getHeight()), handPaintAfter);

        handPaintBefore.setAlpha(alpha);
        canvas.drawOval(new RectF(moveHeight, getHeight() - dip2px(20),
                move_length + dip2px(30), getHeight()), handPaintBefore);
        canvas.drawOval(
                new RectF(getWidth() - dip2px(30) - move_length, getHeight()
                        - dip2px(20), getWidth() - move_length, getHeight()),
                handPaintBefore);

        canvas.drawBitmap(bm_owl_arm_left,// Bitmap
                new Rect(0,// left
                        0,// top
                        bm_owl_arm_left.getWidth(),// right
                        moveHeight),// bottom
                new Rect(dip2px(43), getHeight() - moveHeight - dip2px(10),
                        dip2px(43) + bm_owl_arm_left.getWidth(), getHeight()
                                - dip2px(9)), handPaintAfter);// Paint
        // canvas.drawBitmap(Bitmap,Rect,Rect,Paint)
        canvas.drawBitmap(bm_owl_arm_right,// Bitmap
                new Rect(0,// left
                        0,// top
                        bm_owl_arm_right.getWidth(),// right
                        moveHeight),// bottom
                new Rect(getWidth() - dip2px(40) - bm_owl_arm_right.getWidth(),// left
                        getHeight() - moveHeight - dip2px(10),// top
                        getWidth() - dip2px(40),// right
                        getHeight() - dip2px(9)),// bottom
                handPaintAfter);// Paint
    }

    /**
     * 压缩图片
     *
     * @param bitmap
     * @param reqsW
     * @param reqsH
     * @param isAdjust
     * @return
     */
    private Bitmap compressBitmap(Bitmap bitmap, int reqsW, int reqsH,
            boolean isAdjust) {
        if (bitmap == null || reqsW == 0 || reqsH == 0)
            return bitmap;
        if (bitmap.getWidth() > reqsW || bitmap.getHeight() > reqsH) {
            /**
             * BigDecimal用法详解
             *
             * 由于NumberFormat类的format()方法可以使用BigDecimal对象作为其参数,
             * 可以利用BigDecimal对超出16位有效数字的货币值,百分值,以及一般数值进行格式化控制。
             * 以利用BigDecimal对货币和百分比格式化为例
             * 。首先,创建BigDecimal对象,进行BigDecimal的算术运算后,分别建立对货币和百分比格式化的引用
             * ,最后利用BigDecimal对象作为format()方法的参数,输出其格式化的货币值和百分比。
             */
            float scaleX = new BigDecimal(reqsW).divide(
                    new BigDecimal(bitmap.getWidth()), 4, RoundingMode.DOWN)
                    .floatValue();
            float scaleY = new BigDecimal(reqsH).divide(
                    new BigDecimal(bitmap.getHeight()), 4, RoundingMode.DOWN)
                    .floatValue();
            if (isAdjust) {
                scaleX = scaleX < scaleY ? scaleX : scaleY;
                scaleY = scaleX;
            }
            Matrix matrix = new Matrix();
            matrix.postScale(scaleX, scaleY);

            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                    bitmap.getHeight(), matrix, true);
        }
        return bitmap;
    }

    private int dip2px(int dpValue) {
        float scale = mContext.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);

    }
}


然后界面:

<FrameLayout 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:background="#008ECB" >

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="140dp"
        android:layout_marginTop="107dp"
        android:background="@drawable/bg_layout">"

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="140dp"
            android:orientation="vertical" >

            <EditText
                android:id="@+id/uname"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:layout_marginTop="10dp"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp"
                android:layout_marginBottom="5dp"
                android:background="@drawable/bg_edittext"
                android:hint="请输入账号"
                android:paddingLeft="10dp" />

            <EditText
                android:id="@+id/upwd"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:layout_marginTop="10dp"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp"
                android:layout_marginBottom="5dp"
                android:password="true"
                android:background="@drawable/bg_edittext"
                android:hint="请输入密码"
                android:paddingLeft="10dp" />
        </LinearLayout>
    </FrameLayout>

    <com.example.logindemo.OwlView
        android:id="@+id/owl"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center_horizontal" >
    </com.example.logindemo.OwlView>

</FrameLayout>


最后就是在activity里给两个Editext加监听了:

public class MainActivity extends Activity {
    private EditText uname, upwd;
    private OwlView owl;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        uname = (EditText) findViewById(R.id.uname);
        upwd = (EditText) findViewById(R.id.upwd);
        owl = (OwlView) findViewById(R.id.owl);
        uname.setOnFocusChangeListener(new OnFocusChangeListener() {

            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                // TODO Auto-generated method stub
                if (hasFocus) {

                    owl.close();
                }
            }
        });
        upwd.setOnFocusChangeListener(new OnFocusChangeListener() {

            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                // TODO Auto-generated method stub
                if (hasFocus) {
                    owl.open();
                }
            }
        });
    }
}


 附上项目下载地址:http://download.csdn.net/detail/stephenzml/9889642


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值