Android 仿微信发动态九宫格拖拽、删除功能
作者:INTKILOW 发布时间:2022-08-28 12:51:03
标签:android,微信,发动态,九宫格,拖拽,删除
1、完美1比1 仿照微信仿微信发动态 九宫格拖拽、删除
暴力拖拽ui有点问题,不影响使用,资源文件自己找个+号
2、微信发动态拖拽bug
当选择完图片,长按图片拖拽过程中按下屏幕home键盘,再次进入这时候就不能点击输入文字,点击输入文字的时候会触发选择相册事件
3、拖拽事件用的basequickadapter
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation "com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50"
implementation "com.github.bumptech.glide:glide:4.9.0"
4、演示
5、快速入手
activity
NineGridChooseImage nineGridChooseImage = findViewById(R.id.nineGridChooseImage);
FrameLayout frameLayout= findViewById(R.id.frameLayout);
nineGridChooseImage.init(frameLayout);
int statusBarHeight = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusBarHeight = getResources().getDimensionPixelSize(resourceId);
}
nineGridChooseImage.setFixH(statusBarHeight);//自己对一下高度
nineGridChooseImage.setAddClick(new NineGridChooseImage.AddClick() {
@Override
public void onAdd() {
/* List<String> list = new LinkedList<>();
for(int i = 0;i<5;i++){
list.add("https://xx.jpg");
}*/
nineGridChooseImage.addData("https://xxx.jpg");
}
});
xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Main11Activity">
<com.example.hotfix_01.view.NineGridChooseImage
android:background="#A8A1A1"
android:layout_marginTop="100dp"
android:id="@+id/nineGridChooseImage"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
5、实现过程
如果帮助到你请关注点赞一下
NineGridChooseImage.java
package com.example.hotfix_01.view;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.chad.library.adapter.base.BaseItemDraggableAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.chad.library.adapter.base.callback.ItemDragAndSwipeCallback;
import com.chad.library.adapter.base.listener.OnItemDragListener;
import java.util.LinkedList;
import java.util.List;
import top.antaikeji.base.R;
import top.antaikeji.foundation.utils.DisplayUtil;
import static android.support.v7.widget.helper.ItemTouchHelper.ACTION_STATE_IDLE;
/**
* Author: flyzhang
*/
public class NineGridChooseImage extends RecyclerView {
private Rect lastRect = new Rect();
private Rect rect = new Rect();
private boolean isDel = false, tempImageDel = false;
private int mSelectPosition = 0;
private int SCREEN_W, SCREEN_H;
private int mImageWH;
private int mImageCount = 4;
private DraggableAdapter mDraggableAdapter;
private LinearLayout mBottomView;
private FrameLayout mFrameLayout;
private AddClick mAddClick;
private DragCallBack mDragCallBack;
private ImageView mTempImage;
;
private int mFixH = 0;
private int bottomViewH = 55;
private ImageView trash;
private int margin = 2;
public NineGridChooseImage(@NonNull Context context) {
super(context);
}
public NineGridChooseImage(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public void init(FrameLayout f) {
this.mFrameLayout = f;
Display defaultDisplay = ((Activity) getContext()).getWindowManager().getDefaultDisplay();
Point point = new Point();
defaultDisplay.getSize(point);
SCREEN_H = point.y;
SCREEN_W = point.x;
mImageWH = SCREEN_W / 3 - 2 * DisplayUtil.dpToPx(5) - 4 * DisplayUtil.pxToDp(20) - DisplayUtil.pxToDp(50);
bottomViewH = DisplayUtil.dpToPx(bottomViewH);
margin = DisplayUtil.dpToPx(margin);
mTempImage = new ImageView(getContext());
mTempImage.setScaleType(ImageView.ScaleType.FIT_XY);
//初始化底部view
mBottomView = new LinearLayout(getContext());
mBottomView.setGravity(Gravity.CENTER);
mBottomView.setBackgroundColor(Color.RED);
FrameLayout.LayoutParams bottomLayoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, bottomViewH);
bottomLayoutParams.gravity = Gravity.BOTTOM;
trash = new ImageView(getContext());
int wh = DisplayUtil.dpToPx(25);
FrameLayout.LayoutParams trashParams = new FrameLayout.LayoutParams(wh, wh);
trash.setLayoutParams(trashParams);
mBottomView.addView(trash);
TextView tipTextView = new TextView(getContext());
tipTextView.setTextColor(Color.WHITE);
tipTextView.setText("拖拽此处删除");
mBottomView.addView(tipTextView);
mBottomView.setOrientation(LinearLayout.VERTICAL);
mBottomView.setLayoutParams(bottomLayoutParams);
mBottomView.setVisibility(GONE);
out();
mFrameLayout.addView(mBottomView);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 3);
setLayoutManager(gridLayoutManager);
List<String> data = new LinkedList<>();
data.add("");
mDraggableAdapter = new DraggableAdapter(data);
DragAndSwipeCallback mItemDragAndSwipeCallback = new DragAndSwipeCallback(mDraggableAdapter);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(mItemDragAndSwipeCallback);
itemTouchHelper.attachToRecyclerView(this);
mDraggableAdapter.enableDragItem(itemTouchHelper, R.id.image, true);
mItemDragAndSwipeCallback.setSwipeMoveFlags(ItemTouchHelper.START | ItemTouchHelper.END);
mDraggableAdapter.setOnItemDragListener(new OnItemDragListener() {
@Override
public void onItemDragStart(RecyclerView.ViewHolder viewHolder, int pos) {
if(null!=mDragCallBack){
mDragCallBack.onStart();
}
mSelectPosition = pos;
mFrameLayout.removeView(mTempImage);
tempImageDel = false;
isDel = false;
in();
ImageView imageView = viewHolder.itemView.findViewById(R.id.image);
mTempImage.setImageDrawable(imageView.getDrawable());
ViewGroup.LayoutParams l = new ViewGroup.LayoutParams(imageView.getWidth(), imageView.getHeight());
mTempImage.setLayoutParams(l);
imageView.getGlobalVisibleRect(lastRect);
mTempImage.setX(lastRect.left);
mTempImage.setY(lastRect.top - mFixH);
mTempImage.setScaleX(1.2f);
mTempImage.setScaleY(1.2f);
mFrameLayout.addView(mTempImage);
imageView.setAlpha(0f);
}
@Override
public void onItemDragMoving(RecyclerView.ViewHolder source, int from, RecyclerView.ViewHolder target, int to) {
target.itemView.findViewById(R.id.image).getGlobalVisibleRect(lastRect);
mSelectPosition = to;
}
@Override
public void onItemDragEnd(RecyclerView.ViewHolder viewHolder, int pos) {
if(null!=mDragCallBack){
mDragCallBack.onEnd();
}
ImageView imageView = viewHolder.itemView.findViewById(R.id.image);
imageView.setScaleX(1f);
imageView.setScaleY(1f);
if (tempImageDel) {
mDraggableAdapter.remove(mSelectPosition);
} else {
imageView.setAlpha(1f);
mFrameLayout.removeView(mTempImage);
}
out();
}
});
setAdapter(mDraggableAdapter);
}
public void setFixH(int mFixH) {
this.mFixH = mFixH;
}
/**
* 拖住adapter
*/
private class DraggableAdapter extends BaseItemDraggableAdapter<String, BaseViewHolder> {
private DraggableAdapter(List<String> data) {
super(R.layout.base_iamge_item, data);
}
@Override
protected void convert(@NonNull BaseViewHolder helper, String item) {
ImageView imageView = helper.getView(R.id.image);//图片
LinearLayout.LayoutParams l = (LinearLayout.LayoutParams) imageView.getLayoutParams();
l.height = mImageWH;
l.width = mImageWH;
l.rightMargin = margin;
l.bottomMargin = margin;
l.topMargin = margin;
imageView.setLayoutParams(l);
ImageView imageView2 = helper.getView(R.id.image2);//加号
LinearLayout.LayoutParams l2 = (LinearLayout.LayoutParams) imageView.getLayoutParams();
l2.height = mImageWH;
l2.width = mImageWH;
l2.rightMargin = margin;
l2.bottomMargin = margin;
l2.topMargin = margin;
imageView2.setLayoutParams(l2);
/**
* 如果list的长度等于mImageCount 最后一张最后一张显示正常图片
*
*/
if(TextUtils.isEmpty(item)){
if(mImageCount <= helper.getAdapterPosition()){
imageView.setVisibility(View.GONE);
imageView2.setVisibility(View.GONE);
}else{
imageView.setVisibility(View.GONE);
imageView2.setVisibility(View.VISIBLE);
imageView2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (null != mAddClick) {
mAddClick.onAdd();
}
}
});
}
}else{
imageView.setVisibility(View.VISIBLE);
imageView2.setVisibility(View.GONE);
Glide.with(mContext).load(item).into(imageView);
}
imageView.setAlpha(1f);
}
}
/**
* 拖拽监听
*/
private class DragAndSwipeCallback extends ItemDragAndSwipeCallback {
private DragAndSwipeCallback(BaseItemDraggableAdapter adapter) {
super(adapter);
}
@Override
public boolean canDropOver(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder current, @NonNull RecyclerView.ViewHolder target) {
if (target.getAdapterPosition() == mDraggableAdapter.getData().size() - 1 || current.getAdapterPosition() == mDraggableAdapter.getData().size() - 1) {
return false;
}
return super.canDropOver(recyclerView, current, target);
}
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
super.onSelectedChanged(viewHolder, actionState);
if (actionState == ACTION_STATE_IDLE) {
//空闲状态
if (isDel) {
isDel = false;
tempImageDel = true;
mFrameLayout.removeView(mTempImage);
}
}
}
@Override
public void onChildDrawOver(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
super.onChildDrawOver(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
if (tempImageDel) {
return;
}
ImageView tempImageView = viewHolder.itemView.findViewById(R.id.image);
boolean b = tempImageView.getGlobalVisibleRect(rect);
Log.e("TAG", "dX:" + dX);
Log.e("TAG", "dY:" + dY);
if (b && dX > 0 && dY > 0) {
mTempImage.setX(rect.left);
mTempImage.setY(rect.top - mFixH);
} else {
mTempImage.setX(lastRect.left + dX);
mTempImage.setY(lastRect.top - mFixH + dY);
}
mTempImage.getGlobalVisibleRect(rect);
if (SCREEN_H - bottomViewH < rect.bottom) {
isDel = true;
trash.setBackgroundResource(R.drawable.base_trash_open);
} else {
isDel = false;
trash.setBackgroundResource(R.drawable.base_trash_close);
}
}
}
public void addData(String path) {
mDraggableAdapter.addData(0, path);
mDraggableAdapter.notifyItemChanged(mDraggableAdapter.getData().size()-1);
}
public void addData(List<String> path){
int size = mDraggableAdapter.getData().size();
int offset = mImageCount - size + 1;
if(offset > path.size()){
offset = path.size();
}
mDraggableAdapter.addData(0, path.subList(0,offset));
mDraggableAdapter.notifyItemChanged(mDraggableAdapter.getData().size() -1);
}
public void setImageCount(int mImageCount) {
this.mImageCount = mImageCount;
}
public void setAddClick(AddClick mAddClick) {
this.mAddClick = mAddClick;
}
public void setDragCallBack(DragCallBack mDragCallBack) {
this.mDragCallBack = mDragCallBack;
}
/**
* 获取列表
*
* @return
*/
public List<String> getData() {
List<String> res = new LinkedList<>();
for (int i = 0; i < mDraggableAdapter.getData().size() - 1; i++) {
res.add(mDraggableAdapter.getData().get(i));
}
return res;
}
/**
* 底部进入
*/
private void in() {
mBottomView.setVisibility(View.VISIBLE);
ObjectAnimator animator = ObjectAnimator.ofFloat(mBottomView, "translationY", 0)
.setDuration(200);
animator.start();
}
/**
* 底部移除屏幕外部
*/
private void out() {
final int moveX = DisplayUtil.dpToPx(55);
ObjectAnimator animator = ObjectAnimator.ofFloat(mBottomView, "translationY", moveX)
.setDuration(200);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mBottomView.setVisibility(View.GONE);
trash.setBackgroundResource(R.drawable.base_trash_close);
}
});
animator.start();
}
public interface AddClick {
void onAdd();
}
public interface DragCallBack{
void onStart();
void onEnd();
}
}
iamge_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/l"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:scaleType="fitXY"
android:id="@+id/image"
android:layout_width="149dp"
android:layout_height="149dp" />
<ImageView
android:id="@+id/image2"
android:visibility="gone"
android:layout_width="149dp"
android:layout_height="149dp" />
</LinearLayout>
总结
以上所述是小编给大家介绍的Android 仿微信发动态九宫格拖拽、删除功能网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
来源:https://blog.csdn.net/INTKILOW/article/details/103101782


