模仿360安全卫士项目笔记5


42_自定义土司显示归属地_26

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

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 = new WindowManager.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、处理电话挂断情形

case TelephonyManager.CALL_STATE_IDLE:

if(view != null){

 wm.removeView(view);

 view = null;

}

break;

 

 

 

5、演示

 

 

 

43_更改归属地的背景风格_30

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

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(new OnClickListener() {

@Override

public void onClick(View v) {

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

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

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

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

@Override

public void 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]);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

44_拖动的原理&和实现_42

 准备:开启低版本(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;

}

return true;

}

});

  

 

 

 

45_归属地显示位置的修改_35

 演示拖到边界等效果

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、用第一阶段生效的方式

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

LayoutParams params = (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);

 

 

 

 

46_两个TextView的交换显示_8

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

 

47_多次点击事件的实现_25

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];

 

public void 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、讲解代码,画图分析;

 

48_双击事件移植到项目中_25

 

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());

int lastx = iv_drag.getLeft();

int lasty = 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();

 

 

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

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:

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

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

int dX = newX - startX;

int dY = 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();

}

 

50_小火箭_36

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

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

.qqpimsecure.1342757679068.apk

例如:

C:\Users\Administrator>adb -s emulator-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/API Guides/App Resources/Resource Types/Animation/Frame animation

 

 

布局文件:rocket.xml

<animation-list xmlns: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:

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

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

int dx = newX - startX;

int dy = 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();

int top = iv_rocket.getTop();

int right = iv_rocket.getRight();

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

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

}

9、发生火箭代码:

 protected void sendRocket() {

new Thread(){

public void run() {

int startY = 380;

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

try {

Thread.sleep(50);

} catch (InterruptedException e) {

e.printStackTrace();

}

//更新UI

Message msg = Message.obtain();

msg.obj =startY - i*38;

handler.sendMessage(msg);

}

};

}.start();

}

10、更新火箭坐标代码

  private Handler handler = new Handler(){

public void handleMessage(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 = new AlphaAnimation(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);

}

 

知识拓展:

 

 





---------------------------------------------------------------------------------------------------------------------------------------------------------

</pre>Activity启动模式</h2><div></div><div><span style="color:rgb(51,51,51); font-family:'Microsoft YaHei',Verdana,sans-serif,宋体; font-size:14px; line-height:22px">1.在service中启动Activity时,需要为intent设置一个flags为Intent.FLAG_ACTIVITY_NEW_TASK.启动这个栈来存放activity</span></div><div><span style="color:rgb(51,51,51); font-family:'Microsoft YaHei',Verdana,sans-serif,宋体; font-size:14px; line-height:22px"></span><div class="post" style="padding:0px; margin:5px 0px 0px; font-size:10.5pt; line-height:22px; overflow:hidden; color:rgb(51,51,51); font-family:'Microsoft YaHei',Verdana,sans-serif,宋体">2.Activity半透明效果,指定透明主题,给布局文件加上半透明背景颜色</div><pre style="padding:0px; margin-top:5px; margin-bottom:10px; color:rgb(51,51,51); font-size:13px; background-color:rgb(255,255,255)"><code class="xml hljs " style="padding:0.5em; margin:0px; display:block; background-color:rgb(240,240,240); color:black">android:theme="@android:style/Theme.Translucent.NoTitleBar"</code>


N击事件的实现.

final long[] mHits = new long[2];// 点击的次数
  ivDrag.setOnClickListener(new OnClickListener() {

  @Override
  public void onClick(View v) {
  System.arraycopy(mHits, 1, mHits, 0, mHits.length - 1);
  mHits[mHits.length - 1] = SystemClock.uptimeMillis();// 开机后开始计算的时间
  if (mHits[0] >= (SystemClock.uptimeMillis() - 500)) {// 500表示点击总次数共用的时间小于500ms
  Toast.makeText(DragViewActivity.this, "ok",
    Toast.LENGTH_SHORT).show();
  // 业务逻辑的实现,图片居中
  ivDrag.layout(winWidth / 2 - ivDrag.getWidth() / 2,
    ivDrag.getTop(), winWidth / 2 + ivDrag.getWidth()
    / 2, ivDrag.getBottom());

  }
  }
});










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值