本文实例为大家分享了Android模仿Toast实现提示框效果的具体代码,供大家参考,具体内容如下

Toast提示只要提示的时间够长,就可以浮动到其他任何界面之上,所以我们可以模仿Toast来实现来电号码归属地的提示框

1、WindowManager

The interface that apps use to talk to the window manager. Use Context.getSystemService(Context.WINDOW_SERVICE) to get one of these. Each window manager instance is bound to a particular Display.

1).void addView(View view,ViewGroup.LayoutParams params)
将一个View视图显示到当前窗口,LayoutParams are used by views to tell their parents how they want to be laid out.

2).void removeView(View view); 将一个View视图从当前窗口中移除。

2、自定义窗体提示框(参考Toast源码)

WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); 
View view = View.inflate(getApplicationContext(), R.layout.toast_location,
                null); 
TextView tv = (TextView) view.findViewById(R.id.tv_toast_address);
tv.setText(address);
LayoutParams params = new LayoutParams();
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.gravity = Gravity.LEFT | Gravity.TOP;
params.x = sp.getInt("lastx", 0);
params.y = sp.getInt("lasty", 0);
//本来还有一个FLAG_NOTUCHALBE为了让下面能触摸把这个给去掉了
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
params.format = PixelFormat.TRANSLUCENT;    //源码中这里是TYPE_TAOST但是这里为了下面要进行点击拖动事件,而Toast不能拖动,
所以这里改成了TYPE_PRIORITY_PHONE,这是一个系统类型的提示框,使用这个提示框必须要申请权限,android.permission.SYSTEM_ALERT_WINDOW
params.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE; 
wm.addView(view, params); 

3、WindowManager添加的显示框的简单拖动

该这个View注册一个onTouchListener

public void showLocation(String address) {
    view = View.inflate(getApplicationContext(), R.layout.toast_location,
            null);
    // 得到spint which = sp.getInt("which", 0);
    view.setBackgroundResource(bgs[which]);
    view.setOnTouchListener(new OnTouchListener() {
        int startX ,startY;

        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:Log.i(TAG,"摸到");
                startX = (int) event.getRawX();
                startY  = (int) event.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:Log.i(TAG,"移动");
                int newX = (int) event.getRawX();
                int newY  = (int) event.getRawY();
                int dx = newX - startX;
                int dy = newY - startY;
                params.x =dx;
                params.y =dy;   //这里在WindowManager中不能够使用layout方法了,无效,只能使用layoutparams来更新位置,这里的params就是上面的那个params
                wm.updateViewLayout(view, params);
                //重新初始化 手指的位置
                startX = (int) event.getRawX();
                startY  = (int) event.getRawY();
                break;
            }
            return true;
        }
    });
}

4、普通ImageView随手指拖动改变位置

iv_drag_view.setOnTouchListener(new OnTouchListener() {
    //记录住最初手指按下时的位置int startX , startY; 
    //onTouch方法的返回值如果是true监听器会把这个事件给消费掉, false则监听器不会消费掉这个事件public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {  
            case MotionEvent.ACTION_DOWN:Log.i(TAG,"摸到这个控件了");
                startX = (int) event.getRawX();//记录手指第一次点击到屏幕时候距离x和y轴的距离
                startY = (int) event.getRawY();
            break;
            case MotionEvent.ACTION_MOVE:// 手指在屏幕上移动的事件Log.i(TAG,"移动");
                int newX = (int) event.getRawX(); //在移动的过程中不断的获取到手指当前移动到的位置int newY = (int) event.getRawY();
                int dx = newX - startX;           //计算出手指移动了多少int dy = newY - startY;
                int l = iv_drag_view.getLeft(); //获取图片上下左右的长度int r = iv_drag_view.getRight();
                int b = iv_drag_view.getBottom();
                int t = iv_drag_view.getTop();

                int newl = l dx; //计算图片应该移动的距离int newr = r dx;
                int newt = t dy;//imageview 在窗体中新的位置int newb = b dy;

                //判断如果图片准备移动到的位置超出了屏幕就不让它移动,这里减去30是减去窗体上面的状态栏的高度if(newl<0||newt < 0 ||newb>display.getHeight()-30||newr>display.getWidth()){
                    break;
                }            
                //将图片移动到新的位置。直接调用ImageView的layout方法
                iv_drag_view.layout(newl,  newt, newr, newb); 
                //一旦图片移动到新的位置就重新计算手指当前的位置,这样循环下去就能实现随着手指的拖动
                startX = (int) event.getRawX();
                startY = (int) event.getRawY();
            break;
            case MotionEvent.ACTION_UP: // 手指在离开屏幕的一瞬间对应的事件.Log.i(TAG,"放手");
            int lasty = iv_drag_view.getTop();//得到最后在离屏幕上方的距离int lastx = iv_drag_view.getLeft();//得到最后离屏幕左边的距离Editor editor = sp.edit();
            editor.putInt("lastx", lastx);
            editor.putInt("lasty", lasty);
            editor.commit();
            break;
        }
            return true; //这地方一定要返回true告诉系统这个事件做完了
    }
});

