100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 【Android自定义View】 仿照腾讯漫画自定义Toast的实现

【Android自定义View】 仿照腾讯漫画自定义Toast的实现

时间:2018-07-07 06:39:00

相关推荐

【Android自定义View】 仿照腾讯漫画自定义Toast的实现

效果展示:

话不多说,先上效果图:

看完了效果,我们来分析一下如何实现,并且实现这个我们能学到什么。

如何实现:

仿照腾讯漫画的效果,实现toast从顶部出现,又从顶部消失,代码逻辑比较简单。只需要用到Android的补间动画。另外需要仿照原生的调用方法,一行代码实现调用,降低开发者学习成本。

学习目的:

主要是强调一个良好的封装和适配,在写这个控件的过程中充分理解Android补间动画,以及自定义View的使用。另外需要仿照原生的调用方法,一行代码实现调用。

代码结构:

代码非常简单,只需要两个类,一个ToastLayout继承自RelativeLayout,是一个自定义view,动画的逻辑可以写在里面。另外一个类则是ZToast,是暴露给开发者的类,里面有静态的方法将提供给开发者使用。另外还需要一个布局文件,自定义view将会使用到layout文件。

代码以及讲解:

首先是布局文件,比较简单,不做详细说明:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="/apk/res/android"android:id="@+id/rl_toast"android:background="#eb6056"android:layout_width="match_parent"android:layout_height="match_parent"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"><ImageViewandroid:layout_marginBottom="8dp"android:layout_alignParentBottom="true"android:id="@+id/iv_icon"android:layout_marginLeft="20dp"android:layout_centerVertical="true"android:src="@mipmap/icon_toast"android:layout_width="wrap_content"android:layout_height="wrap_content" /><TextViewandroid:layout_marginBottom="5dp"android:layout_alignParentBottom="true"android:id="@+id/tv_content"android:layout_marginLeft="10dp"android:textSize="14dp"android:layout_toRightOf="@id/iv_icon"android:text="内容"android:textColor="#ffffff"android:layout_centerVertical="true"android:layout_width="wrap_content"android:layout_height="wrap_content" /></RelativeLayout></RelativeLayout>

ToastLayout:

package com.zhhr.custom;import android.content.Context;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.View;import android.view.animation.Animation;import android.view.animation.AnimationSet;import android.view.animation.TranslateAnimation;import android.widget.ImageView;import android.widget.RelativeLayout;import android.widget.TextView;import com.zhhr.R;/*** Created by 皓然 on /8/3.*/public class ToastLayout extends RelativeLayout {private static final int ANIMATION_TIME = 200;private TextView mContent;private View view;private boolean isShow;private RelativeLayout mWrapper;private ImageView mIcon;private int height;public boolean isShow() {return isShow;}public ToastLayout(Context context) {this(context, null);}public ToastLayout(Context context, AttributeSet attrs) {this(context, attrs, 0);}public ToastLayout(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);view = LayoutInflater.from(getContext()).inflate(R.layout.layout_toast, null);addView(view);mContent = view.findViewById(R.id.tv_content);mWrapper = view.findViewById(R.id.rl_toast);mIcon = view.findViewById(R.id.iv_icon);height = 60;}public void setTextColor(int color){mContent.setTextColor(color);}public void setBgColor(int color){mWrapper.setBackgroundColor(color);}public void setIconVisible(boolean isShow){if(isShow){mIcon.setVisibility(View.VISIBLE);}else {mIcon.setVisibility(View.GONE);}}public void setIcon(int resId){mIcon.setImageResource(resId);}public void setHeight(int height) {this.height = height;}public void setContent(String content){if(mContent!=null){mContent.setText(content);}}public void showToast(long time){AnimationSet animationSet = new AnimationSet(true);TranslateAnimation trans1 = new TranslateAnimation(0, 0 ,-dip2px(getContext(),height) ,0);TranslateAnimation trans2 = new TranslateAnimation(0,0 , 0 , -dip2px(getContext(),height));trans1.setDuration(ANIMATION_TIME);trans2.setStartOffset(ANIMATION_TIME+time);trans2.setDuration(ANIMATION_TIME);animationSet.addAnimation(trans1);animationSet.addAnimation(trans2);this.startAnimation(animationSet);animationSet.setAnimationListener(new Animation.AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {isShow = true;ToastLayout.this.setVisibility(View.VISIBLE);}@Overridepublic void onAnimationEnd(Animation animation) {isShow = false;ToastLayout.this.setVisibility(View.GONE);}@Overridepublic void onAnimationRepeat(Animation animation) {}});}/*** 将dip或dp值转换为px值,保证尺寸大小不变* @param context* @param dipValue* @return*/public static int dip2px(Context context, float dipValue) {float density = context.getResources().getDisplayMetrics().density;return (int) (dipValue * density + 0.5f);}}

主要在showToast方法里写了两个动画,这里用到了Android的补间动画,详细的说明可以参考博客Android开发——View动画、帧动画和属性动画详解,这里使用的是位移动画TranslationAnimation,分别设置了进入动画trans1和退出动画trans2,再通过动画的持续时间来控制toast的弹出和退出。

ZToast:

package com.zhhr.custom;import android.app.Activity;import android.view.ViewGroup;import android.widget.RelativeLayout;import com.zhhr.R;/*** Created by zhhr on /3/27.*/public class ZToast {private Activity mActivity;private RelativeLayout mToastLayout;private ToastLayout mToast;private ViewGroup mView;private String text;private long times;private static ZToast mToastInstance;/*** 固定参数*/public static final long LENGTH_LONG = 3000;public static final long LENGTH_SHORT = 1000;/*** 静态可设置参数*/public static int TextColor;public static int BgColor;public static boolean isShowIcon = true;public static int height = 60;public static int resId;/*** 设置小图标* @param resId*/public static void setResId(int resId) {ZToast.resId = resId;}/*** 设置高度* @param height*/public static void setHeight(int height) {ZToast.height = height;}/*** 图标是否显示* @param isShowIcon*/public static void setIsShowIcon(boolean isShowIcon) {ZToast.isShowIcon = isShowIcon;}/*** 背景色* @param bgColor*/public static void setBgColor(int bgColor) {BgColor = bgColor;}/*** 文字颜色* @param textColor*/public static void setTextColor(int textColor) {TextColor = textColor;}/*** 初始化* @param BgColor 背景颜色* @param TextColor 文字颜色* @param isIcon 图标是否显示* @param resId 图标* @param height 高度*/public static void init(int BgColor, int TextColor, boolean isIcon,int resId,int height){ZToast.BgColor = BgColor;ZToast.TextColor = TextColor;ZToast.isShowIcon = isIcon;ZToast.height = height;ZToast.resId = resId;}/*** 构造函数,上下文为activity* @param mActivity* @param text* @param times*/public ZToast(Activity mActivity, String text, long times){this.mActivity = mActivity;this.text = text;this.times = times;}/*** 构造函数,上下文为View* @param mView* @param text* @param times*/public ZToast(ViewGroup mView, String text, long times){this.mView = mView;this.text = text;this.times = times;}/*** 调用方法,上下文为activity* @param mActivity* @param text* @param times* @return*/public static ZToast makeText(Activity mActivity, String text, long times){mToastInstance = new ZToast(mActivity,text,times);return mToastInstance;}/*** 调用方法,上下文为view* @param mView* @param text* @param times* @return*/public static ZToast makeText(ViewGroup mView, String text, long times){mToastInstance = new ZToast(mView,text,times);return mToastInstance;}/*** 展示*/public void show(){if(mActivity!=null){mToastLayout = (RelativeLayout) mActivity.findViewById(R.id.rl_toast);if(mToastLayout==null){//判断是否已经添加进母VIEW里,没有则添加进去mToast = new ToastLayout(mActivity);initToast(mToast);mActivity.addContentView(mToast,new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ToastLayout.dip2px(mActivity,height)));}else{//如果有,则直接取出mToast = (ToastLayout) mToastLayout.getParent();}mToast.setContent(text);mToast.showToast(times);return;}else if(mView!=null){mToastLayout = (RelativeLayout) mView.findViewById(R.id.rl_toast);if(mToastLayout==null){mToast = new ToastLayout(mView.getContext());initToast(mToast);mView.addView(mToast,new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ToastLayout.dip2px(mView.getContext(),height)));}else{mToast = (ToastLayout) mToastLayout.getParent();}mToast.setContent(text);mToast.showToast(times);}}/*** 设置各个参数* @param mToast*/private void initToast(ToastLayout mToast) {if(TextColor!=0){mToast.setTextColor(TextColor);}if(BgColor!=0){mToast.setBgColor(BgColor);}if(resId!=0){mToast.setIcon(resId);}mToast.setIconVisible(isShowIcon);mToast.setHeight(height);}private boolean isShowToast(){if(mToast == null){return false;}return mToast.isShow();}/*** 是否在展示* @return*/public static boolean isShow(){if(mToastInstance == null){return false;}else{boolean isShow = mToastInstance.isShowToast();mToastInstance = null;return isShow;}}}

这个类主要是做了一些基本的封装,我们要基本仿照原生toast的写法,降低开发者的学习成本,所以采用ZToast.makeText(MainActivity.this,"文字",ZToast.LENGTH_SHORT).show(); 这样的方法来进行实现。首先判断上下文是activity还是自定义view,这里提供了两套构造方法。如果是activity,则通过addContentView()的方法把我们刚刚写完的自定义view添加进activity里;如果是view,则通过addview()方法把自定义view添加进去,再调用时候自定义view的showToast()方法来进行动画的播放。

还可以通过init方法和各种set方法来手动设置自定义view的属性。

实现:

显示toast

在activity中使用

ZToast.makeText(MainActivity.this,"文字",ZToast.LENGTH_SHORT).show();

在fragment中使用

ZToast.makeText(getActivity(), "文字",1000).show();

在自定义View中使用

ZToast.makeText((ViewGroup) getParent(),"文字"",1000).show();

设置toast的各个参数

在调用makeText方法之前调用init方法来设置参数ZToast.init(Color.parseColor("#000000"),Color.parseColor("#ff00ff"),true,R.mipmap.item_pasue,90);//参数为 背景色 文字颜色 是否有图标 图标资源 高度//也可以单独设置参数,如高度ZToast.setHeight(200);//最后调用toast方法ZToast.makeText(MainActivity.this,"点击事件",ZToast.LENGTH_SHORT).show();

判断是否正在显示toast

ZToast.isShow()当isShow()为true时,则说明正在显示中,可以用来做双击退出

点击两下back按键退出可以这样写:

代码如下:public boolean onKeyDown(int keyCode, KeyEvent event) {if((keyCode == KeyEvent.KEYCODE_BACK)){if(ZToast.isShow()){return super.onKeyDown(keyCode, event);}else{ZToast.makeText(MainActivity.this,"再按一次返回键退出",1000).show();return false;}}else{return super.onKeyDown(keyCode, event);}}

PS:推荐使用无actionbar的主题和设置statusbar颜色

强烈建议搭配无actionbar的主题来使用在style.xml中:<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"><!-- Customize your theme here. --><item name="colorPrimary">@color/colorPrimary</item><item name="colorPrimaryDark">@color/colorPrimaryDark</item><item name="colorAccent">@color/colorAccent</item></style>最好再设置一下statusbar的颜色在activity中:Window window = getWindow();window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);window.setStatusBarColor(Color.TRANSPARENT);

总结:

自定义view的使用已经仿照原生控件的封装方式,极大的简化了我们代码,为项目中今后所有需要用到toast的地方都提供了完整的一套方案。掌握的并不是说代码的技术含量,而是一种封装的思路。

完整的DEMO代码已经提交到GitHub和Jcenter。GITHUB地址:ZToastDemo

安装方法:

compile 'com.zhhr:ztoast:1.0.0'

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。