Android 频道管理,可拖动item排列,删除,添加

样式效果

         

 

1、创建自定义GridView

/*** 作者:created by meixi* 邮箱:15913707499@163.com* 日期:2019/5/31 13*/public class DragGridView extends GridView {/** 点击时候的X位置 */public int downX;/** 点击时候的Y位置 */public int downY;/** 点击时候对应整个界面的X位置 */public int windowX;/** 点击时候对应整个界面的Y位置 */public int windowY;/** VIEW相对自己的X */private int win_view_x;/**VIEW相对自己的Y*/private int win_view_y;/** 长按时候对应postion */public int dragPosition;/** Up后对应的ITEM的Position */private int dropPosition;/** 开始拖动的ITEM的Position*/private int startPosition;/** item高 */private int itemHeight;/** item宽 */private int itemWidth;/** 拖动的时候对应ITEM的VIEW */private View dragImageView = null;/** 长按的时候ITEM的VIEW*/private ViewGroup dragItemView = null;/** WindowManager管理器 */private WindowManager windowManager = null;/** */private WindowManager.LayoutParams windowParams = null;/** item总量*/private int itemTotalCount;/** 一行的ITEM数量*/private int nColumns = 4;/** 行数 */private int nRows;/** 剩余部分 */private int Remainder;/** 是否在移动 */private boolean isMoving = false;/** */private int holdPosition;/** 拖动的时候放大的倍数 */private double dragScale = 1.2D;/** 震动器  */private Vibrator mVibrator;/** 每个ITEM之间的水平间距 */private int mHorizontalSpacing = 15;/** 每个ITEM之间的竖直间距 */private int mVerticalSpacing = 15;/** 移动时候最后个动画的ID */private String LastAnimationID;public DragGridView(Context context) {super(context);init(context);}public DragGridView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init(context);}public DragGridView(Context context, AttributeSet attrs) {super(context, attrs);init(context);}/*** dip转为 px*/public  int dip2px(Context context, float dipValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (dipValue * scale + 0.5f);}public void init(Context context){mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);//将布局文件中设置的间距dip转为pxmHorizontalSpacing = dip2px(context, mHorizontalSpacing);}/** 在ScrollView内,所以要进行计算高度 */@Overridepublic void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);super.onMeasure(widthMeasureSpec, expandSpec);}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {if (ev.getAction() == MotionEvent.ACTION_DOWN) {downX = (int) ev.getX();downY = (int) ev.getY();windowX = (int) ev.getX();windowY = (int) ev.getY();setOnItemClickListener(ev);}return super.dispatchTouchEvent(ev);}/** 停止拖动 ,释放并初始化 */private void stopDrag() {if (dragImageView != null) {windowManager.removeView(dragImageView);dragImageView = null;}}/** 在拖动的情况更新View的位置 */private void onDrag(int x, int y , int rawx , int rawy) {if (dragImageView != null) {windowParams.alpha = 0.6f;windowParams.x = rawx - win_view_x;windowParams.y = rawy - win_view_y;windowManager.updateViewLayout(dragImageView, windowParams);}}/***创建窗口对象、添加我们要移动的View* @param dragBitmap* @param x* @param y*/public void startDrag(Bitmap dragBitmap, int x, int y) {stopDrag();windowParams = new WindowManager.LayoutParams();// 获取WINDOW界面的//Gravity.TOP|Gravity.LEFT;这个必须加windowParams.gravity = Gravity.TOP | Gravity.LEFT;//得到要移动的View左上角相对于屏幕的坐标windowParams.x = x - win_view_x;windowParams.y = y  - win_view_y;//设置拖拽item的宽和高windowParams.width = (int) (dragScale * dragBitmap.getWidth());// 放大dragScale倍,可以设置拖动后的倍数windowParams.height = (int) (dragScale * dragBitmap.getHeight());// 放大dragScale倍,可以设置拖动后的倍数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);// "window"windowManager.addView(iv, windowParams);dragImageView = iv;}/** 隐藏 放下 的ITEM*/private void hideDropItem() {((DragAdapter) getAdapter()).setShowDropItem(false);}/** 在松手下放的情况,更新界面 */private void onDrop(int x, int y) {// 根据拖动到的x,y坐标获取拖动位置下方的ITEM对应的POSTIONint tempPostion = pointToPosition(x, y);
//    if (tempPostion != AdapterView.INVALID_POSITION) {dropPosition = tempPostion;DragAdapter mDragAdapter = (DragAdapter) getAdapter();//显示刚拖动的ITEMmDragAdapter.setShowDropItem(true);//刷新适配器,让对应的ITEM显示mDragAdapter.notifyDataSetChanged();
//    }}/*** 长按点击监听* @param ev*/public void setOnItemClickListener(final MotionEvent ev) {setOnItemLongClickListener(new OnItemLongClickListener() {@Overridepublic boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {int x = (int) ev.getX();// 长按事件的X位置int y = (int) ev.getY();// 长按事件的y位置startPosition = position;// 第一次点击的postiondragPosition = position;if (startPosition <= 1) {//前2个默认不点击、可以设置return false;}ViewGroup dragViewGroup = (ViewGroup) getChildAt(dragPosition - getFirstVisiblePosition());TextView dragTextView = (TextView)dragViewGroup.findViewById(R.id.text_item);dragTextView.setSelected(true);dragTextView.setEnabled(false);itemHeight = dragViewGroup.getHeight();itemWidth = dragViewGroup.getWidth();itemTotalCount = DragGridView.this.getCount();// 如果特殊的这个不等于拖动的那个,并且不等于-1if (dragPosition != AdapterView.INVALID_POSITION) {// 释放的资源使用的绘图缓存。如果你调用buildDrawingCache()手动没有调用setDrawingCacheEnabled(真正的),你应该清理缓存使用这种方法。win_view_x = windowX - dragViewGroup.getLeft();//VIEW相对自己的X,半斤win_view_y = windowY - dragViewGroup.getTop();//VIEW相对自己的y,半斤dragItemView = dragViewGroup;dragViewGroup.destroyDrawingCache();dragViewGroup.setDrawingCacheEnabled(true);Bitmap dragBitmap = Bitmap.createBitmap(dragViewGroup.getDrawingCache());mVibrator.vibrate(50);//设置震动时间startDrag(dragBitmap, (int)ev.getRawX(),  (int)ev.getRawY());hideDropItem();dragViewGroup.setVisibility(View.INVISIBLE);isMoving = false;return true;}return false;}});}@Overridepublic boolean onTouchEvent(MotionEvent ev) {if (dragImageView != null && dragPosition != AdapterView.INVALID_POSITION) {// 移动时候的对应x,y位置int x = (int) ev.getX();int y = (int) ev.getY();switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:downX = (int) ev.getX();windowX = (int) ev.getX();downY = (int) ev.getY();windowY = (int) ev.getY();break;case MotionEvent.ACTION_MOVE:onDrag(x, y ,(int) ev.getRawX() , (int) ev.getRawY());if (!isMoving){OnMove(x, y);}if (pointToPosition(x, y) != AdapterView.INVALID_POSITION){break;}break;case MotionEvent.ACTION_UP:stopDrag();onDrop(x, y);requestDisallowInterceptTouchEvent(false);break;default:break;}}return super.onTouchEvent(ev);}/** 移动的时候触发,移动所有改变的Item*/public void OnMove(int x, int y) {// 拖动的VIEW下方的POSTIONint dPosition = pointToPosition(x, y);// 判断下方的POSTION是否是最开始2个不能拖动的if (dPosition > 1) {if ((dPosition == -1) || (dPosition == dragPosition)){return;}dropPosition = dPosition;if (dragPosition != startPosition){dragPosition = startPosition;}int movecount;//拖动的=开始拖的,并且 拖动的 不等于放下的if ((dragPosition == startPosition) || (dragPosition != dropPosition)){//移需要移动的动ITEM数量movecount = dropPosition - dragPosition;}else{//移需要移动的动ITEM数量为0movecount = 0;}if(movecount == 0){return;}int movecount_abs = Math.abs(movecount);if (dPosition != dragPosition) {//dragGroup设置为不可见ViewGroup dragGroup = (ViewGroup) getChildAt(dragPosition);dragGroup.setVisibility(View.INVISIBLE);float to_x = 1;//移动的X偏移量float to_y;// 移动的Y偏移量//x_vlaue移动的距离百分比(相对于自己长度的百分比)float x_vlaue = ((float) mHorizontalSpacing / (float) itemWidth) + 1.0f;//y_vlaue移动的距离百分比(相对于自己宽度的百分比)float y_vlaue = ((float) mVerticalSpacing / (float) itemHeight) + 1.0f;Log.d("x_vlaue", "x_vlaue = " + x_vlaue);for (int i = 0; i < movecount_abs; i++) {to_x = x_vlaue;to_y = y_vlaue;//向右if (movecount > 0) {// 判断是不是同一行的holdPosition = dragPosition + i + 1;if (dragPosition / nColumns == holdPosition / nColumns) {to_x = - x_vlaue;to_y = 0;} else if (holdPosition % 4 == 0) {to_x = 3 * x_vlaue;to_y = - y_vlaue;} else {to_x = - x_vlaue;to_y = 0;}}else{//向左,下移到上,右移到左holdPosition = dragPosition - i - 1;if (dragPosition / nColumns == holdPosition / nColumns) {to_x = x_vlaue;to_y = 0;} else if((holdPosition + 1) % 4 == 0){to_x = -3 * x_vlaue;to_y = y_vlaue;}else{to_x = x_vlaue;to_y = 0;}}ViewGroup moveViewGroup = (ViewGroup) getChildAt(holdPosition);Animation moveAnimation = getMoveAnimation(to_x, to_y);moveViewGroup.startAnimation(moveAnimation);//如果是最后一个移动的,那么设置他的最后个动画ID为LastAnimationIDif (holdPosition == dropPosition) {LastAnimationID = moveAnimation.toString();}moveAnimation.setAnimationListener(new Animation.AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {isMoving = true;}@Overridepublic void onAnimationRepeat(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {// 如果为最后个动画结束,那执行下面的方法if (animation.toString().equalsIgnoreCase(LastAnimationID)) {DragAdapter mDragAdapter = (DragAdapter) getAdapter();mDragAdapter.exchange(startPosition,dropPosition);startPosition = dropPosition;dragPosition = dropPosition;isMoving = false;}}});}}}}/** 获取移动的动画 */public Animation getMoveAnimation(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);// 设置一个动画效果执行完毕后,View对象保留在终止的位置。mTranslateAnimation.setDuration(300L);return mTranslateAnimation;}
}

