您的位置:首页 > 其它

21、高级工具--来电归属地提示框的位置设置

2014-01-14 17:04 176 查看
创建设置提示框位置的activity:DragViewActivity以及布局文件。

代码:

package com.example.mobilesafe;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
* Created by sing on 14-1-14.
* desc:
*/
public class DragViewActivity extends Activity {

public static final String TAG = "DragViewActivity";

private SharedPreferences sp;

private View rl_drag_view;
private ImageView iv_drag_view;
private TextView tv_drag_view;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dragview_layout);
sp = getSharedPreferences("config", MODE_PRIVATE);

rl_drag_view = findViewById(R.id.rl_drag_view);
iv_drag_view = (ImageView) findViewById(R.id.iv_drag_view);
tv_drag_view = (TextView) findViewById(R.id.tv_drag_view);

InitControls();

iv_drag_view.setOnTouchListener(new View.OnTouchListener() {

int startx = 0;
int starty = 0;
int parentLeft = 0;
int parentTop = 0;
int parentRight = 0;
int parentBottom = 0;

int boundaryHeight = 0;

@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i(TAG, "按下");
startx = (int) motionEvent.getRawX();
starty = (int) motionEvent.getRawY();

parentLeft = rl_drag_view.getLeft();
parentTop = rl_drag_view.getTop();
parentRight = rl_drag_view.getRight();
parentBottom = rl_drag_view.getBottom();

boundaryHeight = (parentBottom - parentTop) / 2;
break;
case MotionEvent.ACTION_MOVE:
int x = (int) motionEvent.getRawX();
int y = (int) motionEvent.getRawY();
int dx = x - startx;
int dy = y - starty;
int offsetX = 0;
int offsetY = 0;
int l = iv_drag_view.getLeft() + dx;
int t = iv_drag_view.getTop() + dy;
int r = iv_drag_view.getRight() + dx;
int b = iv_drag_view.getBottom() + dy;

//边界判断及微调
if (l < parentLeft) {
offsetX = parentLeft - l;
}
if (r > parentRight) {
offsetX = parentRight - r;
}
if (t < parentTop) {
offsetY = parentTop - t;
}
if (b > parentBottom) {
offsetY = parentBottom - b;
}

int newLeft = l + offsetX;
int newTop = t + offsetY;
int newRight = r + offsetX;
int newBottom = b + offsetY;
//iv_drag_view.layout(newLeft, newTop, newRight, newBottom);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.leftMargin = newLeft;
params.topMargin = newTop;
params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
iv_drag_view.setLayoutParams(params);

if (newTop + (newBottom - newTop) / 2 >= boundaryHeight) {
setTipOnMidTop();
}else {
setTipOnMidBottom();
}

startx = x;
starty = y;
break;
case MotionEvent.ACTION_UP:
Log.i(TAG, "松开");
SharedPreferences.Editor editor = sp.edit();
editor.putInt("showCallPosX", iv_drag_view.getLeft());
editor.putInt("showCallPosY", iv_drag_view.getTop());
editor.commit();
break;
}

return true;
}
});
}

private void InitControls() {
int width = getWindowManager().getDefaultDisplay().getWidth();
int height = getWindowManager().getDefaultDisplay().getHeight();
//        int parentLeft = rl_drag_view.getLeft();
//        int parentTop = rl_drag_view.getTop();
//        int parentRight = rl_drag_view.getRight();
//        int parentBottom = rl_drag_view.getBottom();
int boundaryHeight = height / 2;

int l = tv_drag_view.getLeft();
int t = tv_drag_view.getTop();
int r = tv_drag_view.getRight();
int b = tv_drag_view.getBottom();

int midX = (width - (r - l)) / 2;
int midY = (height - (b - t)) / 2;
int showCallPosX = sp.getInt("showCallPosX", midX);
int showCallPosY = sp.getInt("showCallPosY", midY);
if (showCallPosX < 0) {
showCallPosX = 0;
}
if (showCallPosX > width) {
showCallPosX = width;
}
if (showCallPosY < 0) {
showCallPosY = 0;
}
if (showCallPosY > height) {
showCallPosY = height;
}

RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) iv_drag_view.getLayoutParams();
params.leftMargin = showCallPosX;
params.topMargin = showCallPosY;
params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
iv_drag_view.setLayoutParams(params);

