gridviewsort.gif
如何实现拖拽一个Item
用WindowManager添加一个ImageView,并且将这个ImageView的显示图片设置成被拖拽item的截图,截图可以通过View的getDrawingCache获得。拖拽的时候,隐藏原始的item。处理触摸事件的ActionMove,调整ImageView的位置,跟随手指移动。在ActionUp的时候removeView
GridView
@Overridepublic boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l){// 至少有两个item的时候,才有排序if (getChildCount() >= 2){mView = view;// 在调用getDrawingCache必须先调用view.setDrawingCacheEnabled(true);// 获取截图并设置Bitmap bitmap = view.getDrawingCache();mDragItemView.setImageBitmap(bitmap);// 设置拖拽的imageview的paramsmDragItemLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;mDragItemLayoutParams.width = bitmap.getWidth();mDragItemLayoutParams.height = bitmap.getHeight();mDragItemLayoutParams.x = (mDownX - mDragItemLayoutParams.width / 2);mDragItemLayoutParams.y = (mDownY - mDragItemLayoutParams.height / 2);// 设置拖拽imageview的中心位于长按点击点mDragItemLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE //不接受按键事件| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE // 不接收触摸事件| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON// 保持常亮| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; // place the window within the entire screen, ignoring decorations around the border (such as the status bar)mDragItemLayoutParams.format = PixelFormat.TRANSLUCENT;mDragItemLayoutParams.windowAnimations = 0;// 往WindowManager中添加拖拽的ViewmWindowManager.addView(mDragItemView, mDragItemLayoutParams);((GridViewSortAdapter) getAdapter()).init();((GridViewSortAdapter) getAdapter()).hideView(i);Log.d(TAG, "long click = " + i);mDragStarted = true;}return true;}@Overridepublic boolean onTouchEvent(MotionEvent ev){switch (ev.getAction() & ev.getActionMasked()){case MotionEvent.ACTION_DOWN:mDownX = (int) ev.getRawX();mDownY = (int) ev.getRawY();break;case MotionEvent.ACTION_MOVE:if (mDragStarted){// 保持中心mDragItemLayoutParams.x = (int) (ev.getRawX() - mDragItemView.getWidth() / 2);mDragItemLayoutParams.y = (int) (ev.getRawY() - mDragItemView.getHeight() / 2);// 更新paramsmWindowManager.updateViewLayout(mDragItemView, mDragItemLayoutParams);// ......}break;case MotionEvent.ACTION_UP:// ......break;}return super.onTouchEvent(ev);}如何实现隐藏拖拽的Item
@Overridepublic boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l){// ......((GridViewSortAdapter) getAdapter()).hideView(i);// ......}GridViewSortAdapterpublic void hideView(int item){// ......mStartHideItemPosition = item;notifyDataSetChanged();}private int mStartHideItemPosition = AdapterView.INVALID_POSITION;@Overridepublic View getView(int position, View convertView, ViewGroup parent){ViewHolder holder = null;if (convertView == null){convertView = LayoutInflater.from(mContext).inflate(R.layout.view_item_grid_view_sort, null);holder = new ViewHolder();holder.title = (TextView) convertView.findViewById(R.id.view_item_grid_view_sort_title);convertView.setTag(holder);}else{holder = (ViewHolder) convertView.getTag();}holder.title.setText(mTypeTitle.get(position));if (mStartHideItemPosition == position){convertView.setVisibility(View.INVISIBLE);}else{convertView.setVisibility(View.VISIBLE);}return convertView;}如何知道当前拖拽到哪一个item之上
@Override public boolean onTouchEvent(MotionEvent ev) {case MotionEvent.ACTION_MOVE:if (mDragStarted){// ......int position = pointToPosition((int) ev.getX(), (int) ev.getY());// ......}break;}如何实现动画
View view = mGridView.getChildAt(0);mTranslateX = view.getWidth() + mHorizontalSpace;mTranslateY = view.getHeight() + mVerticalSpace;当拖拽到其他item之上时,开始动画
if (position != AdapterView.INVALID_POSITION && !((GridViewSortAdapter) getAdapter()).isInAnimation()){ Log.d(TAG, "position = " + position); ((GridViewSortAdapter) getAdapter()).swap(position);}GridSortAdapterpublic void swap(int position){mAnimatorSetList.clear();int r_p = mPositionList.indexOf(position);Log.d(TAG, "r_p = " + r_p);if (mCurrentHideItemPosition < r_p){for (int i = mCurrentHideItemPosition + 1; i <= r_p; i++){View v = mGridView.getChildAt(mPositionList.get(i));if (i % mColsNum == 0 && i > 0){startMoveAnimation(v, v.getTranslationX() + mTranslateX * (mColsNum - 1), v.getTranslationY() -mTranslateY);}else{startMoveAnimation(v, v.getTranslationX() - mTranslateX, 0);}}}else if (mCurrentHideItemPosition > r_p){for (int i = r_p; i < mCurrentHideItemPosition; i++){View v = mGridView.getChildAt(mPositionList.get(i));if ((i + 1) % mColsNum == 0){startMoveAnimation(v, v.getTranslationX() - mTranslateX * (mColsNum - 1), v.getTranslationY() + mTranslateY);}else{startMoveAnimation(v, v.getTranslationX() + mTranslateX, 0);}}}resetPositionList();int value = mPositionList.get(mStartHideItemPosition);if (mStartHideItemPosition < r_p){mPositionList.add(r_p + 1, value);mPositionList.remove(mStartHideItemPosition);}else if (mStartHideItemPosition > r_p){mPositionList.add(r_p, value);mPositionList.remove(mStartHideItemPosition + 1);}mCurrentHideItemPosition = r_p;}public boolean isInAnimation(){return mInAnimation;}private void resetPositionList(){mPositionList.clear();for (int i = 0; i < mGridView.getChildCount(); i++){mPositionList.add(i);}}private void startMoveAnimation(View myView, float x, float y){AnimatorSet set = new AnimatorSet();set.playTogether(ObjectAnimator.ofFloat(myView, "translationX", myView.getTranslationX(), x),ObjectAnimator.ofFloat(myView, "translationY", myView.getTranslationY(), y));set.addListener(new Animator.AnimatorListener(){@Overridepublic void onAnimationStart(Animator animator){mInAnimation = true;}@Overridepublic void onAnimationEnd(Animator animator){mInAnimation = false;}@Overridepublic void onAnimationCancel(Animator animator){}@Overridepublic void onAnimationRepeat(Animator animator){}});mAnimatorSetList.add(set);set.setDuration(150).start();}这里我主要解释一下代码中 mPositionList这个列表的作用,之前说过一次拖拽的时候,item的position是不会变化的。
mPositionList.indexOf(pointToPosition(x,y))就能得到真实的item的position
gridviewex.gif
源码地址
https://github.com/jiahuanyu/android-example-code/tree/master/app/src/main/java/com/github/jiahuanyu/example/ui/dragsortgird
以上所述是小编给大家介绍的Android 仿网易新闻客户端分类排序功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!