Android实现随意拖动View效果的实例代码
项目过程中要实现能在页面中随意的拖动,刚开始实现是用悬浮球的形式进行实现,因为之前项目中用过,实现后发现用户每次安装后,都有权限的限制,甚至有些用户关闭悬浮球权限之后,不知道怎么在手机上打开悬浮球的权限,这样的话用户体验很不好,所以自己重新自定义实现在页面中拖动,不需要请求权限。
自定义随意拖动View:
packagecom.dragdemo;
importandroid.annotation.SuppressLint;
importandroid.content.Context;
importandroid.util.AttributeSet;
importandroid.util.Log;
importandroid.view.MotionEvent;
importandroid.widget.ImageView;
/**
*随意拖动的view
*/
@SuppressLint("AppCompatCustomView")
publicclassDragViewextendsImageView{
privateintwidth;
privateintheight;
privateintscreenWidth;
privateintscreenHeight;
privateContextcontext;
//是否拖动
privatebooleanisDrag=false;
publicbooleanisDrag(){
returnisDrag;
}
publicDragView(Contextcontext,AttributeSetattrs){
super(context,attrs);
this.context=context;
}
@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
width=getMeasuredWidth();
height=getMeasuredHeight();
screenWidth=ScreenUtil.getScreenWidth(context);
screenHeight=ScreenUtil.getScreenHeight(context)-getStatusBarHeight();
}
publicintgetStatusBarHeight(){
intresourceId=getResources().getIdentifier("status_bar_height","dimen","android");
returngetResources().getDimensionPixelSize(resourceId);
}
privatefloatdownX;
privatefloatdownY;
@Override
publicbooleanonTouchEvent(MotionEventevent){
super.onTouchEvent(event);
if(this.isEnabled()){
switch(event.getAction()){
caseMotionEvent.ACTION_DOWN:
isDrag=false;
downX=event.getX();
downY=event.getY();
break;
caseMotionEvent.ACTION_MOVE:
Log.e("kid","ACTION_MOVE");
finalfloatxDistance=event.getX()-downX;
finalfloatyDistance=event.getY()-downY;
intl,r,t,b;
//当水平或者垂直滑动距离大于10,才算拖动事件
if(Math.abs(xDistance)>10||Math.abs(yDistance)>10){
Log.e("kid","Drag");
isDrag=true;
l=(int)(getLeft()+xDistance);
r=l+width;
t=(int)(getTop()+yDistance);
b=t+height;
//不划出边界判断,此处应按照项目实际情况,因为本项目需求移动的位置是手机全屏,
//所以才能这么写,如果是固定区域,要得到父控件的宽高位置后再做处理
if(l<0){
l=0;
r=l+width;
}elseif(r>screenWidth){
r=screenWidth;
l=r-width;
}
if(t<0){
t=0;
b=t+height;
}elseif(b>screenHeight){
b=screenHeight;
t=b-height;
}
this.layout(l,t,r,b);
}
break;
caseMotionEvent.ACTION_UP:
setPressed(false);
break;
caseMotionEvent.ACTION_CANCEL:
setPressed(false);
break;
}
returntrue;
}
returnfalse;
}
}
用到的工具类:
packagecom.dragdemo;
importandroid.content.Context;
importandroid.util.DisplayMetrics;
importandroid.view.Display;
importandroid.view.View;
importandroid.view.WindowManager;
publicclassScreenUtil{
privatestaticintwidth=0;
privatestaticintheight=0;
privatestaticintshowHeight=0;
privatestaticintstatusHeight=0;
privatestaticfloatdensity=0;
publicstaticintgetScreenWidth(Contextcontext){
if(width==0){
WindowManagermanager=(WindowManager)context
.getSystemService(Context.WINDOW_SERVICE);
Displaydisplay=manager.getDefaultDisplay();
width=display.getWidth();
}
returnwidth;
}
publicstaticintgetScreenHeight(Contextcontext){
if(height==0){
WindowManagermanager=(WindowManager)context
.getSystemService(Context.WINDOW_SERVICE);
Displaydisplay=manager.getDefaultDisplay();
height=display.getHeight();
}
returnheight;
}
publicstaticintgetScreenShowHeight(Contextcontext){
if(showHeight==0){
showHeight=getScreenHeight(context)-getStatusBarHeight(context);
}
returnshowHeight;
}
publicstaticintgetStatusBarHeight(Contextcontext){
if(statusHeight>0){
returnstatusHeight;
}
Class>c=null;
Objectobj=null;
java.lang.reflect.Fieldfield=null;
intx=0;
try{
c=Class.forName("com.android.internal.R$dimen");
obj=c.newInstance();
field=c.getField("status_bar_height");
x=Integer.parseInt(field.get(obj).toString());
statusHeight=context.getResources().getDimensionPixelSize(x);
returnstatusHeight;
}catch(Throwablee){
e.printStackTrace();
}
returnstatusHeight;
}
publicstaticfloatgetScreenDensity(Contextcontext){
if(density==0){
try{
DisplayMetricsdm=newDisplayMetrics();
WindowManagermanager=(WindowManager)context
.getSystemService(Context.WINDOW_SERVICE);
manager.getDefaultDisplay().getMetrics(dm);
density=dm.density;
}catch(Exceptionex){
ex.printStackTrace();
density=1.0f;
}
}
returndensity;
}
publicstaticfloatgetScreentMinLength(Contextcontext){
returngetScreenHeight(context)>getScreenWidth(context)?getScreenWidth(context)
:getScreenHeight(context);
}
/**
*根据指定k的系数获取屏幕在max范围内的最大长宽,默认宽比较小
*
*@paramcontext
*@paramk
*@return
*/
publicstaticDrawWrapgetCutWrap(Contextcontext,floatk,floatmax){
floattWidth=getScreenWidth(context);
floattHeight=getScreenHeight(context);
if(tWidth*max*k>tHeight){
returnnewDrawWrap(tHeight*max/k,tHeight*max);
}else{
returnnewDrawWrap(tWidth*max,tWidth*max*k);
}
}
publicstaticclassDrawWrap{
publicfloatwidth;
publicfloatheight;
publicDrawWrap(floatwidth,floatheight){
this.width=width;
this.height=height;
}
}
publicstaticintdip2px(Contextcontext,floatdipValue){
return(int)(dipValue*getScreenDensity(context)+0.5f);
}
/**
*将sp值转换为px值,保证文字大小不变
*
*@paramcontext
*@paramspValue
*(DisplayMetrics类中属性scaledDensity)
*@return
*/
publicstaticintsp2px(Contextcontext,floatspValue){
finalfloatfontScale=context.getResources().getDisplayMetrics().scaledDensity;
return(int)(spValue*fontScale+0.5f);
}
/**
*根据手机的分辨率从px(像素)的单位转成为dp
*/
publicstaticintpx2dip(Contextcontext,floatpxValue){
finalfloatscale=context.getResources().getDisplayMetrics().density;
return(int)(pxValue/scale+0.5f);
}
/**
*获取屏幕中控件顶部位置的高度--即控件顶部的Y点
*
*@return
*/
publicstaticintgetScreenViewTopHeight(Viewview){
returnview.getTop();
}
/**
*获取屏幕中控件底部位置的高度--即控件底部的Y点
*
*@return
*/
publicstaticintgetScreenViewBottomHeight(Viewview){
returnview.getBottom();
}
/**
*获取屏幕中控件左侧的位置--即控件左侧的X点
*
*@return
*/
publicstaticintgetScreenViewLeftHeight(Viewview){
returnview.getLeft();
}
/**
*获取屏幕中控件右侧的位置--即控件右侧的X点
*
*@return
*/
publicstaticintgetScreenViewRightHeight(Viewview){
returnview.getRight();
}
/*
*获取控件宽
*/
publicstaticintgetWidth(Viewview){
intw=View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
inth=View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
view.measure(w,h);
return(view.getMeasuredWidth());
}
/*
*获取控件高
*/
publicstaticintgetHeight(Viewview){
intw=View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
inth=View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
view.measure(w,h);
return(view.getMeasuredHeight());
}
}
XML文件:
MainActivity:
packagecom.dragdemo;
importandroid.support.v7.app.AppCompatActivity;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.widget.Toast;
publicclassMainActivityextendsAppCompatActivity{
DragViewiv_drag;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv_drag=(DragView)findViewById(R.id.iv_drag);
iv_drag.setOnClickListener(newView.OnClickListener(){
@Override
publicvoidonClick(Viewv){
if(!iv_drag.isDrag()){
Toast.makeText(MainActivity.this,"响应点击",Toast.LENGTH_SHORT).show();
}
}
});
}
}
总结
以上所述是小编给大家介绍的Android实现随意拖动View效果的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!