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