android通过自定义toast实现悬浮通知效果的示例代码

android通过toast实现悬浮通知效果,如图:

实现的功能:

  • 自定义悬浮弹窗;
  • 点击其他地方该布局不受影响;
  • 可自定义显示时间;
  • 可以设置点击事件;

代码如下:

import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import cn.droidlover.xdroidmvp.router.Router;
import io.slife.wallet.R;
import io.slife.wallet.config.IntentKey;
import io.slife.wallet.ui.NewsFlashDetailActivity;

public class PushToast {
private AppCompatActivity mActivity;
private static PushToast mInstance;
private Toast mToast;
private final int SHOW = 1;
private final int HIDE = 0;
private Object mTN;
private Method mShow;
private Method mHide;
private Field mViewFeild;
private long durationTime = 5*1000;

public static PushToast getInstance() {
 if (mInstance == null) {
  mInstance = new PushToast();
 }
 return mInstance;
}

public void init(AppCompatActivity activity) {
 mActivity = activity;
}

public void createToast(String title, String content, Map<String,String> params) {
 if (mActivity == null) {
  return;
 }
 LayoutInflater inflater = mActivity.getLayoutInflater();//调用Activity的getLayoutInflater()
//  LayoutInflater inflater = (LayoutInflater) context.getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 View view = inflater.inflate(R.layout.view_push_toast, null); //加載layout下的布局
 LinearLayout llPushContent = (LinearLayout) view.findViewById(R.id.ll_push_content);
 TextView tvTitle = (TextView) view.findViewById(R.id.tv_title);
 TextView tvContent = (TextView) view.findViewById(R.id.tv_content);
 tvTitle.setText(title);
 tvContent.setText(content);
 mToast = new Toast(mActivity);
 mToast.setView(view);
 mToast.setDuration(Toast.LENGTH_LONG);
 mToast.setGravity(Gravity.TOP, 0, 0);
 reflectEnableClick();
 reflectToast();
 llPushContent.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
   String newsFlashId = params.get("InformationID");
   Router.newIntent(mActivity).to(NewsFlashDetailActivity.class).putString(IntentKey.NEWS_FLASH_ID,newsFlashId).launch();
   handler.sendEmptyMessage(HIDE);
  }
 });
 if(mShow != null && mHide != null){
  handler.sendEmptyMessage(SHOW);
 }else{
  mToast.show();
 }
}

private void reflectEnableClick() {
 try {
  Object mTN;
  mTN = getField(mToast, "mTN");
  if (mTN != null) {
   Object mParams = getField(mTN, "mParams");
   if (mParams != null
     && mParams instanceof WindowManager.LayoutParams) {
    WindowManager.LayoutParams params = (WindowManager.LayoutParams) mParams;
    //显示与隐藏动画
//     params.windowAnimations = R.style.ClickToast;
    //Toast可点击
    params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
      | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
    //设置viewgroup宽高
    params.width = WindowManager.LayoutParams.MATCH_PARENT; //设置Toast宽度为屏幕宽度
    params.height = WindowManager.LayoutParams.WRAP_CONTENT; //设置高度
   }
  }
 } catch (Exception e) {
  e.printStackTrace();
 }
}

/**
 * 反射字段
 *
 * @param object 要反射的对象
 * @param fieldName 要反射的字段名称
 */
private static Object getField(Object object, String fieldName)
  throws NoSuchFieldException, IllegalAccessException {
 Field field = object.getClass().getDeclaredField(fieldName);
 if (field != null) {
  field.setAccessible(true);
  return field.get(object);
 }
 return null;
}

private Handler handler = new Handler() {
 @Override
 public void handleMessage(Message msg) {
  super.handleMessage(msg);
  switch (msg.what) {
   case SHOW:
    handler.sendEmptyMessageDelayed(HIDE, durationTime);
    show();
    break;
   case HIDE:
    hide();
    break;
  }
 }
};