if (showCallPosY + (b - t) / 2 >= boundaryHeight) {
setTipOnMidTop();
} else {
setTipOnMidBottom();
}
}

private void setTipOnMidTop() {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
tv_drag_view.setLayoutParams(params);
}

private void setTipOnMidBottom() {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
tv_drag_view.setLayoutParams(params);
}
}


布局文件:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:id="@+id/rl_drag_view">
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/change_locate"
android:layout_centerHorizontal="true"
android:id="@+id/iv_drag_view" />
<TextView style="@style/content_text"
android:text="按住提示框拖动任意位置\n按手机返回键立刻生效"
android:background="@drawable/call_locate_blue"
android:id="@+id/tv_drag_view"
android:layout_centerHorizontal="true" />
</RelativeLayout>


这里要说的是,因为实现效果是移动ImageView来设置显示框位置,并且实现水平居中显示,这里图片上显示的是“双击居中”,但是都是为了实现水平居中,最终并没有采取处理双击事件的方法来使其居中,而是直接在移动的时候就让它在水平方向上居中,使用的代码是:

RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.leftMargin = newLeft;
params.topMargin = newTop;
  params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
iv_drag_view.setLayoutParams(params);
如果不想限制ImageView在移动过程中的水平方向上的位置,那么只需要:

RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.leftMargin = newLeft;
params.topMargin = newTop;
iv_drag_view.setLayoutParams(params);

以上代码有边界判断,使得ImageView只能在屏幕范围内部移动。并且当ImageView在屏幕上半部分时TIP框在底部显示,当ImageView在屏幕下半部分时TIP框在顶部显示。

这里设置TIP的位置有个讨巧的地方,就是巧妙地使用布局参数:RelativeLayout.LayoutParams,来设置TIP水平居中,靠顶或者靠底部显示。

另外需要注意的地方是:

RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
也就是布局参数都是重新构造的,避免参数的累加效果。

另外在onCreate中中获取控件的布局大小均为0,因此获取布局父容器的高度和宽度就靠获取屏幕大小来代替:

int width = getWindowManager().getDefaultDisplay().getWidth();
int height = getWindowManager().getDefaultDisplay().getHeight();


在设置中心里添加:

//归属地提示框位置设置
private View rl_setting_show_location_pos;


//归属地提示框位置设置
rl_setting_show_location_pos = findViewById(R.id.rl_setting_show_location_pos);
rl_setting_show_location_pos.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(SettingCenterActivity.this, DragViewActivity.class);
startActivity(intent);
}
});


设置中心完整代码:

package com.example.mobilesafe;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;

import com.example.mobilesafe.service.ShowCallLocationService;
import com.example.utils.ServiceStatusUtil;

/**
* Created by sing on 13-12-24.
* desc:
*/
public class SettingCenterActivity extends Activity {

//背景风格
private static final String[] bg_styles = {"半透明", "活力橙", "卫士蓝", "苹果绿", "金属灰"};

//设置自动更新的checkbox
private View rl_setting_autoupdate;
private CheckBox cb_setting_autoupdate;

//显示自动更新开启状态的文本框
private TextView tv_setting_autoupdate_status;

private View rl_setting_show_location;
private CheckBox cb_setting_showlocation;
private TextView tv_setting_show_location_status;

//来电归属地显示风格
private View rl_setting_showlocation_style;
private TextView tv_setting_showlocation_style;

//归属地提示框位置设置 private View rl_setting_show_location_pos;

//开启来电归属地信息显示的意图
private Intent showLocationIntent;

//保存配置
private SharedPreferences sp;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settingcenter);