注意:在onCreate方法中使用layout方法是没有效果的,因为在进入一个Activity中系统首先会执行一个计算的操作,计算各个控件的布局,然后调用setContentView方法显示出来这个控件,第二步才会执行这个layout方法,但是在onCreate方法中设置了layout,在执行layout这段代码的时候,窗体有可能还没有计算完控件的布局,所以先执行了这个layout,然后又执行了计算控件布局来显示,这样layout就没效了,这里要怎么弄呢只能是通过设置这个控件的layout布局,这样在计算位置的时候就能计算了,这样设置布局能让它在计算的时候就计算了。如下,在onCreate方法中去这样设置。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    sp = getSharedPreferences("config", MODE_PRIVATE);
    // Have the system blur any windows behind this one.
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
            WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
    wm = (WindowManager) getSystemService(WINDOW_SERVICE);//窗体管理者
    display = wm.getDefaultDisplay();

    setContentView(R.layout.activity_drag_view);
    tv_drag_view = (TextView) findViewById(R.id.tv_drag_view);
    iv_drag_view = (ImageView) findViewById(R.id.iv_drag_view);

    int lastx = sp.getInt("lastx", 0);
    int lasty = sp.getInt("lasty", 0);

    RelativeLayout.LayoutParams params = (LayoutParams) iv_drag_view.getLayoutParams();
    params.leftMargin = lastx;
    params.topMargin = lasty;
    iv_drag_view.setLayoutParams(params); 
}

注意:在WindowManager中要想更新控件的距离就不能用layout方法了,只能用mWindowManager.updateViewLayout(view, params);

5、实现双击事件

1).双击的定义 Android中没有提供双击的点击事件,双击就是单位时间内的两次点击

2).触摸和点击事件的区别 点击事件: 一组动作的集合 点击 - 停留 - 离开. 触摸事件: 手指按下屏幕 手指在屏幕上移动 手指离开屏幕的一瞬间

public class DragViewActivity extends Activity {
    protected static final String TAG = "DragViewActivity";
    private ImageView iv_drag_view;
    private TextView tv_drag_view;
    private SharedPreferences sp;

    private WindowManager wm;
    private Display  display; //窗体的显示的分辨率private long firstClickTime;//第一次点击时候的事件@Overrideprotected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        sp = getSharedPreferences("config", MODE_PRIVATE);
        // Have the system blur any windows behind this one.
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
                WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
        wm = (WindowManager) getSystemService(WINDOW_SERVICE);//窗体管理者
        display = wm.getDefaultDisplay();

        setContentView(R.layout.activity_drag_view);
        tv_drag_view = (TextView) findViewById(R.id.tv_drag_view);
        iv_drag_view = (ImageView) findViewById(R.id.iv_drag_view);

        int lastx = sp.getInt("lastx", 0);
        int lasty = sp.getInt("lasty", 0);

        RelativeLayout.LayoutParams params = (LayoutParams) iv_drag_view.getLayoutParams();
        params.leftMargin = lastx;
        params.topMargin = lasty;
        iv_drag_view.setLayoutParams(params);

