一直以来 android 的碎片化 和 种种原因 , 导致大部分的 Android App 设计起来干脆跟 ios 同步 . 在 ios 上可以轻易实现的风格和效果 在 Android 这边实现起来相当复杂 , Google 在 14年的 I/O 大会上 重磅发布的 Material Desgin , 随着近两年的发展 Material Desgin 的设计风格已经融入越来越多的 App , 也被越来越多的 Android 开发者所接受和钟爱。笔者收集收录国内外各大 Material Desgin 风格的 widget 对它们的效果和使用做分享(如果有版权或者所有权相关冲突可在下方留言或者发私信联系笔者)

MaterialTextField

效果:

MaterialDesgin之MaterialTextField_第1张图片

一个 MaterialDesgin风格带动画的EditView 用在注册登陆界面 第一次看到也能给人眼前一亮的感觉

使用

code:

package com.materialdesignam.widget;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Color;import android.support.v7.widget.CardView;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.inputmethod.InputMethodManager;import android.widget.EditText;import android.widget.FrameLayout;import android.widget.ImageView;import android.widget.TextView;import com.materialdesignam.R;import com.nineoldandroids.animation.AnimatorSet;import com.nineoldandroids.animation.ObjectAnimator;import com.nineoldandroids.animation.ValueAnimator;import com.nineoldandroids.view.ViewHelper;/** * Copyright 2015 florent37, Inc. * <p/> * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * <p/> * http://www.apache.org/licenses/LICENSE-2.0 * <p/> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * https://github.com/florent37/MaterialTextField *//** * Created by florentchampigny on 27/08/15. */public class MaterialTextField extends FrameLayout {    protected TextView label;    protected View card;    protected ImageView image;    protected EditText editText;    protected ViewGroup editTextLayout;    protected int labelTopMargin = -1;    protected boolean expanded = false;    protected int ANIMATION_DURATION = -1;    protected boolean OPEN_KEYBOARD_ON_FOCUS = true;    protected int labelColor = -1;    protected int cardColor = -1;    protected int imageDrawableId = -1;    protected int cardCollapsedHeight = -1;    protected void handleAttributes(Context context, AttributeSet attrs) {        try {            TypedArray styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.MaterialTextField);            {                ANIMATION_DURATION = styledAttrs.getInteger(R.styleable.MaterialTextField_mtf_animationDuration, 400);            }            {                OPEN_KEYBOARD_ON_FOCUS = styledAttrs.getBoolean(R.styleable.MaterialTextField_mtf_openKeyboardOnFocus, false);            }            {                labelColor = styledAttrs.getColor(R.styleable.MaterialTextField_mtf_labelColor, -1);            }            {                cardColor = styledAttrs.getColor(R.styleable.MaterialTextField_mtf_cardColor, -1);            }            {                imageDrawableId = styledAttrs.getResourceId(R.styleable.MaterialTextField_mtf_image, -1);            }            {                cardCollapsedHeight = styledAttrs.getDimensionPixelOffset(R.styleable.MaterialTextField_mtf_cardCollapsedHeight, context.getResources().getDimensionPixelOffset(R.dimen.mtf_cardHeight_initial));            }            cardCollapsedHeight += context.getResources().getDimensionPixelOffset(R.dimen.mtf_cardview_additionnal);            styledAttrs.recycle();        } catch (Exception e) {            e.printStackTrace();        }    }    public MaterialTextField(Context context) {        super(context);    }    public MaterialTextField(Context context, AttributeSet attrs) {        super(context, attrs);        handleAttributes(context, attrs);    }    public MaterialTextField(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        handleAttributes(context, attrs);    }    protected EditText findEditTextChild() {        if (getChildCount() > 0 && getChildAt(0) instanceof EditText) {            return (EditText) getChildAt(0);        }        return null;    }    @Override    protected void onFinishInflate() {        super.onFinishInflate();        editText = findEditTextChild();        if (editText == null)            return;        addView(LayoutInflater.from(getContext()).inflate(R.layout.mtf_layout, this, false));        editTextLayout = (ViewGroup) findViewById(R.id.mtf_editTextLayout);        removeView(editText);        editTextLayout.addView(editText);        label = (TextView) findViewById(R.id.mtf_label);        ViewHelper.setPivotX(label, 0);        ViewHelper.setPivotY(label, 0);        if (editText.getHint() != null) {            label.setText(editText.getHint());            editText.setHint("");        }        card = findViewById(R.id.mtf_card);        card.getLayoutParams().height = cardCollapsedHeight;        card.requestLayout();        image = (ImageView) findViewById(R.id.mtf_image);        ViewHelper.setAlpha((View) image, 0);        ViewHelper.setScaleX(image, 0.4f);        ViewHelper.setScaleY(image, 0.4f);        ViewHelper.setAlpha(editText, 0f);        editText.setBackgroundColor(Color.TRANSPARENT);        labelTopMargin = FrameLayout.LayoutParams.class.cast(label.getLayoutParams()).topMargin;        customizeFromAttributes();        this.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                toggle();            }        });    }    protected void customizeFromAttributes() {        if (labelColor != -1) {            this.label.setTextColor(labelColor);        }        if (cardColor != -1) {            if (card instanceof CardView)                CardView.class.cast(this.card).setCardBackgroundColor(cardColor);        }        if (imageDrawableId != -1) {            this.image.setImageDrawable(getContext().getResources().getDrawable(imageDrawableId));        }    }    public void toggle() {        if (expanded)            reduce();        else            expand();    }    public void reduce() {        if (expanded) {            ValueAnimator expand = ValueAnimator.ofInt(card.getHeight(), cardCollapsedHeight);            expand.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                @Override                public void onAnimationUpdate(ValueAnimator animation) {                    Integer value = (Integer) animation.getAnimatedValue();                    card.getLayoutParams().height = value.intValue();                    card.requestLayout();                }            });            AnimatorSet animatorSet = new AnimatorSet();            animatorSet.setDuration(ANIMATION_DURATION);            animatorSet.playTogether(                    ObjectAnimator.ofFloat(label, "alpha", 1),                    ObjectAnimator.ofFloat(label, "scaleX", 1),                    ObjectAnimator.ofFloat(label, "scaleY", 1),                    ObjectAnimator.ofFloat(label, "translationY", 0),                    ObjectAnimator.ofFloat(image, "alpha", 0),                    ObjectAnimator.ofFloat(image, "scaleX", 0.4f),                    ObjectAnimator.ofFloat(image, "scaleY", 0.4f),                    ObjectAnimator.ofFloat(editText, "alpha", 0),                    expand            );            animatorSet.start();            if (OPEN_KEYBOARD_ON_FOCUS)                ((InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE)).toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);            editText.clearFocus();            expanded = false;        }    }    public void expand() {        if (!expanded) {            ValueAnimator expand = ValueAnimator.ofInt(0, getContext().getResources().getDimensionPixelOffset(R.dimen.mtf_cardHeight_final));            expand.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                @Override                public void onAnimationUpdate(ValueAnimator animation) {                    Integer value = (Integer) animation.getAnimatedValue();                    card.getLayoutParams().height = value.intValue();                    card.requestLayout();                }            });            AnimatorSet animatorSet = new AnimatorSet();            animatorSet.setDuration(ANIMATION_DURATION);            animatorSet.playTogether(                    ObjectAnimator.ofFloat(label, "alpha", 0.4f),                    ObjectAnimator.ofFloat(label, "scaleX", 0.7f),                    ObjectAnimator.ofFloat(label, "scaleY", 0.7f),                    ObjectAnimator.ofFloat(label, "translationY", -labelTopMargin),                    ObjectAnimator.ofFloat(image, "alpha", 1),                    ObjectAnimator.ofFloat(image, "scaleX", 1),                    ObjectAnimator.ofFloat(image, "scaleY", 1),                    ObjectAnimator.ofFloat(editText, "alpha", 1),                    expand            );            animatorSet.start();            editText.requestFocus();            if (OPEN_KEYBOARD_ON_FOCUS)                ((InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);            expanded = true;        }    }    public View getCard() {        return card;    }    public TextView getLabel() {        return label;    }    public ImageView getImage() {        return image;    }    public EditText getEditText() {        return editText;    }    public ViewGroup getEditTextLayout() {        return editTextLayout;    }    public boolean isExpanded() {        return expanded;    }}