tv_setting_autoupdate_status = (TextView) findViewById(R.id.tv_setting_autoupdate_status);
cb_setting_autoupdate = (CheckBox) findViewById(R.id.cb_setting_autoupdate);

//加载上次设置的状态
sp = getSharedPreferences("config", MODE_PRIVATE);
boolean autoupdate = sp.getBoolean("autoupdate", true);
cb_setting_autoupdate.setChecked(autoupdate);
tv_setting_autoupdate_status.setText(autoupdate ? "自动更新已经开启" : "自动更新已经关闭");
tv_setting_autoupdate_status.setTextColor(autoupdate ? Color.WHITE : Color.GRAY);

//为checkbox编写响应事件
rl_setting_autoupdate = findViewById(R.id.rl_setting_autoupdate);
rl_setting_autoupdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
boolean b = !cb_setting_autoupdate.isChecked();
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("autoupdate", b);
editor.commit();
cb_setting_autoupdate.setChecked(b);
tv_setting_autoupdate_status.setText(b ? "自动更新已经开启" : "自动更新已经关闭");
tv_setting_autoupdate_status.setTextColor(b ? Color.WHITE : Color.GRAY);
}
});

//来电归属地设置
showLocationIntent = new Intent(this, ShowCallLocationService.class);
tv_setting_show_location_status = (TextView)findViewById(R.id.tv_setting_show_location_status);
cb_setting_showlocation = (CheckBox) findViewById(R.id.cb_setting_showlocation);
rl_setting_show_location = findViewById(R.id.rl_setting_show_location);
rl_setting_show_location.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (cb_setting_showlocation.isChecked()) {
cb_setting_showlocation.setChecked(false);
tv_setting_show_location_status.setText("来电归属地显示没有开启");
tv_setting_show_location_status.setTextColor(Color.GRAY);
//开启来电归属地显示
stopService(showLocationIntent);
}else{
cb_setting_showlocation.setChecked(true);
tv_setting_show_location_status.setText("来电归属地显示已经开启");
tv_setting_show_location_status.setTextColor(Color.WHITE);
//关闭来电归属地显示
startService(showLocationIntent);
}
}
});

//来电归属地风格设置
tv_setting_showlocation_style = (TextView) findViewById(R.id.tv_setting_showlocation_style);
int style = sp.getInt("which", 0);
tv_setting_showlocation_style.setText(bg_styles[style]);
rl_setting_showlocation_style = findViewById(R.id.rl_setting_showlocation_style);
rl_setting_showlocation_style.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showChooseBgDlg();
}
});

//归属地提示框位置设置
rl_setting_show_location_pos = findViewById(R.id.rl_setting_show_location_pos);
rl_setting_show_location_pos.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(SettingCenterActivity.this, DragViewActivity.class);
startActivity(intent);
}
});

}

@Override
protected void onResume() {
boolean serviceRunning = ServiceStatusUtil.isServiceRunning(this, "com.example.mobilesafe.service.ShowCallLocationService");
cb_setting_showlocation.setChecked(serviceRunning);
tv_setting_show_location_status.setText(serviceRunning ? "来电归属地显示已经开启" : "来电归属地显示没有开启");
tv_setting_show_location_status.setTextColor(serviceRunning ? Color.WHITE : Color.GRAY);

super.onResume();
}

//选择背景颜色对话框
private void showChooseBgDlg() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setIcon(R.drawable.notification);
builder.setTitle("归属地提示框风格");
int which = sp.getInt("which", 0);
builder.setSingleChoiceItems(bg_styles,which,new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
SharedPreferences.Editor editor = sp.edit();
editor.putInt("which", i);
editor.commit();
tv_setting_showlocation_style.setText(bg_styles[i]);
dialogInterface.dismiss();
}
});

builder.setNegativeButton("取消",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});

builder.create().show();
}
}
运行效果图:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: