亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Android 仿網(wǎng)易新聞客戶端分類排序功能

 更新時(shí)間:2016年12月26日 10:32:14   作者:l_215851356  
這篇文章主要介紹了Android 仿網(wǎng)易新聞客戶端分類排序功能,實(shí)現(xiàn)此功能涉及到拖拽item及隱藏拖拽的Item的方法,本文給大家介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友參考下吧

先來看看網(wǎng)易新聞客戶端以及自己實(shí)現(xiàn)的效果圖,效果當(dāng)然還是網(wǎng)易的好

gridviewsort.gif

如何實(shí)現(xiàn)拖拽一個(gè)Item

用WindowManager添加一個(gè)ImageView,并且將這個(gè)ImageView的顯示圖片設(shè)置成被拖拽item的截圖,截圖可以通過View的getDrawingCache獲得。拖拽的時(shí)候,隱藏原始的item。處理觸摸事件的ActionMove,調(diào)整ImageView的位置,跟隨手指移動(dòng)。在ActionUp的時(shí)候removeView

GridView

 @Override
  public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l)
  {
    // 至少有兩個(gè)item的時(shí)候,才有排序
    if (getChildCount() >= 2)
    {
      mView = view;
      // 在調(diào)用getDrawingCache必須先調(diào)用
      view.setDrawingCacheEnabled(true);
      // 獲取截圖并設(shè)置
      Bitmap bitmap = view.getDrawingCache();
      mDragItemView.setImageBitmap(bitmap);
      // 設(shè)置拖拽的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);
      // 設(shè)置拖拽imageview的中心位于長(zhǎng)按點(diǎn)擊點(diǎn)
      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);
}

如何實(shí)現(xiàn)隱藏拖拽的Item

在開始拖拽的時(shí)候,把隱藏的item的position告訴Adapter,調(diào)用Adapter的notifyDataSetChanged刷新數(shù)據(jù),在getView方法中判斷當(dāng)前的構(gòu)建的item的position是不是需要隱藏的position是的話就設(shè)置view為inVisible

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;
}

如何知道當(dāng)前拖拽到哪一個(gè)item之上

要想在拖拽到其他item上面時(shí)互換位置,那必須得知道當(dāng)前拖拽到了哪一個(gè)item之上。GrideView提供了一個(gè)方法叫pointToPosition,可以在處理觸摸事件的ACTION_MOVE時(shí),獲取手指觸摸的x,y來得到當(dāng)前拖拽到item之上的position。這里需要注意的一點(diǎn)是,在拖拽的過程,同一個(gè)item的position是不會(huì)變的,除非調(diào)用了Adapter的notifyDataSetChanged,position才會(huì)重新計(jì)算。比如position為2的item,在拖拽的過程無論怎么動(dòng)畫移動(dòng)位置,他的position都是2,知道一次拖拽結(jié)束,ActionUp的時(shí)候,會(huì)調(diào)用notifyDataSetChanged

GridView

@Override
 public boolean onTouchEvent(MotionEvent ev)
 {
  case MotionEvent.ACTION_MOVE:
  if (mDragStarted)
  {
    // ......
    int position = pointToPosition((int) ev.getX(), (int) ev.getY());
    // ......
  }
  break;
}

如何實(shí)現(xiàn)動(dòng)畫

一個(gè)item需要水平以及垂直需要移動(dòng)的距離可以事先先計(jì)算出來,其實(shí)水平距離不管怎么樣一定會(huì)是GridView一個(gè)單元格的寬度加上水平間距,垂直距離無論如何都是一個(gè)單元格的高度加上垂直距離,寬度非常好取,高度的話,這里默認(rèn)item 的高度和單元格的高度相同。

GridViewSortAdapter

View view = mGridView.getChildAt(0);
mTranslateX = view.getWidth() + mHorizontalSpace;
mTranslateY = view.getHeight() + mVerticalSpace;

當(dāng)拖拽到其他item之上時(shí),開始動(dòng)畫

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();
}

這里我主要解釋一下代碼中 mPositionList這個(gè)列表的作用,之前說過一次拖拽的時(shí)候,item的position是不會(huì)變化的。

假設(shè)有一組數(shù)據(jù)

a b c d
e f g h
i j k l

此時(shí)mPositionList的內(nèi)容就是 0 1 2 3 4 5 6 7 8 9 10 11 12

現(xiàn)在將c拖拽到g上,拖拽完成之后的數(shù)據(jù)應(yīng)該是,未釋放手指

a b d e
f g c h
i j k l

此時(shí)mPositionList的內(nèi)容就是 0 1 2 4 5 6 7 3 8 9 10 11 12

緊接著,繼續(xù)拖拽c到e上,你會(huì)發(fā)現(xiàn)調(diào)用pointToPosition方法得到的position是5,但是e現(xiàn)在的索引是4

因此你只需要調(diào)用

mPositionList.indexOf(pointToPosition(x,y))

就能得到真實(shí)的item的position

其他

如果把GridView的列數(shù)變成1那么似曾相識(shí)啊

gridviewex.gif

源碼地址

https://github.com/jiahuanyu/android-example-code/tree/master/app/src/main/java/com/github/jiahuanyu/example/ui/dragsortgird

以上所述是小編給大家介紹的Android 仿網(wǎng)易新聞客戶端分類排序功能,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

最新評(píng)論