안 드 로 이 드 모방 왕 이 뉴스 클 라 이언 트 분류 정렬 기능

먼저 왕 이 뉴스 클 라 이언 트 와 자신 이 실현 한 효과 도 를 살 펴 보 자.효 과 는 당연히 왕 이 가 좋다.

gridviewsort.gif

어떻게 끌 어 당 기 는 아 이 템 을 실현 합 니까?
WindowManager 로 ImageView 를 추가 하고 이 ImageView 의 디 스 플레이 그림 을 끌 어 당 기 는 item 의 캡 처 로 설정 합 니 다.캡 처 는 View 의 getDrawingCache 를 통 해 얻 을 수 있 습 니 다.드래그 할 때 원본 아 이 템 을 숨 깁 니 다.터치 이 벤트 를 처리 하 는 ActionMove 는 ImageView 의 위 치 를 조정 하고 손가락 을 따라 이동 합 니 다.액 션 업 할 때 removeView.
GridView

 @Override
  public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l)
  {
    //      item   ,    
    if (getChildCount() >= 2)
    {
      mView = view;
      //    getDrawingCache     
      view.setDrawingCacheEnabled(true);
      //        
      Bitmap bitmap = view.getDrawingCache();
      mDragItemView.setImageBitmap(bitmap);
      //      imageview params
      mDragItemLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
      mDragItemLayoutParams.width = bitmap.getWidth();
      mDragItemLayoutParams.height = bitmap.getHeight();
      mDragItemLayoutParams.x = (mDownX - mDragItemLayoutParams.width / 2);
      mDragItemLayoutParams.y = (mDownY - mDragItemLayoutParams.height / 2);
      //     imageview          
      mDragItemLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE //       
          | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE //        
          | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON  //     
          | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; // place the window within the entire screen, ignoring decorations around the border (such as the status bar)
      mDragItemLayoutParams.format = PixelFormat.TRANSLUCENT;
      mDragItemLayoutParams.windowAnimations = 0;
      //  WindowManager      View
      mWindowManager.addView(mDragItemView, mDragItemLayoutParams);
      ((GridViewSortAdapter) getAdapter()).init();
      ((GridViewSortAdapter) getAdapter()).hideView(i);
      Log.d(TAG, "long click = " + i);
      mDragStarted = true;
    }
    return true;
  }
@Override
public boolean onTouchEvent(MotionEvent ev)
{
  switch (ev.getAction() & ev.getActionMasked())
  {
    case MotionEvent.ACTION_DOWN:
      mDownX = (int) ev.getRawX();
      mDownY = (int) ev.getRawY();
      break;
    case MotionEvent.ACTION_MOVE:
      if (mDragStarted)
      {
        //     
        mDragItemLayoutParams.x = (int) (ev.getRawX() - mDragItemView.getWidth() / 2);
        mDragItemLayoutParams.y = (int) (ev.getRawY() - mDragItemView.getHeight() / 2);
        //   params
        mWindowManager.updateViewLayout(mDragItemView, mDragItemLayoutParams);
        // ......
      }
      break;
    case MotionEvent.ACTION_UP:
      // ......
      break;
  }
  return super.onTouchEvent(ev);
}
끌 어 당 기 는 아 이 템 을 숨 기 는 방법
드래그 를 시작 할 때 숨겨 진 item 의 position 을 Adapter 에 알 리 고 Adapter 의 notifyDataSetChanged 를 호출 하여 데 이 터 를 새로 고 칩 니 다.getView 방법 에서 현재 구 축 된 item 의 position 가 숨겨 야 할 position 인지 판단 합 니 다.
GridView

