One, foreword
When using QQ, found that did not read the message drag effect is very interesting, imitate once.
Second, the effect drawing
The specific effects are as follows:
The effect map has the following characteristics:
- Dot drag has scope
- Drag and release the dot in the drag range and it bounces back to its original position
- When you drag, the center circle gets smaller and smaller. The size of the center circle stays the same. The connecting part gets longer and thinner until it disappears
- If released beyond the defined drag range it will explode and disappear
Three, the analysis
Of 1.
Start by analyzing the composition of this view:
- Small central circle: a fixed circle
- Small circle followed by finger movement: a drag circle
- The joining part of two circles
- Two straight lines (diameters of two circles) are used to connect two Bessel curves to form a closed figure
2. Draw
- Center circle and drag circle drawing circle is relatively simple, direct call
canvas.drawCircle
Can, the center of the center circle is fixed, drag the circle of the circle is the finger touch screen coordinates. - The connected part between the two circles and the connected part in the middle are actually two second-order Bessel curves, which are analyzed as follows:
Then the line (P1-P3) can be drawn with the following pseudocode:
Path rPathLeft = new Path();
rPathLeft.moveTo(P1.x,P1.y);
rPathLeft.quadTo(M.x,M.y,P3.x,P3.y);
Copy the code
Similarly, the line (p2-p4) can be drawn using the following pseudocode:
Path rPathRight = new Path();
rPathRight.moveTo(P2.x,P2.y);
rPathRight.quadTo(M.x,M.y,P4.x,P4.y);
Copy the code
- So these two lines these two lines are P1 minus P2 and P3 minus P4.
rPathLeft.lineTo(P4.x,P4.y)
rPathRight.lineTo(P2.x,P2.y)
Copy the code
Five points are needed to draw the above two Bezier curves and lines: P1,P2,P3,P4,M. Among them, P1,P2,P3 and P4 are the tangents of the circles. Now we only know the central points O1 and O2 of the two circles, so how to calculate the tangents of the other four circles according to these two points? First analysis:
According to the figure above, it can be known that:
tan(a) = y / x
a = arctan(y / x)
P3.x = X1-r2*sina
P3.y = Y1-r2*cosa
P1.x = X0-r1*sina
P1.y = X0-r1*cosa
Same thing for P2 and P4.
2.1. Static implementation
Let’s draw the image statically and inherit the FrameLayout directly.
public class RedPointView extends FrameLayout{
/ / brush
private Paint rPaint,tPaint;
/ / radius
private int rRadius;
// Set the center of the circle
PointF tCenterPointF = new PointF(300.400);
// Drag the center of the circle
PointF tDragPointF = new PointF(200.550);
// Set the radius of the circle
private float tCenterRadius = 30;
// Drag the radius of the circle
private float tDragRadius = 30;
/ / line
private Path rPath;
// Call the constructor of two arguments
public RedPointView(Context context) {
this(context,null);
}
// Two arguments constructor, call three arguments constructor
public RedPointView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
// A three-argument constructor
public RedPointView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
// Initializes the small circle
private void init(a){
// Initialize the Paint object
rPaint = new Paint();
// Set the color to red
rPaint.setColor(Color.RED);
// Set anti-aliasing
rPaint.setAntiAlias(true);
// Set the fill
rPaint.setStyle(Paint.Style.FILL);
tPaint = new Paint();
// Set the color to red
tPaint.setColor(Color.RED);
// Set anti-aliasing
tPaint.setAntiAlias(true);
/ / radius of 25
rRadius = 25;
}
// Draw your own child method
// The dispatchDraw() method instead of onDraw() method is overridden when drawing on a ViewGroup
protected void dispatchDraw(Canvas canvas){
super.dispatchDraw(canvas);
// Draw the fixed circle first
canvas.drawCircle(tCenterPointF.x,tCenterPointF.y,tCenterRadius,rPaint);
// Draw the drag circle again
canvas.drawCircle(tDragPointF.x,tDragPointF.y,tDragRadius,rPaint);
float x = tCenterPointF.x - tDragPointF.x;
float y = tDragPointF.y - tCenterPointF.y;
// Find the Angle of A
double a = Math.atan(y / x);
// P1 x offset of the center circle
float offsetX1 = (float) (tCenterRadius * Math.sin(a));
float offsetY1= (float) (tCenterRadius * Math.cos(a));
// Drag the circle's p2 x offset
float offsetX2 = (float) (tDragRadius * Math.sin(a));
float offsetY2= (float) (tDragRadius * Math.cos(a));
/ / p1 coordinates
float p1_x = tCenterPointF.x - offsetX1;
float p1_y = tCenterPointF.y - offsetY1;
/ / p2 coordinates
float p2_x = tCenterPointF.x + offsetX1;
float p2_y = tCenterPointF.y + offsetY1;
/ / p3 coordinates
float p3_x = tDragPointF.x - offsetX2;
float p3_y = tDragPointF.y - offsetY2;
/ / p4 coordinates
float p4_x = tDragPointF.x + offsetX2;
float p4_y = tDragPointF.y + offsetY2;
// Control point M coordinates
float controll_x = (tCenterPointF.x + tDragPointF.x) / 2;
float controll_y = (tDragPointF.y + tCenterPointF.y) / 2;
// Create Path to draw the Path
rPath = new Path();
// Draw path direction :P1->P3->P4->P1rPath.reset(); rPath.moveTo(p1_x,p1_y); rPath.quadTo(controll_x,controll_y,p3_x,p3_y); rPath.lineTo(p4_x,p4_y); rPath.quadTo(controll_x,controll_y,p2_x,p2_y); rPath.lineTo(p1_x,p1_y); rPath.close(); canvas.drawPath(rPath,tPaint); }}Copy the code
The layout file simply ConstraintLayout nested the custom View:
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.knight.qq_redpoint.MainActivity">
<com.knight.qq_redpoint.RedPointView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>
Copy the code
The renderings are as follows:
2.2. Dynamic implementation
Static effect is drawn out, then continue to go down, realize the dynamic effect, realize the dynamic was simply drag the circle tangent point and bezier control point in the change, and drag the circle in the center is touching the screen coordinates, then the point of tangency and control points based on a formula to calculate step, directly in touch method onTouchEvent to deal with below:
public boolean onTouchEvent(MotionEvent event){
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
//event.getRawX: represents the distance between the touch point and the left edge of the screen
//event.getRawY: Represents the distance between the touch point and the on-screen boundary
// event.getx () takes the offset relative to the left of the view you touched (X coordinates)
// event.gety () takes the offset relative to the top edge of the view you are touching.
float originalDragX = event.getX();
float originalDragy = event.getY();
updateDragPoint(originalDragX,originalDragy);
break;
case MotionEvent.ACTION_MOVE:
float overDragX = event.getX();
float overDragy = event.getY();
// Update the position of the drag circle as you move it
updateDragPoint(overDragX,overDragy);
break;
}
return true;
}
// Update the center coordinates of the drag circle
private void updateDragPoint(float x,float y){
tDragPointF.set(x,y);
postInvalidate();
}
Copy the code
The renderings are as follows:
2.2.1 Radius change of center circle
Careful observation of the effect, found that as the drag distance increases, the radius of the center circle is getting smaller and smaller, as if there is a little feeling, but far from enough. Then we can make a rule, the relationship between the drag distance and the center circle, and set the drag maximum distance:
// The minimum radius of the center
private float minRadius = 8;
// Default maximum drag distance
private float maxDistance = 160;// Calculate the radius of the center circle during dragging
private float changeCenterRadius(a) {
float mDistance_x = tDragPointF.x - tCenterPointF.x;
float mDistance_y = tDragPointF.y - tCenterPointF.y;
// The distance between two circles
float mDistance = (float) Math.sqrt(Math.pow(mDistance_x, 2) + Math.pow(mDistance_y, 2));
// Calculate the radius of the center circle. Here drag the default radius of the circle to reduce the length of the distance change (you can define the radius change here).
float r = tDragRadius - minRadius * (mDistance / maxDistance);
// Assign the minimum radius if the radius is less than the minimum radius
if (r < minRadius) {
r = minRadius;
}
return r;
}
Copy the code
Finally, in the onDraw method, add the calculation of the radius of the change center circle:
// Draw method
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
// Draw the fixed center circletCenterRadius = changeCenterRadius(); canvas.drawCircle(tCenterPointF.x, tCenterPointF.y, tCenterRadius, rPaint); . }Copy the code
The renderings are as follows:
2.2.2 Distance limitation
When the drag distance is greater than the given distance, the center circle will disappear. The logic is very simple, that is, the ACTION_MOVE in onTouchEvent, calculate the drag distance of the two circles. If the drag distance exceeds the given distance, the Bezier curve and the fixed center circle will not be drawn:
// Indicate whether the drag distance is greater than the specified drag range
private boolean isOut;
// indicate if the drag is out of range
private boolean isOverStep;
// Draw method
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
if(! isOut){// Draw the fixed center circletCenterRadius = changeCenterRadius(); canvas.drawCircle(tCenterPointF.x, tCenterPointF.y, tCenterRadius, rPaint); . }// Draw a drag circle once the given drag distance is exceeded
if(!isOverStep){
canvas.drawCircle(tDragPointF.x,tDragPointF.y,tDragRadius,rPaint);
}
}
// Override the onTouchEvent method
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
........
case MotionEvent.ACTION_MOVE:
float overDragX = event.getX();
float overDragy = event.getY();
// Update the position of the drag circle as you move it
updateDragPoint(overDragX, overDragy);
float tDragDistance = getDistanceTwo(tCenterPointF,tDragPointF);
// Determine if the drag distance is greater than the specified distance
if(tDragDistance > maxDistance){
isOut = true;
}else{
// Do not set isOut to false because there is no recovery once the drag distance is exceeded
isOverStep = false;
}
break;
}
return true;
}
// Calculate the distance between two circles
private float getDistanceTwo(PointF tCenterPointF,PointF tDragPointF){
return (float) Math.sqrt(Math.pow(tCenterPointF.x - tDragPointF.x,2) + Math.pow(tCenterPointF.y - tDragPointF.y,2));
}
Copy the code
The renderings are as follows:
MotionEvent.ACTION_UP
// Override the onTouchEvent method
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
....
case MotionEvent.ACTION_UP:
getDistanceTwo(tCenterPointF,tDragPointF);
// Here to judge
if(! isOut){// No more than
kickBack();
}
postInvalidate();
break;
}
return true;
}
/** * Drag circle rebound animation ** /
private void kickBack(a) {
final PointF initPoint = new PointF(tDragPointF.x,
tDragPointF.y);
final PointF finishPoint = new PointF(tCenterPointF.x,
tCenterPointF.y);
// The value transitions smoothly from 0 to 1
ValueAnimator animator = ValueAnimator.ofFloat(0.0 f.1.0 f);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// Get the animation execution progress
float rFraction = animation.getAnimatedFraction();
// Update the center of the drag circlePointF updateDragPoint = getPoint( initPoint, finishPoint, rFraction); updateDragPoint(updateDragPoint.x, updateDragPoint.y); }});// Set the animation interpolator
animator.setInterpolator(new OvershootInterpolator(3.0 f));
// Animation time
animator.setDuration(500);
animator.start();
}
/** ** gets the coordinates of some point between two points * based on the percentage@paramInitPoint identifies the circle for the first time@paramFinishPoint Final circle *@paramPercent *@return* * /
public PointF getPoint(PointF initPoint, PointF finishPoint, float percent) {
return new PointF(getValue(initPoint.x , finishPoint.x,percent), getValue(initPoint.y , finishPoint.y,percent));
}
/** * get the indexing value *@param start
* @param finish
* @param fraction
* @return* /
public float getValue(Number start, Number finish,float fraction){
return start.floatValue() + (finish.floatValue() - start.floatValue()) * fraction;
}
Copy the code
Effect:
2.2.3 Increase explosion effect
When the drag circle exceeds the drag range, there will be an explosion effect and then disappear. Add the explosion effect below:
// Initialize the explosion image
private int[] explodeImgae = new int[]{
R.mipmap.explode_1,
R.mipmap.explode_2,
R.mipmap.explode_3,
R.mipmap.explode_4,
R.mipmap.explode_5
};
/ / ImageView explosion
private ImageView explodeImage;
Copy the code
Add the explosion image to the init initialization method:
// Add an explosion image
explodeImage = new ImageView(getContext());
// Set layout parameters
LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
explodeImage.setLayoutParams(lp);
explodeImage.setImageResource(R.mipmap.explode_1);
// Do not display at first
explodeImage.setVisibility(View.INVISIBLE);
// Add to viewGroup
addView(explodeImage);
Copy the code
And implement the method of playing animation:
/** ** Display explosion effect outside drag range ** /
private void showExplodeImage(a){
// Property animation
ValueAnimator animator = ValueAnimator.ofInt(0,explodeImgaes.length - 1);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// Update the image constantly
explodeImage.setBackgroundResource(explodeImgaes[(int) animation.getAnimatedValue()]); }});// Add a listener for the animation
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
// Make the image invisible
explodeImage.setVisibility(View.GONE);
}
@Override
public void onAnimationRepeat(Animator animation) {
super.onAnimationRepeat(animation);
}
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
// Start with visible
explodeImage.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationPause(Animator animation) {
super.onAnimationPause(animation);
}
@Override
public void onAnimationResume(Animator animation) {
super.onAnimationResume(animation); }});/ / time
animator.setDuration(600);
// Play once
animator.setRepeatMode(ValueAnimator.RESTART);
/ / difference
animator.setInterpolator(new OvershootInterpolator());
animator.start();
}
Copy the code
The MotionEvent. ACTION_UP in:
case MotionEvent.ACTION_UP:
getDistanceTwo(tCenterPointF,tDragPointF);
// Here to judge
if(! isOut){// No more than
kickBack();
}
if(isOut){
// Lift the flag
isOverandUp = true;
// Place the explosion image in the center of the origin
explodeImage.setX(event.getX() - tDragRadius);
explodeImage.setY(event.getY() - tDragRadius);
// If the center circle and drag circle are larger than the drag distance, play explosion
if(getDistanceTwo(tCenterPointF,tDragPointF) > maxDistance){
showExplodeImage();
}
// If the distance between the drag circle and the center circle exceeds the drag distance and then moves the drag circle to a distance greater than 30, it will still explode
if(getDistanceTwo(tCenterPointF,tDragPointF) >=30){
showExplodeImage();
}
}
postInvalidate();
break;
Copy the code
In dispatchView beyond the drag distance to less than the recovery center circle distance logic:
if(isOut){
// If the distance between the drag circle and the center circle is less than 30, the center circle is restored
if(getDistanceTwo(tCenterPointF,tDragPointF) < 30 && isOverandUp){
canvas.drawCircle(tCenterPointF.x, tCenterPointF.y, tCenterRadius, rPaint);
isOut = false;
isOverandUp = false; }}// Draw a drag circle once the given drag distance is exceeded
if(! isOverStep){// If out and up
if(!isOverandUp && isOut){
canvas.drawCircle(tDragPointF.x,tDragPointF.y,tDragRadius,rPaint);
}
}
Copy the code
The renderings are as follows:
Add to ListView
1. Add to WindowManager
The above effect is far from enough, how to like QQ, in ListView or Recycleview small dots can be free in the screen drag it? Since a view can only be drawn within its parent control, it can only be moved within its own list, so how can you drag and drop in full screen? Custom drag view changes from inheriting ViewGroup to inheriting View only with the help of WindowManager when the dot to be dragged is added to WindowManager and touch listener is set:
public class BetterRedPointView extends View{
/ / WindowManager object
private WindowManager windowManager;
// Drag the width of the view
private int dragViewWidth;
// Drag the height of the view
private int dragViewHeight;
//WindowManager layout parameters
private WindowManager.LayoutParams params;
// Status monitoring
private DragViewStatusListener dragViewStatusListener;
// Layout parameters
params = new WindowManager.LayoutParams();
// Background transparent
params.format = PixelFormat.TRANSLUCENT;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
// Base on the upper-left corner
params.gravity = Gravity.TOP | Gravity.LEFT;
}
Copy the code
The constructor passes in the dragged View and WindowManager objects and initializes some parameters:
// constructor
public BetterRedPointView(Context context, View dragView, WindowManager windowManager){
super(context);
this.context = context;
this.dragView = dragView;
this.windowManager = windowManager;
init();
}
// Initializes the small circle
private void init(a) {
// Manual measurement
dragView.measure(1.1);
dragViewWidth = dragView.getMeasuredWidth() / 2;
dragViewHeight = dragView.getMeasuredHeight() / 2;
tDragRadius = dragViewHeight;
// The radius of the center circle
tCenterRadius = SystemUtil.dp2px(context,8);
// Maximum drag distance
maxDistance = SystemUtil.dp2px(context,80);
// Minimum radius
minRadius = SystemUtil.dp2px(context,3);
// Layout parameters
params = new WindowManager.LayoutParams();
// Background transparent
params.format = PixelFormat.TRANSLUCENT;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
// Base on the upper-left corner
params.gravity = Gravity.TOP | Gravity.LEFT;
}
Copy the code
2. Update the position of the drag view
In the example above update updateDragPoint drag the circle method, also through the WindowManager. UpdateViewLayout to update the drag and drop the view of the position:
/** * Update drag center coordinates *@param x
* @param y
*/
private void updateDragPoint(float x, float y) {
tDragPointF.set(x, y);
changeManagerView(x,y);
postInvalidate();
}
/** * Redraw the layout of the drag circle *@paramX x star@paramY, y coordinate */
private void changeManagerView(float x,float y){
params.x = (int)(x - dragViewWidth);
params.y = (int)(y - dragViewHeight - statusBarHeight);
windowManager.updateViewLayout(dragView,params);
}
Copy the code
3. Add status listeners
Added drag-and-drop monitor for circle and center circle:
public interface DragViewStatusListener {
/** * move ** outside the drag range@param dragPoint
*/
void outDragMove(PointF dragPoint);
/** * Moves outside the drag range * explosion effect ** /
void outDragMoveUp(PointF dragPoint);
/** * moves ** within the drag range@param dragPoint
*/
void inDragUp(PointF dragPoint);
/** * Restore center circle ** / when removed from drag range
void recoverCenterPoint(PointF centerPoint);
}
Copy the code
Implement a listening callback in case of a corresponding trigger, such as an explosion animation:
case MotionEvent.ACTION_UP:
getDistanceTwo(tCenterPointF,tDragPointF);
// Here to judge
if(! isOut){// No more than
kickBack();
}
if(isOut){
// Lift the flag
isOverandUp = true;
// Place the explosion image in the center of the origin
//explodeImage.setX(event.getX() - tDragRadius);
//explodeImage.setY(event.getY() - tDragRadius);
// If the center circle and drag circle are larger than the drag distance, play explosion
if(getDistanceTwo(tCenterPointF,tDragPointF) > maxDistance){
// Listen here for explosion effect
if(dragViewStatusListener ! =null){ dragViewStatusListener.outDragMoveUp(tDragPointF); }}// If the distance between the drag circle and the center circle exceeds the drag distance and then moves the drag circle to a distance greater than 30, it will still explode
if(getDistanceTwo(tCenterPointF,tDragPointF) >=30) {if(dragViewStatusListener ! =null){ dragViewStatusListener.outDragMoveUp(tDragPointF); }}}Copy the code
4. Build intermediate Bridges
Create a new class, mainly used to assist, mainly used to create drag custom view and create WindowManager object initialization data, and make various cases (drag in the scope, drag out of the scope) logic and explosion logic, the main code is as follows:
public class BetterRedPointViewControl implements View.OnTouchListener.DragViewStatusListener{
/ / context
private Context context;
// Drag and drop the layout id
private int mDragViewId;
/ / WindowManager object
private WindowManager windowManager;
// Layout parameters
private WindowManager.LayoutParams params;
private BetterRedPointView betterRedPointView;
// Dragged View
private View dragView;
// The View to display
private View showView;
// Status bar height
private int statusHeight;
// Maximum drag distance
private float maxDistance = 560;
// The radius of the center circle
private float tCenterRadius = 30;
// The minimum radius of a small circle
private float minRadius = 8;
// constructor
public BetterRedPointViewControl(Context context,View showView,int mDragViewId,DragStatusListener dragStatusListener){
this.context = context;
this.showView = showView;
this.mDragViewId = mDragViewId;
this.dragStatusListener = dragStatusListener;
// Set the listener to execute its own touch event
showView.setOnTouchListener(this);
params = new WindowManager.LayoutParams();
params.format = PixelFormat.TRANSLUCENT;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = MotionEventCompat.getActionMasked(event);
if(action == MotionEvent.ACTION_DOWN){
ViewParent parent = v.getParent();
if(parent == null) {return false;
}
parent.requestDisallowInterceptTouchEvent(true);
statusHeight = SystemUtil.getStatusBarHeight(showView);
showView.setVisibility(View.INVISIBLE);
dragView = LayoutInflater.from(context).inflate(mDragViewId,null.false);
// Get the text content
getText();
windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
// Create a drag circle every time you touch it
betterRedPointView = new BetterRedPointView(context,dragView,windowManager);
// Initialize the data
init();
// Set the listening callback
betterRedPointView.setDragViewStatusListener(this);
// Add to form for display
windowManager.addView(betterRedPointView,params);
windowManager.addView(dragView,params);
}
betterRedPointView.onTouchEvent(event);
return true;
}
@Override
public void outDragMove(PointF dragPoint) {}@Override
public void outDragMoveUp(PointF dragPoint) {
removeView();
showExplodeImage(dragPoint);
dragStatusListener.outScope();
}
@Override
public void inDragUp(PointF dragPoint) {
removeView();
dragStatusListener.inScope();
}
@Override
public void recoverCenterPoint(PointF centerPoint) {
removeView();
dragStatusListener.inScope();
}
/** * Initializes data ** /
private void init(a){
// Compute the coordinates of the small circle in the screen
int[] points = new int[2];
showView.getLocationInWindow(points);
int x = points[0] + showView.getWidth() / 2;
int y = points[1] + showView.getHeight() / 2;
betterRedPointView.setStatusBarHeight(statusHeight);
// betterRedPointView.setMaxDistance(maxDistance);
// betterRedPointView.setCenterRadius(tCenterRadius);
// betterRedPointView.setMinRadius(minRadius);
betterRedPointView.setCenterDragPoint(x,y);
}
/** * get text content ** /
private void getText(a){
if(showView instanceof TextView && dragView instanceofTextView){ ((TextView)dragView).setText((((TextView) showView).getText().toString())); }}/** * remove the view object ** /
private void removeView(a){
if(windowManager ! =null&& betterRedPointView.getParent() ! =null&& dragView.getParent() ! =null) { windowManager.removeView(betterRedPointView); windowManager.removeView(dragView); }}}Copy the code
5. Call
Recycleview:
public class RecycleviewAdapter extends RecyclerView.Adapter<ItemHolder> {
/** * The view position to be deleted is used to update the RV operation */
ArrayList<Integer> needRemoveList =new ArrayList<Integer>();
private Context mContext;
public RecycleviewAdapter(Context mContext){
this.mContext = mContext;
}
@NonNull
@Override
public ItemHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
// Load the layout file
View itemView = LayoutInflater.from(mContext).inflate(R.layout.item,null);
return new ItemHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull ItemHolder itemHolder, final int i) {
itemHolder.tv_dragView.setText(String.valueOf(i));
Glide.with(mContext).load(R.mipmap.iv_image).apply(RequestOptions.bitmapTransform(new CircleCrop()).override(200.200)).into(itemHolder.iv_head);
// Whether to hide the view to drag
if(needRemoveList.contains(i)){
itemHolder.tv_dragView.setVisibility(View.GONE);
}
else {
itemHolder.tv_dragView.setVisibility(View.VISIBLE);
itemHolder.tv_dragView.setText(String.valueOf(i));
}
// One is a drag view and the other is a drag view layout
new BetterRedPointViewControl(mContext, itemHolder.tv_dragView, R.layout.includeview, new BetterRedPointViewControl.DragStatusListener() {
/** ** within the range ** /
@Override
public void inScope(a) {
notifyDataSetChanged();
}
/** ** out of range ** /
@Override
public void outScope(a) { needRemoveList.add(i); notifyDataSetChanged(); }}); }@Override
public int getItemCount(a) {
return 100; }}Copy the code
6. End result
The renderings are as follows:
5. Project examples
Github address: github.com/KnightAndro…