黑马52期学后总结笔记(五)

来源:互联网 发布:淘宝白夜追凶视频电话 编辑:程序博客网 时间:2024/04/30 13:30


自定义土司显示归属地

演示:目前的土司的缺陷,比如:无法控制消失、界面丑

1、看Toast的源代码

2、查看toast布局文件的背景目录:\sdk\platforms\android-16\data\res\values\themes.xml;

 

3、实现代码

 

private WindowManager wm;

 

public void showMyToast(String address) {

             

              view = new TextView(this);

              view.setTextSize(20);

              view.setTextColor(Color.RED);

              view.setText(address);

              WindowManager.LayoutParams params = newWindowManager.LayoutParams();

           params.height =WindowManager.LayoutParams.WRAP_CONTENT;

       params.width = WindowManager.LayoutParams.WRAP_CONTENT;

       params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

              |WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE

              |WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;

       params.format = PixelFormat.TRANSLUCENT;

       params.type = WindowManager.LayoutParams.TYPE_TOAST;

              wm.addView(view, params);

             

       }

3、演示发现无法把土司一直停留页面;

 

4、处理电话挂断情形

caseTelephonyManager.CALL_STATE_IDLE:

                            if(view!= null){

                                    wm.removeView(view);

                                    view = null;

                            }

                            break;

 

 

 

5、演示

 

 

 

更改归属地的背景风格

准备:安装市场类似软件(金山软件)开启另外一个模拟器