属性

    <declare-styleable name="MaterialTextField">        <attr name="mtf_cardCollapsedHeight" format="dimension" />        <attr name="mtf_labelColor" format="color" />        <attr name="mtf_cardColor" format="color" />        <attr name="mtf_image" format="reference" />        <attr name="mtf_animationDuration" format="integer" />        <attr name="mtf_openKeyboardOnFocus" format="boolean" />    </declare-styleable>

可以修改的宽高颜色动画速度可以自行参考上面属性

dependence:

 compile 'com.android.support:cardview-v7:23.1.0' compile 'com.nineoldandroids:library:2.4.0'

eclipse 的同学可以下载 jar 包导入

use:

    <com.materialdesignam.widget.MaterialTextField  android:layout_width="300dp" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginLeft="4dp" android:layout_marginRight="4dp" android:layout_marginTop="20dp" app:mtf_cardCollapsedHeight="4dp" app:mtf_image="@drawable/ic_mail_grey600_24dp">        <!-- app:mtf_animationDuration="1000" app:mtf_cardColor="@color/cardview_dark_background" app:mtf_labelColor="@android:color/holo_red_dark" app:mtf_openKeyboardOnFocus="true" -->        <EditText  android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Password" android:numeric="integer" android:textColor="#333" android:textColorHint="#666" android:textSize="15sp" />    </com.materialdesignam.widget.MaterialTextField>

示例项目地址: https://github.com/13120241790/MaterialDesginAM

更多相关文章

  1. CheckBox 设置style 没有效果的原因
  2. Android 浏览图片层叠放大效果(CoverFlow)
  3. Android 带阻尼回弹效果的ScorllView
  4. Android中摇一摇效果的实现
  5. Android翻页效果的实现原理
  6. 初学Android,FrameLayout霓虹灯效果(五)
  7. Android图像处理之冰冻效果
  8. android 幕滑动效果
  9. Android动画效果 Android Animation

随机推荐

  1. javascript实现查看html网页放大图片功能
  2. 原生javascript-图片弹窗交互效果
  3. Javascript学习之匿名函数与自执行详解
  4. 如何使用AngularJS获取url参数
  5. V8是谷歌开源的一个高性能JavaScript引擎
  6. 包含HTML和JavaScript标记的HTML选择控件
  7. 将输入文本字段显示为纯文本
  8. JS计算任意字符串宽度
  9. React-Native:从ListView中的列表项搜索
  10. 如何在选择单选按钮时显示文本字段