猜你喜欢
- 1、字符数组的定义与初始化字符数组的初始化,最容易理解的方式就是逐个字符赋给数组中各元素。char str[10]={ 'I'
- 本文实例为大家分享了C++实现哈夫曼编码的具体代码,供大家参考,具体内容如下#include<iostream>#include
- 在sql server2005以及之后的sql server中引入了Xml数据类型,在C#中使用Xml数据类型需要指定参数类型为SqlDbT
- 购物车项目,业务需要实现了一个购物车的项目,简单的了解下实现逻辑:数据计算等是在Adapter中计算出来的,通过在Adapter中计算出来的
- Android Bitmap和Drawable的对比Bitmap - 称作位图,一般位图的文件格式后缀为bmp,当然编码器也有很多如RGB5
- 1、确定本地网络是通的:2、确定SpringBootq启动后是不报错的3、查看是不是自己在配置文件中加入了项目路径:如果加入了项目路径的话,
- 一般数据库的编码是utf8,utf8是不支持存储表情符的,当存入的微信昵称带有表情符时就会出现乱码情况,有两种解决方法:1.mysql数据库
- 下面就列出配置eclipse联想功能(代码的提示功能)的步骤:1. 打开Eclipse,然后“window”→“Preferences”2.
- 环境操作系统windows10JDKjdk1.8.0_192IDEEclipse IDE for Enterprise Java Devel
- 今天碰到一个非常奇怪的问题: 在Android中ImageView无法显示加载的本地SDCard图片。 具体过程是:先调用本地照相机程序摄像
- 前言目前有两套RocketMQ集群,集群A包含topic名称为cluster_A_topic,集群B包含topic名称为cluster_B_
- 一般文本文件我们以日志文件.log文件为例:import java.io.BufferedReader; import java.io.Fi
- 在一个项目中,如果我们既用到了Struts2又用到了Servlet,项目运行时有可能无法正常访问Servlet,原因是在配置Struts的过
- 日常对于金额计算,应该都是用的BigDecimal,可是苦于没有好的工具类方法,现在贡献一个我正在用的对于数字计算的工具类,项目中就是用的这
- 碰到一个项目,需要对指定的网页进行截图保存,晕死! 需求永远都是怪异的..... 解决是关键~ 遂写了以下代码,快准狠!(因为赶时间!) 可
- Wrapper条件构造器updateForSet更新官方文档:https://baomidou.gitee.io/mybatis-plus-
- Java 虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途,如图所示:程序计数器程序计数
- 在安装过后出现了这样的问题:于是看了一下,是找不到这个版本,于是到gradle文件里加了一句话,指定好版本,切记不要低于26,然后去sdk
- 本文实例讲述了C#编程获取各种电脑硬件信息的方法。分享给大家供大家参考,具体如下:获取CPU编号:ManagementClass mc =
- Spring Data JPA 映射VO/DTO对象在项目开发中,时常需要根据业务需求来映射VO/DTO对象(这两个概念理解感觉很模糊- 。