2、activity实现

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {private MyGridView mOtherGv;private DragGridView mUserGv;private List<String> mUserList = new ArrayList<>();private List<String> mOtherList = new ArrayList<>();private OtherAdapter mOtherAdapter;private DragAdapter  mUserAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();}public void initView() {mUserGv = (DragGridView) findViewById(R.id.userGridView);mOtherGv = (MyGridView) findViewById(R.id.otherGridView);mUserList.add("推荐");mUserList.add("热点");mUserList.add("上海");mUserList.add("时尚");mUserList.add("科技");mUserList.add("体育");mUserList.add("军事");mUserList.add("财经");mUserList.add("网络");mOtherList.add("汽车");mOtherList.add("房产");mOtherList.add("社会");mOtherList.add("情感");mOtherList.add("女人");mOtherList.add("旅游");mOtherList.add("健康");mOtherList.add("美女");mOtherList.add("游戏");mOtherList.add("数码");mOtherList.add("娱乐");mOtherList.add("探索");mUserAdapter = new DragAdapter(this, mUserList,true);mOtherAdapter = new OtherAdapter(this, mOtherList,false);mUserGv.setAdapter(mUserAdapter);mOtherGv.setAdapter(mOtherAdapter);mUserGv.setOnItemClickListener(this);mOtherGv.setOnItemClickListener(this);}

