android自定义View及事件
直接如题,本例效果如下图,继承自ImageView,后面画了个圆,圆的大小在布局文件设置,点击圆内会有事件相应,圆外无响应。
先看自定义的MyView代码
package test.bg;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.ImageView;
publicclass MyView extends ImageView implements OnGlobalLayoutListener
{
privateint radius = 0;
private RectF rectF = null;
private test.bg.OnTouchListener mOnTouchListener=null;
public MyView(Context context)
{
super(context);
TypedArray ta = context.obtainStyledAttributes(R.styleable.MyView);
radius = ta.getDimensionPixelSize(R.styleable.MyView_radius, 0);
rectF = new RectF(0, 0, 2 * radius, 2 * radius);
ta.recycle();
ViewTreeObserver vto = getViewTreeObserver();
vto.addOnGlobalLayoutListener(this);
}
public MyView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
TypedArray ta = context.obtainStyledAttributes(attrs,
R.styleable.MyView);
radius = ta.getDimensionPixelSize(R.styleable.MyView_radius, 0);
rectF = new RectF(0, 0, 2 * radius, 2 * radius);
ta.recycle();
ViewTreeObserver vto = getViewTreeObserver();
vto.addOnGlobalLayoutListener(this);
}
public MyView(Context context, AttributeSet attrs)
{
super(context, attrs);
TypedArray ta = context.obtainStyledAttributes(attrs,
R.styleable.MyView);
radius = ta.getDimensionPixelSize(R.styleable.MyView_radius, 0);
rectF = new RectF(0, 0, 2 * radius, 2 * radius);
ta.recycle();
ViewTreeObserver vto = getViewTreeObserver();
vto.addOnGlobalLayoutListener(this);
}
publicvoid setOnTouchListener(test.bg.OnTouchListener mOnTouchListener){
this.mOnTouchListener=mOnTouchListener;
}
@Override
protectedvoid onDraw(Canvas canvas)
{
Paint p = new Paint();
p.reset();
p.setARGB(255, 255, 0, 0);
canvas.drawRoundRect(rectF, radius, radius, p);
super.onDraw(canvas);
}
@Override
publicvoid onGlobalLayout()
{
LayoutParams lp = getLayoutParams();
lp.height = 2 * radius;
lp.width = 2 * radius;
setLayoutParams(lp);
}
@Override
publicboolean onTouchEvent(MotionEvent event)
{
float x = event.getX();
float y = event.getY();
if ((x-radius)*(x-radius)+(y-radius)*(y-radius)<radius*radius)
{
Log.d("nei", ""+x+":"+y);
return mOnTouchListener.onTouchEvent(this, event);
}
else
{
Log.d("wai", ""+x+":"+y);
returnfalse;
}
}
}
radius = ta.getDimensionPixelSize(R.styleable.MyView_radius, 0);
涉及到的代码事先在res/valus下新建attrs.xml并加入内容
<?xmlversion="1.0"encoding="utf-8"?>
<resources>
<declare-styleablename="MyView">
<attrname="radius"format="dimension"/>
</declare-styleable>
</resources>
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:gain="http://schemas.android.com/apk/res/test.bg"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<test.bg.MyView
android:id="@+id/mv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
gain:radius="160dp"
android:src="@drawable/ic_launcher">
</test.bg.MyView>
</LinearLayout>
package test.bg;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
publicclass TestBgActivity extends Activity implements OnTouchListener
{
MyView mv;
/** Called when the activity is first created. */
@Override
publicvoid onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MyView mv = (MyView) findViewById(R.id.mv);
mv.setOnTouchListener(this);
}
@Override
publicboolean onTouchEvent(View v, MotionEvent event)
{
if (v.getId() == R.id.mv)
{
Toast.makeText(this,
"haha:" + v.getId() + ":" + event.getX() + ":"
+ event.getY(),
Toast.LENGTH_SHORT).show();
}
returnfalse;
}
}
package test.bg;
import android.view.MotionEvent;
import android.view.View;
publicinterface OnTouchListener
{
publicboolean onTouchEvent(View v, MotionEvent event);
}
@Override
publicboolean onTouchEvent(MotionEvent event)
{
float x = event.getX();
float y = event.getY();
if ((x-radius)*(x-radius)+(y-radius)*(y-radius)<radius*radius)
{
Log.d("nei", ""+x+":"+y);
return mOnTouchListener.onTouchEvent(this, event);
}
else
{
Log.d("wai", ""+x+":"+y);
returnfalse;
}
}
即事件发生在圆内就触发自定义方法,圆外的直接忽略。
That's all!nice day,isn't it?
转载于:https://blog.51cto.com/rainlee/1275190