1、创建布局文件toast_address.xml  图片(ic_menu_call

2、借用市场软件的图片背景(call_locate_gray)

 

<LinearLayout

    android:background="@drawable/call_locate_gray"

    android:gravity="center_vertical"

    android:orientation="horizontal">

 

    <ImageView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:src="@android:drawable/ic_menu_call"/>

 

    <TextView

        android:id="@+id/tv_location"

        android:text="归属地

        android:textSize="20sp"

        android:textColor="#000000"

        />

 

</LinearLayout>

 

 

3、演示金山的软件的

4、基于ui_setting_item_view自定义点击条目(金山里去找\res\\drawable\jiantou1_pressed.png)

 

5、基于SettingItemView 自定义SettingClickView 并只处理标题和内容描述内容;

6、在SettingActivity 处理点击事件;

 

 

              //设置归属地的背景

              scv_changebg = (SettingClickView)findViewById(R.id.scv_changebg);

              final String [] items = {"半透明","活力橙","卫士蓝","金属灰","苹果绿"};

              scv_changebg.setTitle("归属地提示框风格");

              int which = sp.getInt("which",0);

              scv_changebg.setDesc(items[which]);

              scv_changebg.setOnClickListener(newOnClickListener() {

                    

                     @Override

                     publicvoid onClick(View v) {

                            AlertDialog.Builder builder = newBuilder(SettingActivity.this);

                            builder.setTitle("归属地提示框风格");

                           

                            int which = sp.getInt("which",0);

                            builder.setSingleChoiceItems(items,which, new DialogInterface.OnClickListener() {

                                  

                                   @Override

                                   publicvoid onClick(DialogInterface dialog, int which) {

                                          Editor editor = sp.edit();

                                          editor.putInt("which", which);

                                          scv_changebg.setDesc(items[which]);

                                          editor.commit();

                                          dialog.dismiss();

                                         

                                   }

                            });

                            builder.setNegativeButton("取消", null);

                           

                            builder.show();

                           

                           

                     }

              });

             

7、在实现具体的逻辑;

 

 

  int which = sp.getInt("which", 0);

//            "半透明","活力橙","卫士蓝","金属灰","苹果绿"

       int[] bgs = {R.drawable.call_locate_white,R.drawable.call_locate_orange

                            ,R.drawable.call_locate_blue,R.drawable.call_locate_gray,R.drawable.call_locate_green};

             

       view= (View) View.inflate(this, R.layout.toast_address, null);

       view.setBackgroundResource(bgs[which]);

 

 

 



拖动的原理&和实现

 准备:开启低版本(2.3)的模拟题,并且安装金山卫士

 

1、在设置中心布局文件里面(scv_changeposition),增加进入拖动页面,并代码也做处理;

2、创建拖动页面DragViewActivity,并在清单文件注册;

3、DragViewActivity的布局文件activity_drag_view.xml:使用相对布局。布局文件可以把头省略 

4、透明模糊背景已经废弃,消耗资源比较多,用APIDemo/app/activity/

  搜索:Translucent Blur(透明)或者Translucent

5、画图分析原理,分为5个步骤;

 

6、写代码

//给图片注册一个触摸的监听事件

      iv_drag.setOnTouchListener(new OnTouchListener() {

         //记录第一次触屏的坐标

         int startX ;

         int startY;

        

         @Override

         public boolean onTouch(View v,MotionEvent event) {

           

            switch (event.getAction()) {

            //第一次触摸屏幕对应的事件

            case MotionEvent.ACTION_DOWN:

               startX = (int) event.getRawX();

               startY = (int) event.getRawY();

               Log.e(TAG,"第一次触屏的坐标("+startX+","+startY+")");

               break;

              

            //手指在屏幕移动

            case MotionEvent.ACTION_MOVE:

               int newX = (int) event.getRawX();

               int newY = (int) event.getRawY();

               int dx = newX -startX;

               int dy = newY -startY;

               Log.e(TAG,"在屏幕移动的偏移量("+dx+","+dy+")");

               iv_drag.layout(iv_drag.getLeft()+dx,iv_drag.getTop()+dy, iv_drag.getRight()+dx, iv_drag.getBottom()+dy);

               startX = (int)event.getRawX();

               startY = (int) event.getRawY();

               break;

           //手指离开屏幕的瞬间

            case MotionEvent.ACTION_UP:

              

               break;

            }

           

            returntrue;

         }

      });

 

 

 

 

归属地显示位置的修改

 演示拖到边界等效果

1、在手指离开屏幕的瞬间记录位置(保存的是左上角的位置)。

  int lastx = iv_drag.getLeft();

  int lasty =iv_drag.getTop();

  Editor  editor = sp.edit();

  editor.putInt("lastx", lastx);

  editor.putInt("lasty", lasty);

2、打开的时候去取存起来的值并打印出来。

 

3、把上一次的位置设置到控件上;

 iv_drag.layout(lastx, lasty, lastx+iv_drag.getWidth(),lasty+iv_drag.getHeight());

 

该方法不起作用的原因:

大小和位置分配给一个视图和它的所有后代
这是第二个阶段的布局机制。(第一次测量)。在这个阶段,每个父调用布局对所有孩子的位置。这通常是使用存储在的孩子测量测量通过()
派生类不应该重写此方法。有孩子的派生类应该覆盖onLayout。在该方法中,他们应该调用布局在每个孩子。

 在View对象渲染的第二阶段才生效;第一阶段是测量(measure);

 到View类里去看measure方法,搜索:onMeasure

4、用第一阶段生效的方式

       //用一个第一阶段就生效的方式

              LayoutParamsparams = (LayoutParams) iv_drag.getLayoutParams();

       //导包要导相对布局的包

              params.leftMargin = lastx;

              params.topMargin = lasty;

              iv_drag.setLayoutParams(params);

 

5、演示图片拉到遮挡处事一直变小的问题并分析原因,并解决掉;

  解决方式:控制移动坐标

   int newl = iv_drag.getLeft() + dx;

   int newt = iv_drag.getTop() + dy;

   int newr = iv_drag.getRight() + dx;

   int newb = iv_drag.getBottom() + dy;

   if(newl < 0 ||newt < 0 ||newr>windowWidth||newb >(windowHeight-40)){

              break;

       }

 

6、到来电归属地土司去设置显示位置;

 

showMyToast()里加上

params.gravity = Gravity.LEFT+Gravity.TOP;

params.x = sp.getInt("lastx", 0);

params.y = sp.getInt("lasty", 0);

      


两个TextView的交换显示

1、演示金山的效果

2、说一下实现原理;

 

在屏幕移动的事件里和onCreate()两个地方

if(newt>(windowHeight/2)){

                     //显示上面

       tv_top.setVisibility(View.VISIBLE);

       tv_bottom.setVisibility(View.INVISIBLE);

}else{

                                          //显示下面

       tv_top.setVisibility(View.INVISIBLE);

       tv_bottom.setVisibility(View.VISIBLE);

}

 

注意布局文件里面,不能设置为gone,只能设置为invisible

 

多次点击事件的实现

1、双击事件?单位时间内连续点击两次

2、自己实现双击事件写一个android demo

public void click(View view){

      //先记录第一次点击的事件

       //记录第二次的事件了 ,怎么知道是第二次呢?是否有值

      if(firstClickTime >0 ){

         long secondClickTime = SystemClock.uptimeMillis();

         //两次的时间间隔

         long dTime = secondClickTime -firstClickTime;

         if(dTime < 500){

            Toast.makeText(this,"点击两次了", 0).show();

            firstClickTime = 0;

 

   return;

         }

      }

      firstClickTime = SystemClock.uptimeMillis();//开机的时间

      System.out.println("点击了。。");

   }

3、三击事件,导入系统Settings源代码;参照里面代码

4、查找代码--Android 版本  --firmware_version(固件版本)

  代码

  long[] mHits = new long[3];

 

       publicvoid click(View view) {

//            src 原数组

//            srcPos 原数组拷贝的开始位置

//            dst 目标数组

//            dstPos 目标数组的开始位置

//            length 拷贝元素的长度

              System.arraycopy(mHits, 1, mHits, 0,mHits.length - 1);

              mHits[mHits.length - 1] =SystemClock.uptimeMillis();

              if (mHits[0] >=(SystemClock.uptimeMillis() - 500)) {

                     Toast.makeText(this,"是男人",0).show();

              }

 

       }

5、讲解代码,画图分析;

双击事件移植到项目中

 

1、移植代码到点击监听代码里,并演示无法打Log.

2、讲解点击事件和触摸事件的区别:

   触摸事件 :是要你碰到我 就是触摸 包括 碰到 移动 离开一瞬间

   点击事件:    一组动作的组合 包括  按下--停留--离开;其中按下和离开是必须的

3、讲解事件传递的过程;

4、双击居中代码的实现,并保存双击后的值;

  原理图

 

  原理是:左边坐标X屏幕的一半减掉控件的一半,Y轴不变(iv_drag.getTop());

         右边坐标X屏幕的一半加上空间的一半,Y轴不变(iv_drag.getBottom());

 

                            Log.i(TAG, "点击了。。");

                            System.arraycopy(mHits, 1, mHits, 0,mHits.length - 1);

                            mHits[mHits.length - 1] =SystemClock.uptimeMillis();

                            if (mHits[0] >=(SystemClock.uptimeMillis() - 500)) {

                                   Log.i(TAG,"双击了。。");

                                   iv_drag.layout(windowWidth/2-iv_drag.getWidth()/2,iv_drag.getTop(),windowWidth/2+iv_drag.getWidth()/2,iv_drag.getBottom());

                                   intlastx = iv_drag.getLeft();

                                   intlasty = iv_drag.getTop();

                                   Editor  editor = sp.edit();

                                   editor.putInt("lastx",lastx);

                                   editor.putInt("lasty",lasty);

                                   editor.commit();

                            }

                    

 5.存储位置

  int lastx = iv_drag.getLeft();

  int lasty = iv_drag.getTop();

  Editor  editor = sp.edit();

  editor.putInt("lastx", lastx);

  editor.putInt("lasty", lasty);

  editor.commit();

 

 

桌面和任何地方上移动的View对象

1、在AddressService里的showMyToast()设置土司可以触摸。

   把WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE去掉;

   把params.type修改成对应值

     TYPE_PRIORITY_PHONE

 电话优先,当锁屏时显示。此窗口不能获得输入焦点,否则影响锁屏。

    

2、需要加权限:

     android.permission.SYSTEM_ALERT_WINDOW

3、写代码更改在屏幕的位置,设置监听触摸事件

 public boolean onTouch(View v, MotionEvent event) {

                            System.out.println("onTouch()..");

                            switch (event.getAction()) {

                            case MotionEvent.ACTION_DOWN:

                                   startX= (int) event.getRawX();

                                   startY= (int) event.getRawY();

                                   break;

 

                            case MotionEvent.ACTION_MOVE:

                                   intnewX = (int) event.getRawX();

                                   intnewY = (int) event.getRawY();

                                   intdX = newX - startX;

                                   intdY = newY - startY;

                                   params.x = params.x +dX;

                                   params.y = params.y +dY;

//                                 params.x+=dX;

//                                 params.y+=dY;

//参数定义成类的成员变量

                                   wm.updateViewLayout(view, params);

                                   //重新初始化初始位置

                                   startX= (int) event.getRawX();

                                   startY= (int) event.getRawY();

 

                                   break;

                                  

                            case MotionEvent.ACTION_UP:

 

                                   break;

                            }

4、更新位置代码

 params.x = params.x +dX;

 params.y = params.y +dY;

 //params.x +=dX;

 //params.y +=dY;

 wm.updateViewLayout(view, params);

 

5、在离开事件地方保存拖动的位置

   Editor editor = sp.edit();

       editor.putInt("lastx", params.x);

       editor.putInt("lasty", params.y);

       editor.commit();

 

6、解决在屏幕一直往左拖动或者往右拖动的问题;在移动的地方

 

 

  如何理解这段代码,找不合法的边界,赋值成合法;

 

             if(params.x < 0){

                            params.x = 0;

                     }

 

                     if(params.y< 0){

                            params.y = 0;

                     }

画图理解,原理

                 屏幕的宽减掉控件的宽  

                     if(params.x> wm.getDefaultDisplay().getWidth()-view.getWidth()){

                            params.x = wm.getDefaultDisplay().getWidth()-view.getWidth();

                     }

屏幕的高减掉控件的高

                     if(params.y> wm.getDefaultDisplay().getHeight()-view.getHeight()){

                            params.y =wm.getDefaultDisplay().getHeight()-view.getHeight();

                     }

 

小火箭

准备:在另外一个模拟器(arm的架构)安装腾讯管家

1、命令: adb -s emulator-5554 install D:\手机卫士\day5\com.tencent

.qqpimsecure.1342757679068.apk

例如:

C:\Users\Administrator>adb -semulator-5554 install D:\手机卫士\day5\com.tencent

.qqpimsecure.1342757679068.apk

 

2、演示腾讯的小火箭(rocket)

 

3、创建一个工程:小火箭(com.itheima.rocket)

 

4、在工程清单文件里配置成透明的Activity

android:theme="@android:style/Theme.Translucent.NoTitleBar"

腾讯工程里小火箭图片:drawable_hdpi目录下拷贝两张图片

 

5、写布局文件(逐帧动画);

看文档参照(devolop/APIGuides/App Resources/Resource Types/Animation/Frameanimation

 

 

布局文件:rocket.xml

<animation-listxmlns:android="http://schemas.android.com/apk/res/android"

    android:oneshot="false">

    <item android:drawable="@drawable/desktop_rocket_launch_1"android:duration="200"/>

    <item android:drawable="@drawable/desktop_rocket_launch_2"android:duration="200"/>

</animation-list>

代码播放逐帧动画:

 

rocketImage.setBackgroundResource(R.drawable.rocket);

 

rocketAnimation = (AnimationDrawable) rocketImage.getBackground();

rocketAnimation.start();

 

 

6、写拖动代码;

 

                            switch (event.getAction()) {

                            case MotionEvent.ACTION_DOWN:

                                   startX= (int) event.getRawX();

                                   startY= (int) event.getRawY();

 

                                   break;

 

                            case MotionEvent.ACTION_MOVE:

                                   intnewX = (int) event.getRawX();

                                   intnewY = (int) event.getRawY();

                                   intdx = newX - startX;

                                   intdy = newY- startY;

                                   iv_rocket.layout(iv_rocket.getLeft()+dx,iv_rocket.getTop()+dy,iv_rocket.getRight()+dx, iv_rocket.getBottom()+dy);

                                  

                                   startX= (int) event.getRawX();

                                   startY= (int) event.getRawY();

 

                                   break;

 

                            }

                            return true;

7、烟雾实现,在布局文件里面

<ImageView

        android:visibility="invisible"

        android:layout_alignParentBottom="true"

        android:src="@drawable/desktop_smoke_m"

        android:id="@+id/tv_m"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        />

   

     <ImageView

        android:visibility="invisible"

        android:layout_above="@id/tv_m"

        android:src="@drawable/desktop_smoke_t"

        android:id="@+id/tv_top"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        />

8、火箭发送架代码,在手指离开屏幕处加上代码

                    int left =iv_rocket.getLeft();

                                   inttop = iv_rocket.getTop();

                                   intright = iv_rocket.getRight();

                                   if(left>100 && top >300 && right< 220){

                                          Toast.makeText(getApplicationContext(),"火箭发送",0).show();

                                   }

9、发生火箭代码:

 protected void sendRocket() {

              new Thread(){

                     publicvoid run() {

                            int startY = 380;

                            for(int i = 0 ;i< 10; i++){

                                   try{

                                          Thread.sleep(50);

                                   }catch (InterruptedException e) {

                                          e.printStackTrace();

                                   }

                                   //更新UI

                                   Messagemsg = Message.obtain();

                                   msg.obj=startY - i*38;

                                   handler.sendMessage(msg);

                            }

                     };

              }.start();

             

       }

10、更新火箭坐标代码

  private Handler handler = new Handler(){

        public voidhandleMessage(android.os.Message msg) {

            int position =(Integer) msg.obj;

            iv_rocket.layout(iv_rocket.getLeft(),position,iv_rocket.getRight(), position+iv_rocket.getHeight());

        };

    };

                    

11、烟雾系统底部代码

                    tv_top.setVisibility(View.VISIBLE);

                                          AlphaAnimation aa = newAlphaAnimation(0.0f, 1.0f);

                                          aa.setDuration(500);

                     //播放重复次数

                                          aa.setRepeatCount(1);

// 重复的类型 RESTART - 每次从头开始播放动画 REVERSE - 反向播放动画

                                          aa.setRepeatMode(AlphaAnimation.REVERSE);

              // 保持动画后的状态

                                          aa.setFillAfter(true);

                                          tv_top.startAnimation(aa);

 

12、冒烟上面部分系统

       

   if (position < 320) {

      //显示顶部冒烟动画

      AlphaAnimation aa = new AlphaAnimation(0.0f,1.0f);

      aa.setDuration(300);

      iv_top.startAnimation(aa);

           

   }

      //隐藏顶部冒烟代码

   if (position < 20) {

      AlphaAnimation aa = new AlphaAnimation(1.0f,0.0f);

      aa.setDuration(300);

      aa.setFillAfter(true);

      iv_top.startAnimation(aa);

   }

 

知识拓展:

 

 

0 0