一用到的知识
1.GridView的一些内部方法,如:怎么通过触摸的坐标获取对应的position等(这里我采用的是继承GridView控件)
3.位移动画Animation,本DEMO中主要用到:TranslateAnimation 平移动画
4.WindowManager的窗口机制,这里的item拖拽等都要设计到这个。
二.实现思路
1. 2个GridView--(1.DragGrid 2. OtherGridView)
DragGrid 用于显示我的频道,带有长按拖拽效果
OtherGridView用于显示更多频道,不带推拽效果
2. 点击2个GridView的时候,根据点击的Item对应的position,获取position对应的view,进行创建一层移动的动画层
起始位置:点击的positiongetLocationInWindow()获取。终点位置:另一个GridView的最后个ITEM 的position + 1的位置。
并赋予移动动画,等动画结束后对2者对应的频道列表进行数据的remove和add操作。
3. 设置点击和拖动的限制条件,如 推荐 这个ITEM是不允许用户操作的。
4. 拖动的DragGrid的操作:
(1)长按获取长按的ITEM的position -- dragPosition 以及对应的view ,手指触摸屏幕的时候,调用onInterceptTouchEvent来获取MotionEvent.ACTION_DOWN事件,获取对应的数据。由于这里是继承了GridView,所以长按时间可以通过setOnItemLongClickListener监听来执行,或则你也可以通过计算点击时间来监听是否长按。
(2)通过onTouchEvent(MotionEvent ev)来监听手指的移动和抬起动作。当它移动到 其它的item下面,并且下方的item对应的position 不等于 dragPosition,进行数据交换,并且2者之间的所有item进行移动动画,动画结束后,数据更替刷新界面。
(3) 抬起手后,清除掉拖动时候创建的view,让GridView中的数据显示。
三.流程图
接下来看看代码吧:
/** GRIDVIEW对应的ITEM点击监听接口 */
@Override
public void onItemClick(AdapterView<?> parent, final View view, final int position, long id) {
//如果点击的时候,之前动画还没结束,那么就让点击事件无效
if(isMove){
return;
}
switch (parent.getId()) {
case R.id.userGridView:
//position为 0,1 的不可以进行任何操作
if (position != 0 && position != 1) {
final ImageView moveImageView = getView(view);
if (moveImageView != null) {
TextView newTextView = (TextView) view.findViewById(R.id.text_item);
final int[] startLocation = new int[2];
newTextView.getLocationInWindow(startLocation);
final ChannelItem channel = ((DragAdapter) parent.getAdapter()).getItem(position);//获取点击的频道内容
otherAdapter.setVisible(false);
//添加到最后一个
otherAdapter.addItem(channel);
new Handler().postDelayed(new Runnable() {
public void run() {
try {
int[] endLocation = new int[2];
//获取终点的坐标
otherGridView.getChildAt(otherGridView.getLastVisiblePosition()).getLocationInWindow(endLocation);
MoveAnim(moveImageView, startLocation , endLocation, channel,userGridView);