In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces GridView how to achieve drag-and-drop sorting and data interaction, has a certain reference value, interested friends can refer to, I hope you can learn a lot after reading this article, let the editor take you to understand it.
When studying an effect in the project, in the process of searching for information, we found that there is a need for GridView to achieve drag-and-drop sorting on the basis of drag-and-drop sorting, if it is between two GridView to achieve drag-and-drop effect, and data interaction.
First, the effect picture:
< (mDragTop.getX() + mDragTop.getWidth())) && (mMovePoint.y >MDragTop.getY () & & mMovePoint.y
< (mDragTop.getY() + mDragTop.getHeight()))) { return true; } } return false; } private Point getDragViewCenterPoint(DragView dragView) { Point result = new Point(); if (dragView != null) { int height = dragView.getHeight(); int width = dragView.getWidth(); float x = dragView.getX(); float y = dragView.getY(); result.set((int) (x + width / 2), (int) (y + height / 2)); } return result; } private boolean isDragFromBottom() { if (mMovePoint != null && mDragBottom != null) { if ((mMovePoint.x >MDragBottom.getX () & & mMovePoint.x
< (mDragBottom.getX() + mDragBottom.getWidth())) && (mMovePoint.y >MDragBottom.getY () & & mMovePoint.y
< (mDragBottom.getY() + mDragBottom.getHeight()))) { return true; } } return false; } private boolean isTouchInTop(MotionEvent event) { float y = event.getY(); return isTouchInTop(y); } private boolean isTouchInTop(float y) { return y >MDragTop.getY () & & y
< (mDragTop.getY() + mDragTop.getHeight()); }private void dragChangePosition(DragView dragView, int to) { if (to != dragView.getCurrentDragPosition() && isCanDragMove(dragView, to)) { dragView.onDragPositionChange(dragView.getCurrentDragPosition(), to); } } private boolean isCanDragMove(DragView dragView, int position) { return position >= dragView.getHeadDragPosition () & & position
< dragView.getGridChildCount() - dragView.getFootDragPosition(); } private FrameLayout mDragFrame; private DragView mDragBottom; private DragView mDragTop; private View hideView; private long dragLongPressTime = 600; public DragChessView(@NonNull Context context) { this(context, null); } public DragChessView(@NonNull Context context, @Nullable AttributeSet attrs) { this(context, attrs, -1); } public DragChessView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(attrs); } private void init(AttributeSet attrs) { Context context = getContext(); detector = new GestureDetector(context, simpleOnGestureListener); detector.setIsLongpressEnabled(false); mDragFrame = new FrameLayout(context); dragSlider = LayoutInflater.from(context).inflate(R.layout.layout_drag_chess, this, false); mDragTop = dragSlider.findViewById(R.id.drag_top); mDragBottom = dragSlider.findViewById(R.id.drag_bottom); addView(dragSlider, -1, -1); addView(mDragFrame, -1, -1); } @Override public boolean onTouchEvent(MotionEvent ev) { if (l != null) { l.onTouch(this, ev); } if (!isViewInitDone()) { return false; } if (isDragable) { handleScrollAndCreMirror(ev); } else { // 交给子控件自己处理 dispatchEvent(isTouchInTop(ev) ? mDragTop : mDragBottom, ev); } // 处理拖动 detector.onTouchEvent(ev); if (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP) { lastLocation = null; if (hasSendDragMsg) { hasSendDragMsg = false; handler.removeMessages(0x123); } } return true; } private void dispatchEvent(DragView dragView, MotionEvent ev) { dragView.dispatchEvent(ev); } private boolean isDragInTop() { if (mCopyView == null) return false; return (mCopyView.getY() + mCopyView.getHeight()) < (mDragTop.getY() + mDragTop.getBottom()); } /** * Description :拦截所有事件 */ @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return true; } /** * 处理自动滚屏,和单击生成镜像 */ private void handleScrollAndCreMirror(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: // 通知父控件不拦截我的事件 getParent().requestDisallowInterceptTouchEvent(true); // 根据点击的位置生成该位置上的view镜像 int position = eventToPosition(ev); makeCopyView(isTouchInTop(ev) ? mDragTop : mDragBottom, position); break; case MotionEvent.ACTION_MOVE: getParent().requestDisallowInterceptTouchEvent(true);// 通知父控件不拦截我的事件 // 内容太多时,移动到边缘会自动滚动 decodeScrollArea(isDragInTop() ? mDragTop : mDragBottom, ev); break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: if (hideView != null) { hideView.setVisibility(View.VISIBLE); if (onDragSelectListener != null) { onDragSelectListener.onPutDown(hideView); } } mDragFrame.removeAllViews(); // mDragFrame.scrollTo(0, 0); // isNotifyByDragSort = true; updateUI(isDragInTop() ? mDragTop : mDragBottom, ev); mCopyView = null; canAddViewWhenDragChange = true; // 放手时取消拖动排序模式 if (mDragMode == DRAG_BY_LONG_CLICK) { isDragable = false; } break; default: break; } } private void updateUI(DragView dragView, MotionEvent ev) { if (dragView.isHasPositionChange()) { dragView.setHasPositionChange(false); dragView.getAdapter().notifyDataSetChanged(); } else if (mDragMode == DRAG_BY_LONG_CLICK && itemLongClickListener != null) { dragView.onItemLongClick(itemLongClickListener); } // 停止滚动 if (dragView.isCanScroll()) { int scrollStates2 = dragView.decodeTouchArea(ev); if (scrollStates2 != 0) { dragView.onTouchAreaChange(0); mTouchArea = 0; } } } private void decodeScrollArea(DragView dragView, MotionEvent ev) { if (dragView.isCanScroll()) { int touchArea = dragView.decodeTouchArea(ev); if (touchArea != mTouchArea) { dragView.onTouchAreaChange(touchArea); mTouchArea = touchArea; } } } private void makeCopyView(DragView dragView, int position) { if (position >= dragView.getHeadDragPosition () & & position
< dragView.getGridChildCount() - dragView.getFootDragPosition()) { dragView.setCurrentDragPosition(position); copyView(dragView); } } /** * 得到事件触发点, 摸到的是哪一个item */ public int eventToPosition(MotionEvent ev) { if (ev != null) { if (isTouchInTop(ev)) return mDragTop.eventToPosition(ev); return mDragBottom.eventToPosition(ev); } return 0; } /** * 复制一个镜像,并添加到透明层 */ private void copyView(DragView dragView) { // TODO: 2018/4/2 创建可移动的 item hideView = dragView.getGridChildAt(dragView.getCurrentDragPosition()); int realPosition = dragView.getGridChildPos(hideView); DragAdapter adapter = dragView.getAdapter(); if (!adapter.isUseCopyView()) { mCopyView = adapter.getView(realPosition, mCopyView, mDragFrame); } else { mCopyView = adapter.copyView(realPosition, mCopyView, mDragFrame); } hideView.setVisibility(View.INVISIBLE); if (mCopyView.getParent() == null) mDragFrame.addView(mCopyView, dragView.getmColWidth(), dragView.getmColHeight()); int[] l1 = new int[2]; int[] l2 = new int[2]; hideView.getLocationOnScreen(l1); mDragFrame.getLocationOnScreen(l2); // mCopyView.setX(hideView.getLeft()); // mCopyView.setY(hideView.getTop() - mCurrentY); mCopyView.setX(l1[0] - l2[0]); mCopyView.setY(l1[1] - l2[1]); if (onDragSelectListener == null) { mCopyView.setScaleX(1.2f); mCopyView.setScaleY(1.2f); } else { onDragSelectListener.onDragSelect(mCopyView); } } private DragSortGridView.OnDragSelectListener onDragSelectListener; /** * @描述:一个item view刚被拖拽和放下时起来生成镜像时调用. */ public void setOnDragSelectListener(DragSortGridView.OnDragSelectListener onDragSelectListener) { this.onDragSelectListener = onDragSelectListener; } /** * @param mode int类型 * @描述:设置拖动的策略是点击还是长按 */ public void setDragModel(int mode) { this.mDragMode = mode; isDragable = mode == DRAG_WHEN_TOUCH; } public void setAnimFrame(ListenFrameLayout mDragFrame) { this.mDragFrame = mDragFrame; } /** * 设置长按需要用时 * * @param time */ public void setDragLongPressTime(long time) { dragLongPressTime = time; } public void setBottomAdapter(@NotNull DragAdapter adapter) { mDragBottom.setAdapter(adapter); } public boolean isViewInitDone() { boolean result = mDragBottom.isViewInitDone(); if (mDragTop.getVisibility() == VISIBLE) result &= mDragTop.isViewInitDone(); return result; } public void setTopAdapter(@NotNull DragAdapter adapter) { mDragTop.setAdapter(adapter); }} 2. DragView的实现: public class DragView extends FrameLayout { private static final int TAG_KEY = R.id.first; private NoScrollGridView mGridView; private List mChilds = new ArrayList(); protected int mNumColumns = 3; protected int mColHeight = 0; protected int mColWidth = 0; protected int mChildCount = 0; protected int mMaxHeight = 0; private boolean isViewInitDone = false; private ListenScrollView mScrollView; private int mCurrentY = 0; /** * 自动滚屏的动画 */ private ValueAnimator animator; private DragAdapter adapter; private int headDragPosition = 0; private int footDragPosition = 0; private int currentDragPosition = -1; /** * 是否有位置发生改变,否则不用重绘 */ private boolean hasPositionChange = false; /** * gridview能否滚动,是否内容太多 */ private boolean canScroll = true; /** * 动画时间 */ private static final long ANIM_DURING = 250; private Object swapeData; public DragView(@NonNull Context context) { this(context, null); } public DragView(@NonNull Context context, @Nullable AttributeSet attrs) { this(context, attrs, -1); } public DragView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { Context context = getContext(); mGridView = new NoScrollGridView(context); mGridView.setVerticalScrollBarEnabled(false); mGridView.setStretchMode(GridView.STRETCH_COLUMN_WIDTH); mGridView.setSelector(new ColorDrawable()); // View的宽高之类必须在测量,布局,绘制一系列过程之后才能获取到 mGridView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { if (mChilds.isEmpty()) { for (int i = 0; i < mGridView.getChildCount(); i++) { View view = mGridView.getChildAt(i); view.setTag(TAG_KEY, new int[]{0, 0}); view.clearAnimation(); mChilds.add(view); } } if (!mChilds.isEmpty()) { mColHeight = mChilds.get(0).getHeight(); } mColWidth = mGridView.getColumnWidth(); if (mChildCount % mNumColumns == 0) { mMaxHeight = mColHeight * mChildCount / mNumColumns; } else { mMaxHeight = mColHeight * (mChildCount / mNumColumns + 1); } canScroll = mMaxHeight - getHeight() >0; / / tell event handling to complete View loading, and many properties have also been initialized isViewInitDone = true;}}); mScrollView = new ListenScrollView (context); mGridView.setNumColumns (mNumColumns); mScrollView.addView (mGridView,-1,-1); addView (mScrollView,-1,-1) } private DataSetObserver observer = new DataSetObserver () {@ Override public void onChanged () {mChildCount = adapter.getCount (); / / the following attribute states are cleared before the mChilds.clear () is retrieved after the gridview survey layout is completed when notifyDataSetChange is called; mColHeight = mColWidth = mMaxHeight = 0; isViewInitDone = false } @ Override public void onInvalidated () {mChildCount = adapter.getCount ();}}; / * controls the animation listener that scrolls automatically. * / private ValueAnimator.AnimatorUpdateListener animUpdateListener = new ValueAnimator.AnimatorUpdateListener () {@ Override public void onAnimationUpdate (ValueAnimator animation) {int targetY = Math.round ((Float) animation.getAnimatedValue ()); if (targetY
< 0) { targetY = 0; } else if (targetY >MMaxHeight-getHeight () {targetY = mMaxHeight-getHeight ();} / / mGridView.scrollTo (0, targetY); mScrollView.smoothScrollTo (0, targetY); / / mCurrentY = targetY;}}; public void setAdapter (DragAdapter adapter) {if (this.adapter! = null & & observer! = null) {this.adapter.unregisterDataSetObserver (observer) } this.adapter = adapter; mGridView.setAdapter (adapter); adapter.registerDataSetObserver (observer); mChildCount = adapter.getCount ();} / * * @ param from * @ param to * @ description: animated effects move View * / public void translateView (int from, int to) {View view = mChilds.get (from) Int fromXValue = (int []) view.getTag (TAG_KEY) [0]; int fromYValue = ((int []) view.getTag (TAG_KEY)) [1]; int toXValue = to% mNumColumns-from% mNumColumns + fromXValue; int toYValue = to / mNumColumns-from / mNumColumns + fromYValue; Animation animation = new TranslateAnimation (1, fromXValue, 1, toXValue, 1, fromYValue, 1, toYValue); animation.setDuration (ANIM_DURING) Animation.setFillAfter (true); view.setTag (TAG_KEY, new int [] {toXValue, toYValue}); view.startAnimation (animation);} / * * @ param from * @ param to * @ description: drag View to change position * / public void onDragPositionChange (int from, int to) {if (from > to) {for (int I = to; I)
< from; i++) { translateView(i, i + 1); } } else { for (int i = to; i >From; iMel -) {translateView (I, I-1);}} if (! hasPositionChange) {hasPositionChange = true;} if ((from > = mChilds.size ()) | from
< 0) || (to >= mChilds.size () | | to
< 0)) return; adapter.onDataModelMove(from, to); View view = mChilds.remove(from); mChilds.add(to, view); currentDragPosition = to; } /** * @param scrollStates * @描述:触摸区域改变,做相应处理,开始滚动或停止滚动 */ public void onTouchAreaChange(int scrollStates) { if (!canScroll) { return; } if (animator != null) { animator.removeUpdateListener(animUpdateListener); } if (scrollStates == 1) {// 从普通区域进入触发向上滚动的区域 int instance = mMaxHeight - getHeight() - mCurrentY; animator = ValueAnimator.ofFloat(mCurrentY, mMaxHeight - getHeight()); animator.setDuration((long) (instance / 0.5f)); animator.setTarget(mGridView); animator.addUpdateListener(animUpdateListener); animator.start(); } else if (scrollStates == -1) {// 进入触发向下滚动的区域 animator = ValueAnimator.ofFloat(mCurrentY, 0); animator.setDuration((long) (mCurrentY / 0.5f)); animator.setTarget(mGridView); animator.addUpdateListener(animUpdateListener); animator.start(); } } /** * @param ev 事件 * @return 0中间区域, 1底部,-1顶部 * @描述: 检查当前触摸事件位于哪个区域, 顶部1/5可能触发下滚,底部1/5可能触发上滚 */ public int decodeTouchArea(MotionEvent ev) { if (ev.getY() >(getHeight () + getY ()) * 4 / (double) 5) {return 1;} else if (ev.getY ()
< (getHeight() + getY()) / (double) 5) { return -1; } else { return 0; } } public boolean isViewInitDone() { return isViewInitDone; } /** * 设置前几个item不可以改变位置 */ public void setNoPositionChangeItemCount(int count) { headDragPosition = count; } /** * 设置后几个item不可以改变位置 */ public void setFootNoPositionChangeItemCount(int count) { footDragPosition = count; } public int getHeadDragPosition() { return headDragPosition; } public int getFootDragPosition() { return footDragPosition; } public int getGridChildCount() { return mChilds.size(); } public View getGridChildAt(int position) { if (position < 0 || position >= mChilds.size () return null; return mChilds.get (position);} public int getGridChildPos (View view) {return mGridView.indexOfChild (view);} public void setCurrentDragPosition (int currentDragPosition) {this.currentDragPosition = currentDragPosition;} public int getCurrentDragPosition () {return currentDragPosition;} public int getmColHeight () {return mColHeight } public int getmColWidth () {return mColWidth;} public DragAdapter getAdapter () {return adapter;} public boolean isHasPositionChange () {return hasPositionChange;} public void setHasPositionChange (boolean hasPositionChange) {this.hasPositionChange = hasPositionChange;} public boolean isCanScroll () {return canScroll;} public void setOnItemClickListener (AdapterView.OnItemClickListener onItemClickListener) {mGridView.setOnItemClickListener (onItemClickListener) } public void onItemLongClick (AdapterView.OnItemLongClickListener itemLongClickListener) {itemLongClickListener.onItemLongClick (mGridView, childAt (currentDragPosition), currentDragPosition, 0);} public View childAt (int index) {return mGridView.getChildAt (index);} public void dispatchEvent (MotionEvent ev) {if (canScroll) mScrollView.dispatchTouchEvent (ev); else mGridView.dispatchTouchEvent (ev) } public int eventToPosition (MotionEvent ev) {if (ev! = null) {int m = (int) ev.getX () / mColWidth; int n = (int) (ev.getY ()-getY () + mCurrentY) / mColHeight; int position = n * mNumColumns + m; if (position > = mChildCount) {return mChildCount-1 } else {return position;}} return 0;} public void addSwapView (Object data) {adapter.addNewData (data);} public Object getSwapData () {return adapter.getSwapData (currentDragPosition);} public void removeSwapView () {if (adapter! = null) {adapter.removeData (currentDragPosition) Adapter.notifyDataSetChanged ();}} class ListenScrollView extends ScrollView {public ListenScrollView (Context context) {super (context);} @ Override protected void onScrollChanged (int l, int t, int oldl, int oldt) {super.onScrollChanged (l, t, oldl, oldt); mCurrentY = getScrollY () }} class NoScrollGridView extends GridView {public NoScrollGridView (Context context) {super (context);} / * * @ return * @ description: compatible with the older version of getColumWidth * @ author [pWX273343] July 1, 2015 * / public int getColumnWidth () {return getWidth () / getNumColumns () } public NoScrollGridView (Context context, AttributeSet attrs) {super (context, attrs);} @ Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {int mExpandSpec = MeasureSpec.makeMeasureSpec (Integer.MAX_VALUE > > 2, MeasureSpec.AT_MOST); super.onMeasure (widthMeasureSpec, mExpandSpec);}
3. The code of DragAdapter:
Public abstract class DragAdapter extends BaseAdapter {/ * * @ param from * @ param to * @ description: how to handle the data when the sort from from is dragged to to. * / public abstract void onDataModelMove (int from, int to); / * copy the method used by View. By default, you directly use the getView method to obtain * * @ param position * @ param convertView * @ param parent * @ return * / public View copyView (int position, View convertView, ViewGroup parent) {return null } / * * whether the copyView method is enabled * * @ return true use copyView to copy false and use getView to directly obtain the image * / public boolean isUseCopyView () {return false;} public abstract Object getSwapData (int position); public abstract void removeData (int position); public void addNewData (Object data) {}}
4. Use MainActivity:
Class GridDragShortActivity: AppCompatActivity () {override fun onCreate (savedInstanceState: Bundle?) {super.onCreate (savedInstanceState) window.attributes.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_IMMERSIVE or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION setContentView (R .layout.activity _ grid_drag_short) / / long press item to sort in response to the drag of item The default is to start dragging drag_main.setDragModel (DragSortGridView.DRAG_BY_LONG_CLICK) / / set the number of lines per line / / drag_main.numColumns = 3 var arrayList = ArrayList () var list = ArrayList () for (I in 0.. 29) {arrayList.add ("" + I)} for (I in 0. 29) {list.add (('A' + I) .toString ())} drag_main.setBottomAdapter (CustomAdapter (list) This)) drag_main.setTopAdapter (CustomAdapter (arrayList, this))}}
Layout: activity_main.xml
Layout layout_drag_chess.xml:
In practical use, you can expand the use as needed, another effect in the process of code evolution. Let's take a look at it and end this article:
Thank you for reading this article carefully. I hope the article "how to achieve drag-and-drop sorting and data interaction in GridView" shared by the editor will be helpful to you. At the same time, I also hope that you will support and pay attention to the industry information channel. More related knowledge is waiting for you to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.