MaterialDesgin之MaterialTextField
16lz
2021-01-23
一直以来 android 的碎片化 和 种种原因 , 导致大部分的 Android App 设计起来干脆跟 ios 同步 . 在 ios 上可以轻易实现的风格和效果 在 Android 这边实现起来相当复杂 , Google 在 14年的 I/O 大会上 重磅发布的 Material Desgin , 随着近两年的发展 Material Desgin 的设计风格已经融入越来越多的 App , 也被越来越多的 Android 开发者所接受和钟爱。笔者收集收录国内外各大 Material Desgin 风格的 widget 对它们的效果和使用做分享(如果有版权或者所有权相关冲突可在下方留言或者发私信联系笔者)
MaterialTextField
效果:
一个 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
更多相关文章
- CheckBox 设置style 没有效果的原因
- Android 浏览图片层叠放大效果(CoverFlow)
- Android 带阻尼回弹效果的ScorllView
- Android中摇一摇效果的实现
- Android翻页效果的实现原理
- 初学Android,FrameLayout霓虹灯效果(五)
- Android图像处理之冰冻效果
- android 幕滑动效果
- Android动画效果 Android Animation