public void reflectToast() {
 Field field = null;
 try {
  field = mToast.getClass().getDeclaredField("mTN");
  field.setAccessible(true);
  mTN = field.get(mToast);
  mShow = mTN.getClass().getDeclaredMethod("show");
  mHide = mTN.getClass().getDeclaredMethod("hide");
  mViewFeild = mTN.getClass().getDeclaredField("mNextView");
  mViewFeild.setAccessible(true);
 } catch (NoSuchFieldException e) {
  e.printStackTrace();
 } catch (IllegalAccessException e) {
  e.printStackTrace();
 } catch (IllegalArgumentException e) {
  e.printStackTrace();
 } catch (NoSuchMethodException e1) {
  e1.printStackTrace();
 }
}

public void show() {
 try {
  //android4.0以上就要以下处理
  if (Build.VERSION.SDK_INT > 14) {
   Field mNextViewField = mTN.getClass().getDeclaredField("mNextView");
   mNextViewField.setAccessible(true);
   LayoutInflater inflate = (LayoutInflater) mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   View v = mToast.getView();
   mNextViewField.set(mTN, v);
   Method method = mTN.getClass().getDeclaredMethod("show", null);
   method.invoke(mTN, null);
  }
  mShow.invoke(mTN, null);
 } catch (Exception e) {
  e.printStackTrace();
 }
}

private void hide() {
 try {
  mHide.invoke(mTN, null);
 } catch (IllegalAccessException e) {
  e.printStackTrace();
 } catch (IllegalArgumentException e) {
  e.printStackTrace();
 } catch (InvocationTargetException e) {
  e.printStackTrace();
 }catch (NullPointerException ex){
  ex.printStackTrace();
 }
}
}

xml布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_push_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_push_message"
android:orientation="vertical">
<TextView
 android:id="@+id/tv_title"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:textColor="@color/black"
 android:text="标题"
 android:maxLines="2"
 android:ellipsize="end"
 android:textStyle="bold"
 android:textSize="@dimen/text_size_14" />
<TextView
 android:id="@+id/tv_content"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:textColor="@color/black_808080"
 android:textSize="@dimen/text_size_13"
 android:maxLines="3"
 android:ellipsize="end"
 android:layout_marginTop="@dimen/margin_large"
 android:text="1"/>

</LinearLayout>

点九格式图片:

使用方法:

activity中需要初始化一次:

PushToast.getInstance().init(this);

调用:

