Android实现GridView中的item自由拖动效果
之前的工作中,需要实现一个功能就是GridView中的item可以自由拖动,思考了一下,其实实现起来不是很困难,主要工作就是交换节点,以及拖动时的移动效果,下面讲讲具体的实现:
首先声明一个BaseAdapter:
packagecom.dafasoft.dragablegridview; importandroid.content.Context; importandroid.view.LayoutInflater; importandroid.view.View; importandroid.view.ViewGroup; importandroid.widget.AbsListView; importandroid.widget.AdapterView; importandroid.widget.BaseAdapter; importjava.util.ArrayList; importjava.util.List; /** *Createdbyzhangyulongon16/9/22. */ publicabstractclassBaseDragableAdapter<T>extendsBaseAdapter{ protectedList<T>mList; protectedContextmContext; protectedLayoutInflatermInflater; //初始化需隐藏的位置信息 protectedintmHidePosition=AdapterView.INVALID_POSITION; publicBaseDragableAdapter(Contextcontext){ this.mContext=context; this.mInflater=LayoutInflater.from(context); mList=newArrayList<T>(); } @Override publicintgetCount(){ returnmList==null?0:mList.size(); } @Override publicObjectgetItem(inti){ returnmList==null?0:mList.get(i); } @Override publiclonggetItemId(inti){ returni; } @Override publicabstractViewgetView(inti,Viewview,ViewGroupviewGroup); publicvoidsetList(List<T>list){ if(this.mList!=null)this.mList.clear();//避免脏数据 if(list==null){ return; } this.mList=list; } publicvoidsetList(T[]list){ ArrayList<T>arrayList=newArrayList<T>(list.length); for(Tt:list){ arrayList.add(t); } setList(arrayList); } publicList<T>getList(){ returnthis.mList; } publicvoidaddAll(List<T>list){ if(list==null||list.size()==0)return; this.mList.addAll(list); } publicvoidaddAll(intlocation,List<T>list){ if(list==null||list.size()==0)return; this.mList.addAll(location,list); } publicvoidclean(){ if(getCount()==0)return; mList.clear(); } publicvoidhideView(intposition){ mHidePosition=position; notifyDataSetChanged(); } publicvoidshowHideView(){ //重置hideposition mHidePosition=AdapterView.INVALID_POSITION; notifyDataSetChanged(); } /** *交换节点 *@paramdraggedPos拖拽的起始节点 *@paramcurrentPos拖拽的当前节点 */ publicvoidswapView(intdraggedPos,intcurrentPos){ //从前往后拖 if(draggedPos<currentPos){ //将被拖拽的节点移动至当前节点 mList.add(currentPos+1,mList.get(draggedPos)); //删除拖拽前的节点 mList.remove(draggedPos); } //从后往前拖 elseif(draggedPos>currentPos){ //将被拖拽的节点移动至当前节点 mList.add(currentPos,mList.get(draggedPos)); //删除拖拽前的节点 mList.remove(draggedPos+1); } mHidePosition=currentPos; notifyDataSetChanged(); } }
其次实现DragableGridView:
packagecom.dafasoft.dragablegridview; importandroid.content.Context; importandroid.graphics.Bitmap; importandroid.graphics.PixelFormat; importandroid.util.AttributeSet; importandroid.util.Log; importandroid.view.Gravity; importandroid.view.MotionEvent; importandroid.view.View; importandroid.view.WindowManager; importandroid.widget.AdapterView; importandroid.widget.GridView; importandroid.widget.ImageView; /** *Createdbyzhangyulongon16/9/22. */ publicclassDragableGridViewextendsGridView{ privatestaticfinalintDRAG_IMG_SHOW=1; privatestaticfinalintDRAG_IMG_NOT_SHOW=0; privatestaticfinalStringLOG_TAG="DragGridView"; privatestaticfinalfloatAMP_FACTOR=1.2f; privateImageViewdragImageView; privateWindowManager.LayoutParamsdragImageViewParams; privateWindowManagerwindowManager; privatebooleanisViewOnDrag=false; /**previousdraggedoverposition*/ privateintpreDraggedOverPositon=AdapterView.INVALID_POSITION; privateintdownRawX; privateintdownRawY; publicDragableGridView(Contextcontext){ super(context); initView(); } publicDragableGridView(Contextcontext,AttributeSetattrs){ super(context,attrs); initView(); } publicDragableGridView(Contextcontext,AttributeSetattrs,intdefStyleAttr){ super(context,attrs,defStyleAttr); initView(); } publicvoidinitView(){ setOnItemLongClickListener(mOnItemLongClickListener); //setOnItemClickListener(onItemClickListener); //setOnItemSelectedListener(onItemSelectedListener); //初始化显示被拖动item的imageview dragImageView=newImageView(getContext()); dragImageView.setTag(DRAG_IMG_NOT_SHOW); //初始化用于设置dragImageView的参数对象 dragImageViewParams=newWindowManager.LayoutParams(); //获取窗口管理对象,用于后面向窗口中添加dragImageView windowManager=(WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE); } privateOnItemLongClickListenermOnItemLongClickListener=newOnItemLongClickListener(){ @Override publicbooleanonItemLongClick(AdapterView<?>parent,Viewview,intposition,longid){ //记录长按item位置 preDraggedOverPositon=position; //获取被长按item的drawingcache view.destroyDrawingCache(); view.setDrawingCacheEnabled(true); //通过被长按item,获取拖动item的bitmap BitmapdragBitmap=Bitmap.createBitmap(view.getDrawingCache()); //设置拖动item的参数 dragImageViewParams.gravity=Gravity.TOP|Gravity.LEFT; //设置拖动item为原item1.2倍 dragImageViewParams.width=(int)(AMP_FACTOR*dragBitmap.getWidth()); dragImageViewParams.height=(int)(AMP_FACTOR*dragBitmap.getHeight()); //设置触摸点为绘制拖动item的中心 dragImageViewParams.x=(downRawX-dragImageViewParams.width/2); dragImageViewParams.y=(downRawY-dragImageViewParams.height/2); dragImageViewParams.flags=WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; //设置窗口支持透明度 dragImageViewParams.format=PixelFormat.TRANSLUCENT; dragImageViewParams.windowAnimations=0; //dragImageView为被拖动item的容器,清空上一次的显示 if((int)dragImageView.getTag()==DRAG_IMG_SHOW){ windowManager.removeView(dragImageView); dragImageView.setTag(DRAG_IMG_NOT_SHOW); } //设置本次被长按的item dragImageView.setImageBitmap(dragBitmap); //添加拖动item到屏幕 windowManager.addView(dragImageView,dragImageViewParams); dragImageView.setTag(DRAG_IMG_SHOW); isViewOnDrag=true; //设置被长按item不显示 ((BaseDragableAdapter)getAdapter()).hideView(position); returntrue; } }; @Override publicbooleanonTouchEvent(MotionEventev){ //被按下时记录按下的坐标 if(ev.getAction()==MotionEvent.ACTION_DOWN){ //获取触摸点相对于屏幕的坐标 downRawX=(int)ev.getRawX(); downRawY=(int)ev.getRawY(); } //dragImageView处于被拖动时,更新dragImageView位置 elseif((ev.getAction()==MotionEvent.ACTION_MOVE)&&(isViewOnDrag==true)){ Log.i(LOG_TAG,""+ev.getRawX()+""+ev.getRawY()); //设置触摸点为dragImageView中心 dragImageViewParams.x=(int)(ev.getRawX()-dragImageView.getWidth()/2); dragImageViewParams.y=(int)(ev.getRawY()-dragImageView.getHeight()/2); //更新窗口显示,移动dragImageView的位置 windowManager.updateViewLayout(dragImageView,dragImageViewParams); //获取当前触摸点的itemposition intcurrDraggedPosition=pointToPosition((int)ev.getX(),(int)ev.getY()); //如果当前停留位置item不等于上次停留位置的item,交换本次和上次停留的item if((currDraggedPosition!=AdapterView.INVALID_POSITION)&&(currDraggedPosition!=preDraggedOverPositon)){ ((BaseDragableAdapter)getAdapter()).swapView(preDraggedOverPositon,currDraggedPosition); preDraggedOverPositon=currDraggedPosition; } } //释放dragImageView elseif((ev.getAction()==MotionEvent.ACTION_UP)&&(isViewOnDrag==true)){ ((BaseDragableAdapter)getAdapter()).showHideView(); if((int)dragImageView.getTag()==DRAG_IMG_SHOW){ windowManager.removeView(dragImageView); dragImageView.setTag(DRAG_IMG_NOT_SHOW); } isViewOnDrag=false; } returnsuper.onTouchEvent(ev); } }
实现一个adapter继承自BaseDragableAdapter:
packagecom.dafasoft.dragablegridview; importandroid.content.Context; importandroid.view.LayoutInflater; importandroid.view.View; importandroid.view.ViewGroup; importandroid.widget.TextView; /** *Createdbyzhangyulongon16/9/22. */ publicclassMyAdapterextendsBaseDragableAdapter<String>{ publicMyAdapter(Contextcontext){ super(context); } @Override publicViewgetView(inti,Viewview,ViewGroupviewGroup){ ViewHolderviewHolder; if(view==null){ viewHolder=newViewHolder(); view=mInflater.inflate(R.layout.adapter_my,null); viewHolder.mItemTv=(TextView)view.findViewById(R.id.tv_item); view.setTag(viewHolder); }else{ viewHolder=(ViewHolder)view.getTag(); } if(mHidePosition==i){ view.setVisibility(View.GONE); }else{ view.setVisibility(View.VISIBLE); } viewHolder.mItemTv.setText(mList.get(i)); returnview; } classViewHolder{ TextViewmItemTv; } }
在activity中使用:
packagecom.dafasoft.dragablegridview; importandroid.app.Activity; importandroid.support.v7.app.AppCompatActivity; importandroid.os.Bundle; importjava.util.ArrayList; importjava.util.List; publicclassMainActivityextendsActivity{ privateDragableGridViewmDragableGv; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mDragableGv=(DragableGridView)findViewById(R.id.drag_grid_view); MyAdapteradapter=newMyAdapter(this); List<String>list=newArrayList<String>(); for(inti=0;i<30;i++){ list.add("position"+i); } adapter.setList(list); mDragableGv.setAdapter(adapter); } }
以上所述是小编给大家介绍的Android实现GridView中的item自由拖动效果,实现一个模拟后台数据登入的效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!