In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly introduces Android how to customize the gridView imitating headline channel drag management function, the article is very detailed, has a certain reference value, interested friends must read it!
There is such a requirement in the project: the functional navigation of app requires draggable sorting, similar to the channel drag management in the headlines. The effect is as follows, gif is not very smooth, the real opportunity is much better.
Although there are many similar articles searched online, the writing is not satisfactory, the notes are not clear, and the animation is not smooth enough. After being sorted out and optimized by myself, take it out for follow-up use.
The principle of implementation:
GridView as the basic control WindowManager.addView to achieve draggable view TranslateAnimation to achieve mobile animation, after the animation can be updated adapter
The main implementation principle has been explained above, and the key locations in the source code are also annotated, so the following goes directly to the source code.
Package com.hai.draggrid;import android.content.Context;import android.graphics.Bitmap;import android.graphics.PixelFormat;import android.util.AttributeSet;import android.view.Gravity;import android.view.MotionEvent;import android.view.View;import android.view.WindowManager;import android.view.animation.Animation;import android.view.animation.TranslateAnimation;import android.widget.AdapterView;import android.widget.BaseAdapter;import android.widget.GridView;import android.widget.ImageView / * long press the drag icon to adjust the item position Gridview * Created by huanghp on 2019-10-15. * Email h2132760021@sina.com * / public class DragGridView extends GridView {private static final String TAG = "DragGridView"; private int downX, downY; private int rawX, rawY; private int lastPosition = INVALID_POSITION; private int viewL, viewT; private int itemHeight, itemWidth; private int itemCount; private double dragScale = 1.2D rawY; private int lastPosition / drag view magnification private ImageView dragImageView; private WindowManager windowManager = null; private WindowManager.LayoutParams windowParams = null Private boolean isMoving = false; private Animation lastAnimation; private static final long TIME_ANIMATE = 300; public DragGridView (Context context, AttributeSet attrs) {this (context, attrs, 0);} public DragGridView (Context context, AttributeSet attrs, int defStyleAttr) {super (context, attrs, defStyleAttr); setOnItemLongClickListener (new OnItemLongClickListener () {@ Override public boolean onItemLongClick (AdapterView parent, View view, int position, long id) {lastPosition = position; View dragView = getChildAt (lastPosition-getFirstVisiblePosition (); itemHeight = dragView.getHeight (); itemWidth = dragView.getWidth (); itemCount = getCount () Int rows = itemCount / getNumColumns (); / / calculate the number of rows int left = (itemCount% getNumColumns ()); / / calculate the redundant number of the last line if (lastPosition! = INVALID_POSITION) {viewL = downX-dragView.getLeft (); viewT = downY-dragView.getTop (); dragView.destroyDrawingCache (); dragView.setDrawingCacheEnabled (true); Bitmap bitmap = Bitmap.createBitmap (dragView.getDrawingCache ()); startDrag (bitmap); dragView.setVisibility (INVISIBLE); isMoving = false; ((Adapter) getAdapter ()) .setIsDrag (true) RequestDisallowInterceptTouchEvent (true); return true;} return false;}});} private void startDrag (Bitmap dragBitmap) {stopDrag (); windowParams = new WindowManager.LayoutParams (); windowParams.gravity = Gravity.TOP | Gravity.LEFT; / / get the coordinates of the upper left corner of preview relative to the screen windowParams.x = rawX-viewL; windowParams.y = rawY-viewT; / / set the width and height of the drag item windowParams.width = (int) (dragScale * dragBitmap.getWidth ()) / / magnify dragScale, you can set the multiple after dragging windowParams.height = (int) (dragScale * dragBitmap.getHeight ()); / / zoom in dragScale, you can set the multiple after dragging this.windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; this.windowParams.format = PixelFormat.TRANSLUCENT; this.windowParams.windowAnimations = 0 ImageView iv = new ImageView (getContext ()); iv.setImageBitmap (dragBitmap); windowManager = (WindowManager) getContext (). GetSystemService (Context.WINDOW_SERVICE); windowManager.addView (iv, windowParams); dragImageView = iv;} private void stopDrag () {if (dragImageView! = null & & windowManager! = null) {windowManager.removeView (dragImageView); dragImageView = null;}} @ Override public boolean onTouchEvent (MotionEvent ev) {int x = (int) ev.getX (); int y = (int) ev.getY () Switch (ev.getAction ()) {case MotionEvent.ACTION_DOWN: downX = x; downY = y; rawX = (int) ev.getRawX (); rawY = (int) ev.getRawY (); break; case MotionEvent.ACTION_MOVE: if (dragImageView! = null & & lastPosition! = INVALID_POSITION) {updateDrag ((int) ev.getRawX (), (int) ev.getRawY ()); if (! isMoving) onMove (x, y, false);} break Case MotionEvent.ACTION_UP:// Log.e (TAG, "dragImageView is null=" + (dragImageView = = null) + ", lastposition=" + lastPosition// + ", pointToPosition=" + pointToPosition (x, y) + ", ismove=" + isMoving); if (dragImageView! = null & & lastPosition! = INVALID_POSITION) {/ / if (isMoving) onMove (x, y, true); / / before the animation is finished, resetting the animation will clear the previously set animation. StopDrag (); ((Adapter) getAdapter ()) .setIsDrag (false); ((BaseAdapter) getAdapter ()) .notifyDataSetChanged (); requestDisallowInterceptTouchEvent (false);} break;} return super.onTouchEvent (ev);} private void onMove (int moveX, int moveY, boolean isMoveUp) {final int targetPosition = pointToPosition (moveX, moveY); if (targetPosition! = INVALID_POSITION) {if (targetPosition = = lastPosition) {/ / moving position is not yet in the new item } / / move the number of moving ITEM to be moved int moveCount = targetPosition-lastPosition; if (moveCount! = 0) {if (isMoveUp) {/ / when the finger is lifted, directly exchange data Adapter adapter = (Adapter) getAdapter (); adapter.exchange (lastPosition, targetPosition); lastPosition = targetPosition; isMoving = false;} else {int moveCountAbs = Math.abs (moveCount); float toXvalue = 0, toYvalue = 0 / / percentage of distance moved by moveXP (percentage relative to its own length) float moveXP = ((float) getHorizontalSpacing () / (float) itemWidth) + 1.0f; float moveYP = ((float) getVerticalSpacing () / (float) itemHeight) + 1.0f; int holdPosition;// Log.d (TAG, "start annimation=" + moveCountAbs); for (int I = 0; I
< moveCountAbs; i++) { //从左往右,或是从上往下 if (moveCount >0) {holdPosition = lastPosition + I + 1; / / same line if (lastPosition / getNumColumns () = = holdPosition / getNumColumns ()) {toXvalue =-moveXP; toYvalue = 0;} else if (holdPosition% getNumColumns () = 0) {toXvalue = (getNumColumns ()-1) * moveXP; toYvalue =-moveYP;} else {toXvalue =-moveXP; toYvalue = 0;} else {/ / from right to left or holdPosition = lastPosition-I-1 from bottom to top If (lastPosition / getNumColumns () = = holdPosition / getNumColumns ()) {toXvalue = moveXP; toYvalue = 0;} else if ((holdPosition + 1)% getNumColumns () = = 0) {toXvalue =-(getNumColumns ()-1) * moveXP; toYvalue = moveYP;} else {toXvalue = moveXP; toYvalue = 0;} View holdView = getChildAt (holdPosition); Animation moveAnimation = createAnimation (toXvalue, toYvalue); moveAnimation.setAnimationListener (new Animation.AnimationListener () {@ Override public void onAnimationStart (Animation animation) {isMoving = true) } @ Override public void onAnimationRepeat (Animation animation) {} @ Override public void onAnimationEnd (Animation animation) {/ / if this is the end of the last animation, execute the following method if (animation = = lastAnimation) {Adapter adapter = (Adapter) getAdapter (); adapter.exchange (lastPosition, targetPosition); lastPosition = targetPosition; isMoving = false;}); holdView.startAnimation (moveAnimation); if (holdPosition = = targetPosition) {lastAnimation = moveAnimation }} public Animation createAnimation (float toXValue, float toYValue) {TranslateAnimation mTranslateAnimation = new TranslateAnimation (Animation.RELATIVE_TO_SELF, 0.0F, Animation.RELATIVE_TO_SELF, toXValue, Animation.RELATIVE_TO_SELF, 0.0F, Animation.RELATIVE_TO_SELF, toYValue); mTranslateAnimation.setFillAfter (true); / / after the animation effect is completed, the View object remains in the terminated position. MTranslateAnimation.setDuration (TIME_ANIMATE); return mTranslateAnimation;} private void updateDrag (int rawX, int rawY) {windowParams.alpha = 0.6f; windowParams.x = rawX-viewL; windowParams.y = rawY-viewT; windowManager.updateViewLayout (dragImageView, windowParams);} static abstract class Adapter extends BaseAdapter {protected boolean isDrag; protected int holdPosition =-1; public void setIsDrag (boolean isDrag) {this.isDrag = isDrag;} public void exchange (int startPosition, int endPositon) {holdPosition = endPositon;}
The main code is DragGridView, and it's quite easy to get this view to implement. For the sake of the completeness of the article, the main usage code of this effect picture is also posted below.
String [] items = new String [] {"headlines", "Video", "Entertainment", "Sports", "Beijing", "New era", "NetEase", "jokes", "Ice and Snow Sports", "Technology", "car", "easy moment", "Fashion", "Live", "pictures", "follow posts", "NBA", "attitude Open course" "recommendation", "Hot spot", "Society", "fun Picture", "Beauty", "military"} GridView.setAdapter (new DragGridView.Adapter () {@ Override public void exchange (int startPosition, int endPositon) {super.exchange (startPosition, endPositon); String item = list.get (startPosition); if (startPosition < endPositon) {list.add (endPositon + 1, item); list.remove (startPosition);} else {list.add (endPositon, item); list.remove (startPosition + 1);} for (int I = 0; I < list.size () ) {Log.e (TAG, "exchange: =" + list.get (I));} notifyDataSetChanged ();}. Omit part of the code @ Override public View getView (int position, View convertView, ViewGroup parent) {/ / todo, here you need to optimize, there is no reuse of views. Do not take view in the traditional way, otherwise it will cause dragging view blank / / if (convertView = = null) {convertView = getLayoutInflater (). Inflate (R.layout.item, parent, false); / /} ((TextView) convertView.findViewById (R.id.tv)) .setText (getItem (position)); if (isDrag & & position = = holdPosition) {convertView.setVisibility (View.INVISIBLE);} else convertView.setVisibility (View.VISIBLE); return convertView;}})
The above is all the content of this article "how Android customizes gridView to imitate the headline channel drag management function". Thank you for reading! Hope to share the content to help you, more related knowledge, welcome to follow the industry information channel!
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.