demo云盘链接:https://pan.baidu.com/s/1iKAHJ3yrUeece1Yi1dsSEw

云盘密码交流:QQ1085220040

demo链接:https://download.csdn.net/download/meixi_android/11224016

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/414556.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2019王小的Java学习之路

文章背景 身边有个非常要好的朋友王某某&#xff0c;因为是发小的关系&#xff0c;之后文章统称为王小。 大专毕业后 顺利 的被安排进了某某工厂工作&#xff0c;工作一段时间后&#xff0c;尽管工作比较轻松&#xff0c;却无法忍受终日的流水线生活&#xff0c;经过我的介绍&…

JVM入门到放弃之基本概念

1. 基本概念 jvm 是可运行Java代码的假想计算机&#xff0c;包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。 jvm 是运行在操作系统之上的&#xff0c;屏蔽了与具体操作系统平台相关的信息&#xff0c;使得Java程序只需生成在 jvm 上运行的字节码…

java线程并发库之--线程同步工具Exchanger的使用

Exchanger可以在两个线程之间交换数据&#xff0c;只能是2个线程&#xff0c;他不支持更多的线程之间互换数据。今天我们就通过实例来学习一下Exchanger的用法。 Exchanger的简单实例 Exchanger是在两个任务之间交换对象的栅栏&#xff0c;当这些任务进入栅栏时&#xff0c;它们…