@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l)
{
  // ......
  ((GridViewSortAdapter) getAdapter()).hideView(i);
  // ......
}
GridViewSortAdapter
public void hideView(int item)
{
  // ......
  mStartHideItemPosition = item;
  notifyDataSetChanged();
}
private int mStartHideItemPosition = AdapterView.INVALID_POSITION;
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
  ViewHolder holder = null;
  if (convertView == null)
  {
    convertView = LayoutInflater.from(mContext).inflate(R.layout.view_item_grid_view_sort, null);
    holder = new ViewHolder();
    holder.title = (TextView) convertView.findViewById(R.id.view_item_grid_view_sort_title);
    convertView.setTag(holder);
  }
  else
  {
    holder = (ViewHolder) convertView.getTag();
  }
  holder.title.setText(mTypeTitle.get(position));
  if (mStartHideItemPosition == position)
  {
    convertView.setVisibility(View.INVISIBLE);
  }
  else
  {
    convertView.setVisibility(View.VISIBLE);
  }
  return convertView;
}
현재 어떤 아 이 템 위로 끌 어 올 리 는 지 어떻게 압 니까?
다른 아 이 템 위로 끌 어 올 릴 때 위 치 를 바 꾸 려 면 현재 어떤 아 이 템 위로 끌 어 올 렸 는 지 알 아야 합 니 다.GrideView 는 터치 이 벤트 를 처리 할 수 있 는 pointToPosition 이라는 방법 을 제공 합 니 다.ACTIONMOVE 시 손가락 터치 의 x,y 를 가 져 와 현재 아 이 템 위로 끌 어 당 기 는 position 를 가 져 옵 니 다.여기 서 주의해 야 할 것 은 끌 어 당 기 는 과정 에서 같은 item 의 position 는 변 하지 않 습 니 다.Adapter 의 notify DataSetChanged 를 호출 하지 않 는 한 position 는 다시 계산 할 수 있 습 니 다.예 를 들 어 position 이 2 인 item 은 끌 어 당 기 는 과정 에서 아무리 위 치 를 애니메이션 으로 이동 하 더 라 도 그의 position 은 2 입 니 다.끌 어 당 기 는 것 이 끝 난 것 을 알 고 Action Up 을 할 때 notify DataSetChanged 를 호출 합 니 다.
GridView

@Override
 public boolean onTouchEvent(MotionEvent ev)
 {
  case MotionEvent.ACTION_MOVE:
  if (mDragStarted)
  {
    // ......
    int position = pointToPosition((int) ev.getX(), (int) ev.getY());
    // ......
  }
  break;
}
어떻게 애니메이션 을 실현 합 니까?
하나의 아 이 템 이 수평 과 수직 으로 이동 해 야 하 는 거 리 를 미리 계산 할 수 있 습 니 다.사실 수평 거 리 는 어쨌든 GridView 의 한 칸 너비 에 수평 거 리 를 더 해 야 합 니 다.수직 거 리 는 어쨌든 하나의 칸 의 높이 에 수직 거 리 를 더 해 너비 가 매우 좋 습 니 다.높이 는...기본 아 이 템 의 높이 는 셀 의 높이 와 같 습 니 다.
GridViewSortAdapter

View view = mGridView.getChildAt(0);
mTranslateX = view.getWidth() + mHorizontalSpace;
mTranslateY = view.getHeight() + mVerticalSpace;
다른 아 이 템 위로 끌 어 올 릴 때 애니메이션 시작
SortGridView

