android 点击背景,android实现点击背景图片不同区域实现不同事件

有时候我们拿到一张背景图片,客户要求点击图片的不同区域去跳转或者实现不同的操作事件。我们首先要确认图片的点击区域,往往我们会在布局文件那里下手,但是这样不好做适配,所以我实现了以下方法,基本功能可以实现,而且也做好了适配,可以参考一下。

5fd3270b7a4b

201608121014431586.png

1.找到对应区域的像素点。图片中需要点击的区域是圆,所以只要找到圆心和测量出半径即可(介绍一款图片软件Mark Man),由于得到的是PX,所以要转换为dip(dp=px/2);

arrays.xml

man_hair

man_eye

man_mouth

man_throat

man_mind

man_ear

man_nose

hair

头发

eye

mouth

口腔

throat

咽喉

mind

头/脑

ear

耳朵

nose

30

46

20

30

103

20

30

160

20

30

220

20

289

44

20

289

105

20

289

162

20

2.实现自定义ImageView控件,用来存放图片。

BaseBodyView.java

/**

* 类说明:身体区域

* array必存三个点 圆中心坐标 x,y 半径 r

* Author: gaobaiq

* Date: 2016/7/23 11:22

*/

public abstract class BaseBodyView extends ImageView {

protected Context mContext;

// 保存所有点击区域

private Map mBodyArea ;

// 保存点击的区域

private Set mFocus;

protected Paint paint = new Paint();

// 点击时Path区域的转换,用于触摸点的判断

protected RectF mPathRectF = new RectF();

protected OnBodyClickListener mBodyClick;

public BaseBodyView(Context context) {

this(context, null);

}

public BaseBodyView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public BaseBodyView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

mContext = context;

initDatas();

}

private void initDatas() {

mBodyArea = new HashMap<>();

mFocus = new HashSet<>();

//paint.setStyle(Paint.Style.FILL);

//paint.setARGB(170, 0, 205, 0);

initBodyArea();

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

// 进行触摸区域绘制

//for(String key : mFocus) {

// Path path = mBodyArea.get(key).getPath();

// canvas.drawPath(path, paint);

//}

}

@Override

public boolean onTouchEvent(MotionEvent event) {

if (mBodyClick != null) {

checkAreas(event);

if(!mFocus.isEmpty()) {

BodyArea area = null;

for(String key : mFocus){

area = mBodyArea.get(key);

//invalidate(); // 渲染选中区域颜色

mBodyClick.onBodyClick(0, area.getPtKeys());

}

}

}

return super.onTouchEvent(event);

}

private void checkAreas(MotionEvent event) {

mFocus.clear();

for(String key : mBodyArea.keySet()) {

mPathRectF.setEmpty();

Path path = mBodyArea.get(key).getPath();

path.computeBounds(mPathRectF, true);

if(mPathRectF.contains(event.getX(),event.getY())) {

mFocus.add(key);

break;

}

}

}

public void initBodyArea() {

mBodyArea.clear();

mFocus.clear();

String[] keys = mContext.getResources().getStringArray(initArray());

BodyArea bodyArea = null;

int idenId = -1;

if(keys != null) {

for(String key : keys) {

idenId = mContext.getResources().getIdentifier(key, "array", initPackage());

int[] paths = mContext.getResources().getIntArray(idenId);

idenId = mContext.getResources().getIdentifier(key + "_code", "array", initPackage());

String[] ptKeys = mContext.getResources().getStringArray(idenId);

bodyArea = new BodyArea(ptKeys, paths);

mBodyArea.put(key, bodyArea);

}

}

}

/**

* 进行不同材质机器的兼容

* */

private float toDip(Context context,float pxValue){

final float scale = context.getResources().getDisplayMetrics().density;

return (int) (pxValue * scale + 0.5f);

}

protected abstract int initArray();

protected abstract String initPackage();

/**

* 点击事件抽象方法

*/

public void setOnBodyClickListener(OnBodyClickListener listener) {

this.mBodyClick = listener;

}

public interface OnBodyClickListener {

void onBodyClick(int position, String[] keys);

}

/**

* 圆形区域对象

* */

class BodyArea {

private String[] mPtKeys;

private Path mPath;

public BodyArea(String[] ptKeys, int[] paths) {

super();

this.mPtKeys = ptKeys;

mPath = new Path();

int len = paths.length;

if (len >= 3) {

mPath.addCircle(toDip(mContext, paths[0]), toDip(mContext,

paths[1]), toDip(mContext, paths[2]),

Path.Direction.CW);

}

mPath.close();

}

public String[] getPtKeys() {

return mPtKeys;

}

public void setPtKeys(String[] ptKeys) {

this.mPtKeys = ptKeys;

}

public Path getPath() {

return mPath;

}

}

}

ManHeadView.java

/**

* 类说明:男头部图片区域点击

* 自定义控件命名要与array的一样

* Author: gaobaiq

* Date: 2016/7/22 10:00

*/

public class ManHeadView extends BaseBodyView {

public ManHeadView(Context context) {

this(context, null);

}

public ManHeadView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public ManHeadView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

@Override protected int initArray() {

return R.array.man_head;

}

@Override protected String initPackage() {

return mContext.getPackageName();

}

}

3.布局(切记android:scaleType="matrix")

xmlns:android="http://schemas.android.com/apk/res/android"

android:background="@color/white"

android:layout_height="match_parent"

android:layout_width="match_parent"

android:orientation="vertical" >

android:id="@+id/img_head"

android:layout_gravity="center"

android:layout_height="wrap_content"

android:layout_width="wrap_content"

android:scaletype="matrix"

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

4.实现方法

mImgHead.setOnBodyClickListener(new ManHeadView.OnBodyClickListener() {

@Override public void onBodyClick(int position, String[] keys) {

String message ="Code:" + keys[0] + ", Name:" + keys[1];

ToastUtils.ToastMessage(getActivity(), message);

}

});

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值