1. 程式人生 > >Android 仿今日頭條頻道管理(上)(GridView之間Item的移動和拖拽)

Android 仿今日頭條頻道管理(上)(GridView之間Item的移動和拖拽)

前言

經常逛今日頭條、發現它的頻道管理功能做的特別贊,互動體驗非常好、如圖:


它是2個gridview組成、2個gridview之間的Item是可以相互更換的、而且我的頻道的Item是可以拖拽進行排序。仔細觀察、今日頭條有些細節做的的非常好,當一個gridview1的item移動到另一個gridview2時、gridview1的item不會立即消失、而是有一個沒有內容的背景框、等item移動gridview2操作完畢才會消失、並且gridview2在gridview1的Item到達之前也有一個沒有內容的背景框,等到達後覆蓋。給使用者一個很強的互動體驗,很贊。而且在item拖拽移動排序時、拖拽的item會變大變色、效果很贊,體驗極好。感興趣的話可以下一個今日頭條的客戶端看看。當看到這麼讚的互動體驗,我就想看看是怎麼實現的,這篇部落格先講2個Gridview之間item的移動,下一篇在帶來gridview的拖拽排序。

實現思路

要實現2個gridview之間的Item相互移動:

1、首先我們獲取我們點選的位置、處於gridview哪個位置

2、獲取位置後、我們就能拿到這個Item的View,我們獲取item繪製快取的Bitmap物件。

3、將Bitmap設定的一個Imageview上,然後將這個ImageView放到一個容器中去進行移動操作,這樣可能有人有疑問,為什麼不直接把item放到容器中去呢,是因為item已經有自己的父容器gridview,所以我們new一個Imageview來代替item

4、然後我們將imageview移動到另一個gridview的最後一個位置。

5、最後重新整理2個gridview的檢視、就能實現我們所見的效果。

實現程式碼