if (position != AdapterView.INVALID_POSITION && !((GridViewSortAdapter) getAdapter()).isInAnimation())
{  
   Log.d(TAG, "position = " + position);  
   ((GridViewSortAdapter) getAdapter()).swap(position);
}
GridSortAdapter
public void swap(int position)
{
  mAnimatorSetList.clear();
  int r_p = mPositionList.indexOf(position);
  Log.d(TAG, "r_p = " + r_p);
  if (mCurrentHideItemPosition < r_p)
  {
    for (int i = mCurrentHideItemPosition + 1; i <= r_p; i++)
    {
      View v = mGridView.getChildAt(mPositionList.get(i));
      if (i % mColsNum == 0 && i > 0)
      {
        startMoveAnimation(v, v.getTranslationX() + mTranslateX * (mColsNum - 1), v.getTranslationY() -
            mTranslateY);
      }
      else
      {
        startMoveAnimation(v, v.getTranslationX() - mTranslateX, 0);
      }
    }
  }
  else if (mCurrentHideItemPosition > r_p)
  {
    for (int i = r_p; i < mCurrentHideItemPosition; i++)
    {
      View v = mGridView.getChildAt(mPositionList.get(i));
      if ((i + 1) % mColsNum == 0)
      {
        startMoveAnimation(v, v.getTranslationX() - mTranslateX * (mColsNum - 1), v.getTranslationY() + mTranslateY);
      }
      else
      {
        startMoveAnimation(v, v.getTranslationX() + mTranslateX, 0);
      }
    }
  }
  resetPositionList();
  int value = mPositionList.get(mStartHideItemPosition);
  if (mStartHideItemPosition < r_p)
  {
    mPositionList.add(r_p + 1, value);
    mPositionList.remove(mStartHideItemPosition);
  }
  else if (mStartHideItemPosition > r_p)
  {
    mPositionList.add(r_p, value);
    mPositionList.remove(mStartHideItemPosition + 1);
  }
  mCurrentHideItemPosition = r_p;
}
public boolean isInAnimation()
{
  return mInAnimation;
}
private void resetPositionList()
{
  mPositionList.clear();
  for (int i = 0; i < mGridView.getChildCount(); i++)
  {
    mPositionList.add(i);
  }
}
private void startMoveAnimation(View myView, float x, float y)
{
  AnimatorSet set = new AnimatorSet();
  set.playTogether(
      ObjectAnimator.ofFloat(myView, "translationX", myView.getTranslationX(), x),
      ObjectAnimator.ofFloat(myView, "translationY", myView.getTranslationY(), y)
  );
  set.addListener(new Animator.AnimatorListener()
  {
    @Override
    public void onAnimationStart(Animator animator)
    {
      mInAnimation = true;
    }
    @Override
    public void onAnimationEnd(Animator animator)
    {
      mInAnimation = false;
    }
    @Override
    public void onAnimationCancel(Animator animator)
    {
    }
    @Override
    public void onAnimationRepeat(Animator animator)
    {
    }
  });
  mAnimatorSetList.add(set);
  set.setDuration(150).start();
}
여기 서 저 는 코드 에 있 는 mPosition List 라 는 목록 의 역할 을 설명 하 겠 습 니 다.전에 한 번 끌 었 을 때 item 의 position 은 변 하지 않 을 것 이 라 고 말 했 습 니 다.
한 그룹의 데이터 가 있다 고 가정 하 다.
a b c d
e f g h
i j k l
이때 mPositionest 의 내용 은 0,1,2,3,4,5,6,7,8,9,10,11,12 입 니 다.
현재 c 를 g 위로 끌 어 올 립 니 다.끌 어 다 놓 은 데 이 터 는 손가락 을 놓 지 않 은 것 같 습 니 다.
a b d e
f g c h
i j k l
이때 mPositionest 의 내용 은 0,1,2,4,5,6,7,3,8,9,10,11,12 입 니 다.
이 어 c 를 e 위로 계속 끌 어 올 리 면 pointToPosition 방법 으로 얻 은 position 은 5 이지 만 e 현재 색인 은 4 입 니 다.
그 러 니까 호출 만 해.

mPositionList.indexOf(pointToPosition(x,y))
진실 한 아 이 템 의 포지션 을 얻 을 수 있 습 니 다.
기타
GridView 의 열 수 를 1 로 바 꾸 면 어디서 많이 본 것 같은 데.

gridviewex.gif
원본 주소
https://github.com/jiahuanyu/android-example-code/tree/master/app/src/main/java/com/github/jiahuanyu/example/ui/dragsortgird
위 에서 말 한 것 은 편집장 이 여러분 에 게 소개 한 안 드 로 이 드 모방 왕 이 뉴스 클 라 이언 트 의 분류 정렬 기능 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.만약 에 궁금 한 점 이 있 으 면 저 에 게 메 시 지 를 남 겨 주세요.편집장 은 신속하게 여러분 에 게 답 할 것 입 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기