弹出浮层基类 BaseFloating 封装
来源:互联网 发布:淘宝阿里巴巴男士秋装 编辑:程序博客网 时间:2024/05/21 06:18
之前在一个技术群里面有位同学请教大家这种弹出窗怎么做(如下图所示),他是用的PopWindow实现的,但是PopWindow有很多地方不符合他的要求,比如弹出的起始位置,弹出的动画效果。
我们项目中也会有这种弹出浮层的需求,举个例子,下面是仿淘宝选择规格的弹出浮层效果,不仅仅是这一处,整个项目中也会有很多类似的弹出浮层效果,为了方便,我们就需要有一个弹出浮层基类,来简化我们的代码。下面我就来介绍下我们项目的解决方案。
我们的实现思路是:将弹出浮层的View 独立封装,然后获取到这个View的实例,add 到我们需要显示的屏幕 decodeView 上,所以我们默认那个需要使用的页面 最外层使用的是 FramLayout (具体原因大家可以百度 FramLayout ,了解下它的属性),在add到屏幕上后,将 浮层View隐藏,在触发条件后再给View 配上相应的弹出动画显示。下面我们看下这个基类:
package com.example.jin.floating.view;import android.animation.Animator;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.graphics.Color;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.FrameLayout;import android.widget.LinearLayout;import java.util.ArrayList;import java.util.List;/** * 浮层基类 * */public abstract class BaseFloatinglayer { protected Context mContext; protected int resourceId;//布局页面id protected ViewGroup content, resource_View; protected FrameLayout decorView; protected LinearLayout background; protected Intent intentData; protected boolean click_background_close=true; protected boolean isInited=false; protected FloatingCallBack mFloatingCallBack; protected boolean isAnimating=false;//动画正在执行 protected boolean isShowed=false;//页面已经显示 protected List<Animator> mAnimatorList = new ArrayList<Animator>(); public BaseFloatinglayer(Context ctx, int ResourceId){ this.mContext=ctx; this.resourceId =ResourceId; InitView(); } public abstract void openShow();//打开显示动画 public abstract void closeHide();//关闭隐藏 public abstract void findView(ViewGroup resource_View);//页面初始化成功返回布局Resource_View public abstract void hide();//初始化时隐藏 public abstract void setIntentData(Intent intentData);//视图打开后获取数据 public void setmFloatingCallBack(FloatingCallBack mFloatingCallBack) { this.mFloatingCallBack = mFloatingCallBack; } public boolean isShowed() { return isShowed; } public View getView() { return this.resource_View; } protected void InitView(){ LayoutInflater inflater = LayoutInflater.from(mContext); decorView = (FrameLayout) ((ViewGroup)((Activity)mContext).getWindow().getDecorView().findViewById(android.R.id.content));//.getChildAt(0) content = (ViewGroup) decorView.getChildAt(0); resource_View = (ViewGroup) inflater.inflate(resourceId, null); InitBackground(); findView(resource_View); isInited=true; } /** * 初始化背景层 */ protected void InitBackground(){ background=new LinearLayout(mContext); background.setBackgroundColor(Color.BLACK); background.setOrientation(LinearLayout.VERTICAL); background.setVisibility(View.GONE); background.setAlpha(0); background.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)); background.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (click_background_close) { closeHide(); } } }); } public View Background(){ return this.background; } /** * 添加到顶层 */ public void ViewAdd(){ if(decorView.findViewById(resourceId)==null){//如果当前页面没有则addView decorView.addView(background); decorView.addView(resource_View); } } /** * 添加到顶层 * @param VL */ public void ViewAdd(ViewGroup.LayoutParams VL){ if(decorView.findViewById(resourceId)==null){//如果当前页面没有则addView decorView.addView(background); decorView.addView(resource_View,VL); } } public void ViewAddMoBackgrond(ViewGroup.LayoutParams VL){ if(decorView.findViewById(resourceId)==null){//如果当前页面没有则addView decorView.addView(resource_View,VL); } } /** * 添加到顶层 * @param childid */ public void ViewAddToParent(int childid){ if(content.findViewById(resourceId)==null){//如果当前页面没有则addView content.addView(background); content.addView(resource_View); } } /** * 添加到指定索引 * @param childid * @param VL */ public void ViewAddToParent(int childid, ViewGroup.LayoutParams VL){ if(content.findViewById(resourceId)==null){//如果当前页面没有则addView content.addView(background, childid, VL); content.addView(resource_View, childid+1,VL); } }}
我们来看下主要实现代码部分:
1、获取到屏幕,以及传入的 浮层View 的 布局xml 文件id,其中resourceId就是传入的xml 文件id:
LayoutInflater inflater = LayoutInflater.from(mContext);decorView = (FrameLayout) ((ViewGroup)((Activity)mContext).getWindow().getDecorView().findViewById(android.R.id.content));//.getChildAt(0)content = (ViewGroup) decorView.getChildAt(0);resource_View = (ViewGroup) inflater.inflate(resourceId, null);
2、将实例化获取到的浮层View add 到屏幕上,这里我们封装了几个add方法,分别是默认添加到顶层; 添加到置顶索引位置; 同时添加阴影浮层(这个阴影浮层是夹在屏幕和浮层View之间的);根据传入的 LayoutParams 添加浮层,可以满足多种需求,如果有新的需求,也可以在其中添加相应方法。
public void ViewAdd(){ if(decorView.findViewById(resourceId)==null){//如果当前页面没有则addView decorView.addView(background); decorView.addView(resource_View); }}/** * 添加到顶层 * @param childid */public void ViewAddToParent(int childid){ if(content.findViewById(resourceId)==null){//如果当前页面没有则addView content.addView(background); content.addView(resource_View); }}/** * 添加到顶层 * @param VL */public void ViewAdd(ViewGroup.LayoutParams VL){ if(decorView.findViewById(resourceId)==null){//如果当前页面没有则addView decorView.addView(background); decorView.addView(resource_View,VL); }}
3、 这里还封装了几个abstract 方法,对应弹出,隐藏,获取控件,接收传入数据等操作,以实现需要在浮层View进行一些进一步的操作:
public abstract void openShow();//打开显示动画public abstract void closeHide();//关闭隐藏public abstract void findView(ViewGroup resource_View);//页面初始化成功返回布局Resource_Viewpublic abstract void hide();//初始化时隐藏public abstract void setIntentData(Intent intentData);//视图打开后获取数据
4、 同时我们还封装了个回调接口,可以让我们接收到开始弹出,结束弹出,开始隐藏,结束隐藏的动作:
public interface FloatingCallBack { void OpenStart(); void OpenEnd(); void CloseStart(); void CloseEnd();}
介绍了原理,我们来介绍下使用方法:新建类文件,继承基类,在 openShow 和 closeHide 方法中写你需要的弹出,隐藏动画(我这里只是举例了从下方弹出和收起到下方,也可以替换成上下左右4个方向的,任意都可以,看你的具体需求了),并且在Hide方法中将其影藏:
@Overridepublic void hide() { resource_View.setTranslationY(DensityUtils.getHeight(mContext)); resource_View.setVisibility(View.GONE); isAnimating=false; isShowed=false;}
我们来看下已经写好了的 TestFloating:
package com.example.jin.floating.view;import android.animation.Animator;import android.animation.AnimatorSet;import android.animation.ObjectAnimator;import android.content.Context;import android.content.Intent;import android.view.View;import android.view.ViewGroup;import android.widget.RelativeLayout;import com.example.jin.floating.DensityUtils;import com.example.jin.floating.R;import java.util.Collections;/** * Created by Jin on 2016/8/11. * 用途 : */public class TestFloating extends BaseFloatinglayer { private RelativeLayout touch_close; public TestFloating(Context ctx, int ResourceId) { super(ctx, ResourceId); } @Override public void openShow() { if(!isAnimating&&!isShowed){// touch_to_close.setBackgroundResource(R.color.transparent); isAnimating=true; AnimatorSet m_AnimatorSet = new AnimatorSet(); resource_View.setVisibility(View.VISIBLE); ObjectAnimator Resource_View_TRANSLATION_Y= ObjectAnimator.ofFloat(resource_View, View.TRANSLATION_Y, DensityUtils.getHeight(mContext),0 ); mAnimatorList.clear(); Collections.addAll(mAnimatorList, Resource_View_TRANSLATION_Y); m_AnimatorSet.playTogether(mAnimatorList); m_AnimatorSet.setDuration(300); m_AnimatorSet.start(); m_AnimatorSet.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { if(mFloatingCallBack!=null){ mFloatingCallBack.OpenStart(); } } @Override public void onAnimationEnd(Animator animation) { if(mFloatingCallBack!=null){ mFloatingCallBack.OpenEnd(); } isAnimating=false; isShowed=true;// touch_to_close.setBackgroundResource(R.color.back_ground_transpant); } @Override public void onAnimationCancel(Animator animation) { if(mFloatingCallBack!=null){ mFloatingCallBack.OpenEnd(); } isAnimating=false; } @Override public void onAnimationRepeat(Animator animation) { } }); } } @Override public void closeHide() { if(!isAnimating&&isShowed) {// touch_to_close.setBackgroundResource(R.color.transparent); isAnimating=true; isShowed=false; AnimatorSet m_AnimatorSet = new AnimatorSet(); ObjectAnimator Resource_View_TRANSLATION_Y = ObjectAnimator.ofFloat(resource_View, View.TRANSLATION_Y, 0,DensityUtils.getHeight(mContext)); mAnimatorList.clear(); Collections.addAll(mAnimatorList, Resource_View_TRANSLATION_Y); m_AnimatorSet.playTogether(mAnimatorList); m_AnimatorSet.setDuration(300); m_AnimatorSet.start(); m_AnimatorSet.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { if(mFloatingCallBack!=null){ mFloatingCallBack.CloseStart(); } } @Override public void onAnimationEnd(Animator animation) { resource_View.setVisibility(View.GONE); isAnimating=false; if(mFloatingCallBack!=null){ mFloatingCallBack.CloseEnd(); } } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); } } @Override public void findView(ViewGroup resource_View) { touch_close= (RelativeLayout) resource_View.findViewById(R.id.touch_close); touch_close.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { closeHide(); } }); } @Override public void hide() { resource_View.setTranslationY(DensityUtils.getHeight(mContext)); resource_View.setVisibility(View.GONE); isAnimating=false; isShowed=false; } @Override public void setIntentData(Intent intentData) { }}
剩下的就是在我们的Activity中调用,先实例化:
private void initFloating() { testFloating=new TestFloating(this,R.layout.floating_layout); FrameLayout.LayoutParams couponsFloatingFL = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); testFloating.ViewAddMoBackgrond(couponsFloatingFL); testFloating.hide();}
在需要触发的地方调用 openShow方法就可以了:
testFloating.openShow();
我们来看一下效果:
- 弹出浮层基类 BaseFloating 封装
- 封装jquery弹出窗口
- js封装弹出框
- IOS-封装弹出框
- iOS-封装弹出框
- Dialog弹出层封装
- 弹出样式封装
- 弹出层(封装代码)
- 弹出框PopupView的封装
- vue弹出框的封装
- layui 弹出的封装函数
- asp.net弹出对话的封装
- asp.net弹出对话框的封装
- jquery插件封装:弹出iframe模式框
- jquery插件封装:弹出div对话框
- RPG游戏弹出框方法的封装
- 封装的弹出视图的View
- iOS弹出框封装好的方法
- Java 常用排序
- 深入理解java虚拟机——垃圾收集器
- 关于java安全策略的问题
- 数组名为什么代表首地址
- Mysql主从原理
- 弹出浮层基类 BaseFloating 封装
- 随机生成图片验证码
- Python StringIO模块 实现在内存缓冲区中读写数据
- ios cocoapod安装以及常见问题解决
- Activity与Service间的通信:Messenger
- Android各类中静态字段说明
- 用户空间使用i2c_dev
- Redis之Redis配置文件redis.conf 详解
- linux之查看日志