        iv_drag_view.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                Log.i(TAG,"被点击了.");
                if(firstClickTime>0){//说明这是第二次点击.long secondTime = System.currentTimeMillis();
                    long dtime = secondTime - firstClickTime;
                    if(dtime<500){
                        //双击事件.Log.i(TAG,"双击居中");
                        int iv_width = iv_drag_view.getRight() - iv_drag_view.getLeft();
                        iv_drag_view.layout(display.getWidth()/2-iv_width/2, iv_drag_view.getTop(), display.getWidth()/2 iv_width/2, iv_drag_view.getBottom());
                        int lasty = iv_drag_view.getTop();//得到最后在离屏幕上方的距离int lastx = iv_drag_view.getLeft();//得到最后离屏幕左边的距离Editor editor = sp.edit();
                        editor.putInt("lastx", lastx);
                        editor.putInt("lasty", lasty);
                        editor.commit();
                    }
                    firstClickTime = 0;//将第一次点击的时间还原成0。return;
                } else {
                //第一次点击
                    firstClickTime = System.currentTimeMillis();//  记录第一次点击的时间//新开一个线程,在这个子线程中如果是500毫秒内没有再点击就将第一次点击的时间设置为0new Thread(){
                        public void run() {
                            try {
                                Thread.sleep(500);
                                firstClickTime = 0;
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        };
                    }.start();
                }               
            }
        });
    }
}

6、触摸和双击同时发生时候的返回值

//onTouch方法的返回值,True if the listener has consumed the event, false otherwise,true 监听器会把这个事件给消费掉, false 不会消费掉这个事件
iv_drag_view.setOnTouchListener(new OnTouchListener() {

    int startX , startY;
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:// 手指触摸到屏幕的事件Log.i(TAG,"摸到这个控件了");
            startX = (int) event.getRawX();
            startY = (int) event.getRawY();
            break;
        case MotionEvent.ACTION_MOVE:// 手指在屏幕上移动的事件Log.i(TAG,"移动");
            int newX = (int) event.getRawX();
            int newY = (int) event.getRawY();
            int dx = newX - startX;
            int dy = newY - startY;
            int l = iv_drag_view.getLeft();
            int r = iv_drag_view.getRight();
            int b = iv_drag_view.getBottom();
            int t = iv_drag_view.getTop();

            int newl = l dx;
            int newr = r dx;
            int newt = t dy;//imageview 在窗体中新的位置int newb = b dy;

            if(newl<0||newt < 0 ||newb>display.getHeight()-30||newr>display.getWidth()){
                break;
            }

            int tv_height = tv_drag_view.getBottom() - tv_drag_view.getTop();

            if(newt>display.getHeight()/2){//imageview在窗体的下方//textview在窗体的上方
                tv_drag_view.layout(tv_drag_view.getLeft(), 0, tv_drag_view.getRight(), tv_height);
            }else{
                tv_drag_view.layout(tv_drag_view.getLeft(), display.getHeight()-tv_height-30, tv_drag_view.getRight(), display.getHeight()-30);
                //textview在窗体的下方
            }

            iv_drag_view.layout(newl,  newt, newr, newb);

            //更新手指开始的位置.
            startX = (int) event.getRawX();
            startY = (int) event.getRawY();
            break;
        case MotionEvent.ACTION_UP: // 手指在离开屏幕的一瞬间对应的事件.Log.i(TAG,"放手");
            int lasty = iv_drag_view.getTop();//得到最后在离屏幕上方的距离int lastx = iv_drag_view.getLeft();//得到最后离屏幕左边的距离Editor editor = sp.edit();
            editor.putInt("lastx", lastx);
            editor.putInt("lasty", lasty);
            editor.commit();
            break;
        }
        // 这里对于触摸事件应该是返回true为什么这里返回false呢,因为这里这一个控件同时实现了点击和触摸这两个事件,如果返回true,// 那么就不可能发生点击事件了,所以对于同时实现点击和触摸的控件返回值要为falsereturn false;
    }
});

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