了解JVM运行时的内存分配

前言 上文中&#xff0c;在介绍运行时数据区域中的 JAVA 堆时&#xff0c;提到了 JVM 中的堆&#xff0c;一般分为三大部分&#xff1a;新生代、老年代、永久代&#xff0c;本文将进一步了解运行时的内存分配情况。 正文 1.新生代主要用来存放新生(new)的对象。一般占据堆的 …

C#:继承过程中的静态成员

在知乎上看到一个关于“泛基“的实现&#xff0c;感觉挺有意思&#xff0c;想试试效果&#xff0c;代码如下&#xff1a; public abstract class MyBase<T> where T : MyBase<T>{public static string DataForThisType { get; set; }public static T Instance { ge…

Android 分享功能大全

实现效果&#xff1a; 实现步骤&#xff1a; 1、配置SDK 2、 配置平台SDK demo云盘链接&#xff1a;https://pan.baidu.com/s/1DRr85PKtVpuexfyCc2jwsg 在线交流密码&#xff1a;QQ1085220040 demo链接&#xff1a;https://download.csdn.net/download/meixi_android/112506…

fiddler手机端抓包配置

首先&#xff0c;你得安装fiddler&#xff0c;这是前提条件&#xff0c;手机抓包有必须条件&#xff1a; 需要保持电脑和手机在同一个局域网中 &#xff08;这一点&#xff0c;我一般会在电脑上启动一个wifi&#xff0c;然后手机连接即可&#xff09; 下面说一下如何配置&#…

垃圾回收与算法

前边讲到 JVM 运行时内存的地方&#xff0c;关于新生代、老年代中 GC 垃圾回收以及垃圾回收算法&#xff0c;不知是否有点懵懵的&#xff0c;这篇一起了解一下垃圾回收以及垃圾回收算法。 一、垃圾回收需要完成的三件事 哪些内存需要回收&#xff1f;——垃圾对象&#xff08;如…

Android 起调手机QQ,联系客服

1、起调QQ聊天 public void toQQ(){// 跳转之前&#xff0c;可以先判断手机是否安装QQif (isQQClientAvailable(this)) {// 跳转到客服的QQString url "mqqwpa://im/chat?chat_typewpa&uin200870769";Intent intent2 new Intent(Intent.ACTION_VIEW, Uri.p…

jeecg中excel导出字段判空处理

jeecg中excel导出字段判空处理 我们清楚&#xff0c;jeecg 导出 excel 采用的是 easypoi&#xff0c;不知道是否遇到过这种情况&#xff1a; 我们以一个实体属性为例&#xff1a; Excel(name"问题分类",dicCode"xx")private java.lang.String mwoQuestion…

Android LinearLayout加载Fragment

为LinearLayout添加Fragment效果 1、创建Fragment public class Fragment1 extends Fragment {public static Fragment1 getInstance(Bundle bundle) {Fragment1 fg new Fragment1();fg.setArguments(bundle);return fg;}protected View contentView;Overridepublic View onC…

工作247:uniapp--实战--flex布局--商户星级

<template><view ><view v-for"(item,index) in 5"><view style"display: flex;padding: 24rpx 0 0 30rpx;"><text style"font-size: 30rpx;color: #333333;">001-祝菲</text><text style"margin-…

微信小程序开发实战基础一、页面跳转,底部导航栏,分享,加载图片标签,列表

1、页面跳转 wx.navigateTo({ url: "../four/four" })——可返回 wx.redirectTo({ url: "../four/four" })——不可返回 <view> <navigator url"../four/four" hover-class"changestyle">页面跳转&#xff0c;可以返回…

Java面向对象---重写(Override)与重载(Overload)

一、重写(Override) 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变&#xff0c;核心重写&#xff01; 重写的好处在于子类可以根据需要&#xff0c;定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。 重写方法…