主程式程式碼:

  1. package com.test.drag;  
  2. import android.graphics.Bitmap;  
  3. import android.os.Bundle;  
  4. import android.os.Handler;  
  5. import android.support.v7.app.AppCompatActivity;  
  6. import android.view.View;  
  7. import android.view.ViewGroup;  
  8. import android.view.animation.Animation;  
  9. import android.view.animation.AnimationSet;  
  10. import android.view.animation.TranslateAnimation;  
  11. import android.widget.AdapterView;  
  12. import android.widget.AdapterView.OnItemClickListener;  
  13. import android.widget.GridView;  
  14. import android.widget.ImageView;  
  15. import android.widget.LinearLayout;  
  16. import android.widget.TextView;  
  17. import com.test.drag.view.MyGridView;  
  18. import java.util.ArrayList;  
  19. import java.util.List;  
  20. public class MainActivity extends AppCompatActivity implements OnItemClickListener {  
  21.     private MyGridView mUserGv, mOtherGv;  
  22.     private List<String>mUserList = new ArrayList<>();  
  23.     private List<String>mOtherList = new ArrayList<>();  
  24.     private OtherAdapter mUserAdapter, mOtherAdapter;  
  25.     @Override  
  26.     protected void onCreate(Bundle savedInstanceState) {  
  27.         super.onCreate(savedInstanceState);  
  28.         setContentView(R.layout.activity_main);  
  29.         initView();  
  30.     }  
  31.     public void initView() {  
  32.         mUserGv = (MyGridView) findViewById(R.id.userGridView);  
  33.         mOtherGv = (MyGridView) findViewById(R.id.otherGridView);  
  34.         mUserList.add("推薦");  
  35.         mUserList.add("熱點");  
  36.         mUserList.add("上海");  
  37.         mUserList.add("時尚");  
  38.         mUserList.add("科技");  
  39.         mUserList.add("體育");  
  40.         mUserList.add("軍事");  
  41.         mUserList.add("財經");  
  42.         mUserList.add("網路");  
  43.         mOtherList.add("汽車");  
  44.         mOtherList.add("房產");  
  45.         mOtherList.add("社會");  
  46.         mOtherList.add("情感");  
  47.         mOtherList.add("女人");  
  48.         mOtherList.add("旅遊");  
  49.         mOtherList.add("健康");  
  50.         mOtherList.add("美女");  
  51.         mOtherList.add("遊戲");  
  52.         mOtherList.add("數碼");  
  53.         mOtherList.add("娛樂");  
  54.         mOtherList.add("探索");  
  55.         mUserAdapter = new OtherAdapter(this, mUserList,true);  
  56.         mOtherAdapter = new OtherAdapter(this, mOtherList,false);  
  57.         mUserGv.setAdapter(mUserAdapter);  
  58.         mOtherGv.setAdapter(mOtherAdapter);  
  59.         mUserGv.setOnItemClickListener(this);  
  60.         mOtherGv.setOnItemClickListener(this);  
  61.     }  
  62.     /**  
  63.      *獲取點選的Item的對應View,  
  64.      *因為點選的Item已經有了自己歸屬的父容器MyGridView,所有我們要是有一個ImageView來代替Item移動  
  65.      * @param view  
  66.      * @return  
  67.      */  
  68.     private ImageView getView(View view) {  
  69.         view.destroyDrawingCache();  
  70.         view.setDrawingCacheEnabled(true);  
  71.         Bitmap cache = Bitmap.createBitmap(view.getDrawingCache());  
  72.         view.setDrawingCacheEnabled(false);  
  73.         ImageView iv = new ImageView(this);  
  74.         iv.setImageBitmap(cache);  
  75.         return iv;  
  76.     }  
  77.     /**  
  78.      * 獲取移動的VIEW,放入對應ViewGroup佈局容器  
  79.      * @param viewGroup  
  80.      * @param view  
  81.      * @param initLocation  
  82.      * @return  
  83.      */  
  84.     private View getMoveView(ViewGroup viewGroup, View view, int[] initLocation) {  
  85.         int x = initLocation[0];  
  86.         int y = initLocation[1];  
  87.         viewGroup.addView(view);  
  88.         LinearLayout.LayoutParams mLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);  
  89.         mLayoutParams.leftMargin = x;  
  90.         mLayoutParams.topMargin = y;  
  91.         view.setLayoutParams(mLayoutParams);  
  92.         return view;  
  93.     }  
  94.     /**  
  95.      * 建立移動的ITEM對應的ViewGroup佈局容器  
  96.      * 用於存放我們移動的View  
  97.      */  
  98.     private ViewGroup getMoveViewGroup() {  
  99.         //window中最頂層的view  
  100.         ViewGroup moveViewGroup = (ViewGroup) getWindow().getDecorView();  
  101.         LinearLayout moveLinearLayout = new LinearLayout(this);  
  102.         moveLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));  
  103.         moveViewGroup.addView(moveLinearLayout);  
  104.         return moveLinearLayout;  
  105.     }  
  106.     /**  
  107.      * 點選ITEM移動動畫  
  108.      *  
  109.      * @param moveView  
  110.      * @param startLocation  
  111.      * @param endLocation  
  112.      * @param moveChannel  
  113.      * @param clickGridView  
  114.      */  
  115.     private void MoveAnim(View moveView, int[] startLocation, int[] endLocation, final String moveChannel,  
  116.                           final GridView clickGridView, final boolean isUser) {  
  117.         int[] initLocation = new int[2];  
  118.         //獲取傳遞過來的VIEW的座標  
  119.         moveView.getLocationInWindow(initLocation);  
  120.         //得到要移動的VIEW,並放入對應的容器中  
  121.         final ViewGroup moveViewGroup = getMoveViewGroup();  
  122.         final View mMoveView = getMoveView(moveViewGroup, moveView, initLocation);  
  123.         //建立移動動畫  
  124.         TranslateAnimation moveAnimation = new TranslateAnimation(  
  125.                 startLocation[0], endLocation[0], startLocation[1],  
  126.                 endLocation[1]);  
  127.         moveAnimation.setDuration(300L);//動畫時間  
  128.         //動畫配置  
  129.         AnimationSet moveAnimationSet = new AnimationSet(true);  
  130.         moveAnimationSet.setFillAfter(false);//動畫效果執行