PushToast.getInstance().createToast(msg.title,msg.text,umengPushEntity.getExtraMap());

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android实现类似qq微信消息悬浮窗通知功能

    实现方法:(需要开启悬浮窗通知权限.允许应用在其他应用上显示) 一.利用headsup 悬挂式Notification,他是5.0中新增的,也就是API中的Headsup的Notification,可以在不打断用户操作的时候,给用户通知 二.使用Window创建悬浮窗 当window属性设置为FLAGE_NOT_FOCUSABLE表示不需要获取焦点,也不需要接受各种输入事件,此标记会同时启用FLAGE_NOT_TOUCH_MODEL,最终事件会直接传递给下层具有焦点的Widow FLAGE_NO

  • android通过自定义toast实现悬浮通知效果的示例代码

    android通过toast实现悬浮通知效果,如图: 实现的功能: 自定义悬浮弹窗: 点击其他地方该布局不受影响: 可自定义显示时间: 可以设置点击事件: 代码如下: import android.content.Context; import android.os.Build; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import

  • Android仿高德首页三段式滑动效果的示例代码

    目录 高德的效果 实现的效果 自定义View源码 xml布局中的使用 高德首页按钮处理 源码地址 最近发现很多app都使用了三段式滑动,比如说高德的首页和某宝等物流信息都是使用的三段式滑动方式,谷歌其实给了我们很好的2段式滑动,就是BottomSheet,所以这次我也是在这个原理基础上做了一个小小的修改来实现我们今天想要的效果. 高德的效果 实现的效果 我们实现的效果和高德差距不是很大,也很顺滑.具体实现其实就是继承CoordinatorLayout.Behavior 自定义View源码 /**

  • android调用H5显示加载中效果的示例代码

    我们在看有些应用在引入h5的时候经常会有一个进度条在转,显示加载的意思,那么这个东西其实一般是我们android端做的事(不要把所有的事都推给h5~~~),其实实现起来很简单, ok 废话不多说,上代码吧 wv.setWebViewClient(new WebViewClient() { @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view,

  • Android实现带磁性的悬浮窗体效果

    本文实例讲述了Android实现带磁性的悬浮窗体效果.分享给大家供大家参考,具体如下: 带磁性的悬浮窗体,类似于360绿色小人 主要实现的是: 1.悬浮所有窗体之上 2.有吸引力,吸附于屏幕边上 3.有点击效果 下面我就实现上面三点,简单封装了个FloatView 先看下本次Demo的效果图,然后再看代码, 效果图: FloatView代码如下 package com.manymore13.flowwindowdemo; import android.content.Context; impor

  • Android 自定义加载动画Dialog弹窗效果的示例代码

    效果图 首先是创建弹窗的背景 这是上面用到的 以shape_bg_5_blue.xml为例,其他的三个无非就是里面的颜色不一样而已 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <corners android:radius="5dp"

  • Android 通过自定义view实现水波纹效果案例详解

    在实际的开发中,很多时候还会遇到相对比较复杂的需求,比如产品妹纸或UI妹纸在哪看了个让人兴奋的效果,兴致高昂的来找你,看了之后目的很明确,当然就是希望你能给她: 在这样的关键时候,身子板就一定得硬了,可千万别说不行,爷们儿怎么能说不行呢: 好了,为了让大家都能给妹纸们想要的,后面会逐渐分享一些比较比较不错的效果,目的只有一个,通过自定义view实现我们所能实现的动效: 今天主要分享水波纹效果: 标准正余弦水波纹: 非标准圆形液柱水波纹: 虽说都是水波纹,但两者在实现上差异是比较大的,一个通过正余

  • Android打开淘宝客户端(手淘)效果及实现代码

    隐式调用的方法就不讲了,如果安装了手淘的SDK或阿里百川之类的东西请参考官方文档,有了文档这些都不是问题. 一.应用内打开 应用内部调用淘宝,当展示"最近运行的应用"时只会显示一个应用,前提是安装了淘宝客户端. 效果图: 首先判断应用是否安装: private boolean isAppInstalled(Context context, String uri) { PackageManager pm = context.getPackageManager(); boolean ins

  • Android仿IOS上拉下拉弹性效果的实例代码

    用过iphone的朋友相信都体验过页面上拉下拉有一个弹性的效果,使用起来用户体验很好:Android并没有给我们封装这样一个效果,我们来看下在Android里如何实现这个效果.先看效果,感觉有些时候还是蛮实用的. 思路:其实原理很简单,实现一个自定义的Scrollview方法(来自网上大神),然后在布局文件中使用自定义方法Scrollview就可以了. 代码: 自定义View,继承自Scrollview.MyReboundScrollView类 package com.wj.myrebounds

  • Android TV开发:实现3D仿Gallery效果的实例代码

    本文讲述了Android TV开发:实现3D仿Gallery效果的实例代码.分享给大家供大家参考,具体如下: 1.实现效果: 滚动翻页+ 页面点击+页码指示器+焦点控制 2.实现这个效果之前必须要了解 Android高级图片滚动控件实现3D版图片轮播器这篇文章,我是基于他的代码进行修改的,主要为了移植到电视上做了按键事件和焦点控制. 3.具体代码: public class Image3DSwitchView extends LinearLayout { private int currentP

  • Android输入框实时模糊搜索效果的示例代码

    Android输入框实时模糊搜索 很多开发场景会用到搜索框实时模糊搜索来帮助用户输入内容,如图 思路是在EditText 字符变动的时候 弹出ListPopupwindow并更新列表,这样的做法google已经封装为AutoCompleteTextView 用法 mAutoCompleteTextView.setAdapter(adapter); mAutoCompleteTextView.setFocusable(true); mAutoCompleteTextView.setOnItemCl

随机推荐