欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

gridviewsort.gif

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

用WindowManager添加一個(gè)ImageView,并且將這個(gè)ImageView的顯示圖片設(shè)置成被拖拽item的截圖,截圖可以通過(guò)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來(lái)得到當(dāng)前拖拽到item之上的position。這里需要注意的一點(diǎn)是,在拖拽的過(guò)程,同一個(gè)item的position是不會(huì)變的,除非調(diào)用了Adapter的notifyDataSetChanged,position才會(huì)重新計(jì)算。比如position為2的item,在拖拽的過(guò)程無(wú)論怎么動(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ì)算出來(lái),其實(shí)水平距離不管怎么樣一定會(huì)是GridView一個(gè)單元格的寬度加上水平間距,垂直距離無(wú)論如何都是一個(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è)列表的作用,之前說(shuō)過(guò)一次拖拽的時(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)文章

  • 使用RecyclerView添加Header和Footer的方法

    使用RecyclerView添加Header和Footer的方法

    RecyclerView雖然作為L(zhǎng)istView的替代者有著較好的性能提升,但是ListView的一些常用功能卻沒有提供,比如我們平時(shí)會(huì)經(jīng)常用到的addHeaderView,addFooterView,既然RecyclerView沒有提供這個(gè)方法,我們應(yīng)該如何為列表添加頭部和底部呢,接下來(lái)通過(guò)本文給大家介紹
    2016-03-03
  • android百度地圖之公交線路詳情搜索

    android百度地圖之公交線路詳情搜索

    本篇文章介紹了android百度地圖之公交線路詳情搜索,實(shí)現(xiàn)了百度搜索公交詳情具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2016-10-10
  • Android開發(fā)技巧之在a標(biāo)簽或TextView控件中單擊鏈接彈出Activity(自定義動(dòng)作)

    Android開發(fā)技巧之在a標(biāo)簽或TextView控件中單擊鏈接彈出Activity(自定義動(dòng)作)

    a標(biāo)簽以及TextView自動(dòng)識(shí)別的特殊文本(網(wǎng)址、電話號(hào)、Email等),這些都可以通過(guò)單擊來(lái)觸發(fā)不同的動(dòng)作;但如果讀者想在單擊鏈接時(shí)執(zhí)行任意自定義的動(dòng)作,那么將要介紹的一定是你想要的了
    2013-01-01
  • Android中LayoutInflater.inflater()的正確打開方式

    Android中LayoutInflater.inflater()的正確打開方式

    這篇文章主要給大家介紹了關(guān)于Android中LayoutInflater.inflater()的正確打開方式,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • Android中CountDownTimer 實(shí)現(xiàn)倒計(jì)時(shí)功能

    Android中CountDownTimer 實(shí)現(xiàn)倒計(jì)時(shí)功能

    本篇文章主要介紹了Android中CountDownTimer 實(shí)現(xiàn)倒計(jì)時(shí)功能,CountDownTimer 是android 自帶的一個(gè)倒計(jì)時(shí)類,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Android studio設(shè)計(jì)簡(jiǎn)易計(jì)算器

    Android studio設(shè)計(jì)簡(jiǎn)易計(jì)算器

    這篇文章主要為大家詳細(xì)介紹了Android studio設(shè)計(jì)簡(jiǎn)易計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • Android 實(shí)現(xiàn)加載大圖片的方法

    Android 實(shí)現(xiàn)加載大圖片的方法

    對(duì)于超大的圖片,如果不縮放的話,容易導(dǎo)致內(nèi)存溢出。而經(jīng)過(guò)處理后,無(wú)論多大的圖片,都能夠在手機(jī)屏幕上加載出來(lái),不會(huì)導(dǎo)致內(nèi)存溢出。本文將對(duì)Android 加載大圖片的實(shí)現(xiàn)方法進(jìn)行介紹,下面跟著小編一起來(lái)看下吧
    2017-04-04
  • Android 6.0以上權(quán)限拒絕打開權(quán)限設(shè)置界面的解決方法

    Android 6.0以上權(quán)限拒絕打開權(quán)限設(shè)置界面的解決方法

    今天小編就為大家分享一篇Android 6.0以上權(quán)限拒絕打開權(quán)限設(shè)置界面的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • Android Studio 升級(jí)到3.0后輸入法中文狀態(tài)下無(wú)法選詞的終極解決方案

    Android Studio 升級(jí)到3.0后輸入法中文狀態(tài)下無(wú)法選詞的終極解決方案

    這篇文章主要介紹了 AndroidStudio 升級(jí)到3.0后輸入法中文狀態(tài)下無(wú)法選詞的解決方案,需要的朋友可以參考下
    2017-11-11
  • Android提高之藍(lán)牙隱藏API探秘

    Android提高之藍(lán)牙隱藏API探秘

    這篇文章主要介紹了Android的藍(lán)牙隱藏API功能,在Android項(xiàng)目開發(fā)中有一定的借鑒價(jià)值,需要的朋友可以參考下
    2014-08-08

最新評(píng)論