廣州暨華電腦學校
咨詢熱線:020-85566216

誠        毅        精      勤

當前位置:所在位置: 廣州電腦培訓 >> 電腦技術 >> android >> 正文

基于Android圖標拖動布局的實現

發布時間:2018/2/26 14:59:09 內容來源::廣州暨華電腦學校 點擊:

  界面需求:

  界面整齊的排列各個圖標,長按其中一個,可拖動選中的圖標。拖動到想要的位置之后,界面可將圖標再次排列整齊。類似一般android手機桌面布局。

  控件介紹:

  Android為我們提供了GridView 網格視圖。GridView 可在控件內添加view子控件,實現view的整齊排列,但是GridView并沒有給我們提供拖拽view的功能,因此需要重新編寫GridView來實現需要的功能。

  public class DragGrid extends GridView{}

  如上述代碼,重新定義一個DragGrid控件,繼承于GridView。

  Android事件處理:

  事件是我們在與UI交互式發生的,我們點擊一個按鍵時,可能就已經出發好幾個事件,例如我們點擊數字鍵“0”,他會涉及到按下事件,和一個彈起(松開)事件,在我們android中還可能涉及到觸摸屏事件,所以在android系統中,事件是作為常用的功能之一。而這里我用到的主要有兩個:

  1 長按LongClick;

  2 觸碰事件TouchEvent;

  適配器Adapter:

  適配器(Adapter)是一種界面對象,他用于列表組件和數據來源之間的橋梁。在這里我們用于GridView的數據填充,以及拖動后的布局改變。Android本身提供給我們的配置器不滿足我們的需求因此也需要重寫一個新的Adapter;

  public class DateAdapter extends BaseAdapter {}

  主要思路:

  觸發GridView的子控件的長按監聽,需要重寫GridView的LongClick的監聽。之后進入圖標拖拽功能,此功能需要重寫觸碰事件TouchEvent。但是僅僅如此,會帶來一個問題,在沒有長按的時候也會觸發觸碰事件TouchEvent。因此我們需要一個機制來判斷LongClick和TouchEvent的先后順序,在LongClick觸發之后才執行TouchEvent。好在android為我們提供了另一個事件——onInterceptTouchEvent。onInterceptTouchEvent是用于攔截手勢事件的,每個手勢事件都會先調用onInterceptTouchEvent。重寫GridView的onInterceptTouchEvent使得在手指觸碰屏幕的時候調用LongClick而不是TouchEvent,就可以避免兩者之間的矛盾。之后使用Adapter對GridView的內容進行填充,即可完成布局。

  具體實現與代碼:

  具體實現還需要還需要具體的頁面布局。布局文件分為兩個,一個是主界面,之間調用重寫的GridView即可。另一個是GridView的item,我們可以用一個ImageView來顯示圖標,下面用一個TextView來注釋名稱。

  而將item填充到GridView里就是Adapter的工作了。

  獲取item:

  public View getView(int position, View convertView, ViewGroup parent) {

  convertView = LayoutInflater.from(context).inflate(R.layout.item, null);

  txtAge = (TextView) convertView.findViewById(R.id.txt_userAge);

  txtAge.setText(lstDate.get(position));

  return convertView;

  }

  }

  將item填充到GridView中:

  final DateAdapter adapter = new DateAdapter(MainActivity.this, l1);

  gridView.setAdapter(adapter);

  重寫onInterceptTouchEvent:

  public boolean onInterceptTouchEvent(MotionEvent ev) {

  if (ev.getAction() == MotionEvent.ACTION_DOWN) {

  return setOnItemLongClickListener(ev);

  }

  return super.onInterceptTouchEvent(ev);

  }

  ACTION_DOWN代表手指放下,此時返回setOnItemLongClickListener(ev)即可先執行長按監聽。

  重寫TouchEvent:

  public boolean onTouchEvent(MotionEvent ev) {

  if (dragImageView != null

  && dragPosition != AdapterView.INVALID_POSITION) {

  int x = (int) ev.getX();

  int y = (int) ev.getY();

  switch (ev.getAction()) {

  case MotionEvent.ACTION_MOVE:

  if(!isCountXY) {

  xtox = x-mLastX;

  ytoy = y-mLastY;

  isCountXY= true;

  }

  onDrag(x, y);

  if(!isMoving )

  OnMove(x,y);

  break;

  case MotionEvent.ACTION_UP:

  stopDrag();

  onDrop(x, y);

  break;

  }

  }

  return super.onTouchEvent(ev);

  }

  重寫LongClick事件:

  public boolean setOnItemLongClickListener(final MotionEvent ev) {

  this.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

  @Override

  public boolean onItemLongClick(AdapterView arg0, View arg1,

  int arg2, long arg3) {

  int x = (int) ev.getX();

  int y = (int) ev.getY();

  Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache(true));

  Bitmap bitmap = Bitmap.createBitmap(bm, 8, 8, bm.getWidth()-8, bm.getHeight()-8);

  startDrag(bitmap, x, y);

  hideDropItem();

  itemView.setVisibility(View.INVISIBLE);

  isMoving = false;

  return false;

  };

  });

  return super.onInterceptTouchEvent(ev);

  }

  由于相關代碼過于復雜,在此只做簡單思路描述:x,y分別代表拖動item的初始坐標。ACTION_MOVE代表手指在屏幕上滑動。長按事件執行時,獲取長按item的位置,和截圖,隱藏原先Item。事實上用戶拖動的是item的截圖,item本身是無法拖動的,但這不影響用戶體驗。之后執行onTouchEvent,當“item”移動到新的位置是,使用動畫效果使原先在此位置的item被擠到空位,當然這里的item移動也是一個障眼法。而當手指松開的時候再利用Adapter重新排列item位置。解除原先item的隱藏。至此,android圖標拖動布局的實現。

  • 上一篇電腦技術:
  • 下一篇電腦技術:
  • 學校簡介 |專業課程 | 學生就業 | 參觀學校

    學校地址:廣州天河區五山路金華園區C座3樓307(華南理工大學南門旁)

    學校名稱:廣州暨華電腦培訓學校 聯系電話:020-85566215

    2002-2019 廣州青大教育信息咨詢有限公司 版權所有 備案/許可證編號為:粵ICP備11083420號-11

    今天30选5开奖公告