Android模仿Toast实现提示框效果的更多相关文章

  1. html5 canvas合成海报所遇问题及解决方案总结

    这篇文章主要介绍了html5 canvas合成海报所遇问题及解决方案总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Html5 video标签视频的最佳实践

    这篇文章主要介绍了Html5 video标签视频的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  3. HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题

    HTML5在微信内置浏览器下,在右上角菜单的调整字体导致页面显示错乱的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  4. ios – containerURLForSecurityApplicationGroupIdentifier:在iPhone和Watch模拟器上给出不同的结果

    我使用默认的XCode模板创建了一个WatchKit应用程序.我向iOSTarget,WatchkitAppTarget和WatchkitAppExtensionTarget添加了应用程序组权利.(这是应用程序组名称:group.com.lombax.fiveminutes)然后,我尝试使用iOSApp和WatchKitExtension访问共享文件夹URL:延期:iOS应用:但是,测试NSURL

  5. Ionic – Splash Screen适用于iOS,但不适用于Android

    我有一个离子应用程序,其中使用CLI命令离子资源生成的启动画面和图标iOS版本与正在渲染的启动画面完美配合,但在Android版本中,只有在加载应用程序时才会显示白屏.我检查了config.xml文件,所有路径看起来都是正确的,生成的图像出现在相应的文件夹中.(我使用了splash.psd模板来生成它们.我错过了什么?这是config.xml文件供参考,我觉得我在这里做错了–解决方法在config.xml中添加以下键:它对我有用!

  6. ios – 无法启动iPhone模拟器

    /Library/Developer/CoreSimulator/Devices/530A44CB-5978-4926-9E91-E9DBD5BFB105/data/Containers/Bundle/Application/07612A5C-659D-4C04-ACD3-D211D2830E17/ProductName.app/ProductName然后,如果您在Xcode构建设置中选择标准体系结构并再次构建和运行,则会产生以下结果:dyld:lazysymbolbindingFailed:Symbol

  7. Xamarin iOS图像在Grid内部重叠

    heyo,所以在Xamarin我有一个使用并在其中包含一对,所有这些都包含在内.这在Xamarin.Android中看起来完全没问题,但是在Xamarin.iOS中,图像与标签重叠.我不确定它的区别是什么–为什么它在Xamarin.Android中看起来不错但在iOS中它的全部都不稳定?

  8. 在iOS上向后播放HTML5视频

    我试图在iPad上反向播放HTML5视频.HTML5元素包括一个名为playbackRate的属性,它允许以更快或更慢的速率或相反的方式播放视频.根据Apple’sdocumentation,iOS不支持此属性.通过每秒多次设置currentTime属性,可以反复播放,而无需使用playbackRate.这种方法适用于桌面Safari,但似乎在iOS设备上的搜索限制为每秒1次更新–在我的情况下太慢了.有没有办法在iOS设备上向后播放HTML5视频?解决方法iOS6Safari现在支持playbackRat

  9. 使用 Swift 语言编写 Android 应用入门

    Swift标准库可以编译安卓armv7的内核,这使得可以在安卓移动设备上执行Swift语句代码。做梦,虽然Swift编译器可以胜任在安卓设备上编译Swift代码并运行。这需要的不仅仅是用Swift标准库编写一个APP,更多的是你需要一些框架来搭建你的应用用户界面,以上这些Swift标准库不能提供。简单来说,构建在安卓设备上使用的Swiftstdlib需要libiconv和libicu。通过命令行执行以下命令:gitclonegit@github.com:SwiftAndroid/libiconv-libi

  10. Android – 调用GONE然后VISIBLE使视图显示在错误的位置

    我有两个视图,A和B,视图A在视图B上方.当我以编程方式将视图A设置为GONE时,它将消失,并且它正下方的视图将转到视图A的位置.但是,当我再次将相同的视图设置为VISIBLE时,它会在视图B上显示.我不希望这样.我希望视图B回到原来的位置,这是我认为会发生的事情.我怎样才能做到这一点?编辑–代码}这里是XML:解决方法您可以尝试将两个视图放在RelativeLayout中并相对于彼此设置它们的位置.

随机推荐

  1. Flutter 网络请求框架封装详解

    这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Android单选按钮RadioButton的使用详解

    今天小编就为大家分享一篇关于Android单选按钮RadioButton的使用详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

  3. 解决android studio 打包发现generate signed apk 消失不见问题

    这篇文章主要介绍了解决android studio 打包发现generate signed apk 消失不见问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  4. Android 实现自定义圆形listview功能的实例代码

    这篇文章主要介绍了Android 实现自定义圆形listview功能的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. 详解Android studio 动态fragment的用法

    这篇文章主要介绍了Android studio 动态fragment的用法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. Android用RecyclerView实现图标拖拽排序以及增删管理

    这篇文章主要介绍了Android用RecyclerView实现图标拖拽排序以及增删管理的方法,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下

  7. Android notifyDataSetChanged() 动态更新ListView案例详解

    这篇文章主要介绍了Android notifyDataSetChanged() 动态更新ListView案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

  8. Android自定义View实现弹幕效果

    这篇文章主要为大家详细介绍了Android自定义View实现弹幕效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  9. Android自定义View实现跟随手指移动

    这篇文章主要为大家详细介绍了Android自定义View实现跟随手指移动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Android实现多点触摸操作

    这篇文章主要介绍了Android实现多点触摸操作,实现图片的放大、缩小和旋转等处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部