編輯:Android開發實例
根據前面文章中ListView拖拽的實現原理,我們也是很容易實現推拽GridView的,下面我就以相同步驟實現基本的GridView拖拽效果。
因為GridView不用做分組處理,代碼處理起來更簡潔,而且原理前面已經講解清楚了,代碼中只是簡單的過下,必要的地方簡單的注釋一下。
1.主界面DragGridActivity.
public class DragGridActivity extends Activity { private static List<String> list = null; //自定義適配器 private DragGridAdapter adapter = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.drag_grid_activity); initData(); //後面用到的自定義GridView DragGridView dragGridView = (DragGridView)findViewById(R.id.drag_grid); adapter = new DragGridAdapter(this, list); dragGridView.setAdapter(adapter); } public void initData(){ //數據結果 list = new ArrayList<String>(); for(int i=0; i<12; i++){ list.add("grid_"+i%12); } } }
2.主界面UI布局drag_grid_activity.xml.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff" android:padding="10dip" > <com.fengjian.test.DragGridView android:id="@+id/drag_grid" android:layout_width="fill_parent" android:layout_height="wrap_content" android:cacheColorHint="#00000000" android:numColumns="3" android:stretchMode="columnWidth" android:verticalSpacing="5dip" android:horizontalSpacing="20dip" android:background="#ffffff"/> </LinearLayout>
3.列表項布局drag_grid_item.xml.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="5dip" android:paddingRight="5dip"> <ImageView android:id="@+id/drag_grid_item_image" android:src="@drawable/grid_icon" android:layout_margin="5dip" android:layout_alignParentTop="true" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <ImageView android:id="@+id/drag_grid_item_drag" android:src="@drawable/grid_drag" android:layout_alignParentTop="true" android:layout_alignParentRight="true" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </RelativeLayout>
4.自定義適配器DragGridAdapter,繼承ArrayAdapter<String>.
public static class DragGridAdapter extends ArrayAdapter<String>{ public DragGridAdapter(Context context, List<String> objects) { super(context, 0, objects); } public List<String> getList(){ return list; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; if(view==null){ view = LayoutInflater.from(getContext()).inflate(R.layout.drag_grid_item, null); } try { //根據文件名獲取資源文件夾中的圖片資源 Field f= (Field)R.drawable.class.getDeclaredField(getItem(position)); int i=f.getInt(R.drawable.class); ImageView imageview= (ImageView)view.findViewById(R.id.drag_grid_item_image); imageview.setImageResource(i); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return view; } }
5.自定義視圖類DragGridView,繼承GridView.
public class DragGridView extends GridView { //定義基本的成員變量 private ImageView dragImageView; private int dragSrcPosition; private int dragPosition; //x,y坐標的計算 private int dragPointX; private int dragPointY; private int dragOffsetX; private int dragOffsetY; private WindowManager windowManager; private WindowManager.LayoutParams windowParams; private int scaledTouchSlop; private int upScrollBounce; private int downScrollBounce; public DragGridView(Context context, AttributeSet attrs) { super(context, attrs); } }
6. 重寫觸控攔截事件方法onInterceptTouchEvent().
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { if(ev.getAction()==MotionEvent.ACTION_DOWN){ int x = (int)ev.getX(); int y = (int)ev.getY(); dragSrcPosition = dragPosition = pointToPosition(x, y); if(dragPosition==AdapterView.INVALID_POSITION){ return super.onInterceptTouchEvent(ev); } ViewGroup itemView = (ViewGroup) getChildAt(dragPosition-getFirstVisiblePosition()); dragPointX = x - itemView.getLeft(); dragPointY = y - itemView.getTop(); dragOffsetX = (int) (ev.getRawX() - x); dragOffsetY = (int) (ev.getRawY() - y); View dragger = itemView.findViewById(R.id.drag_grid_item_drag); //如果選中拖動圖標 if(dragger!=null&&dragPointX>dragger.getLeft()&&dragPointX<dragger.getRight()&&dragPointY>dragger.getTop()&&dragPointY<dragger.getBottom()+20){ upScrollBounce = Math.min(y-scaledTouchSlop, getHeight()/4); downScrollBounce = Math.max(y+scaledTouchSlop, getHeight()*3/4); itemView.setDrawingCacheEnabled(true); Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache()); startDrag(bm, x, y); } return false; } return super.onInterceptTouchEvent(ev); }startDrag和stopDrag方法如下:
public void startDrag(Bitmap bm, int x, int y){ stopDrag(); windowParams = new WindowManager.LayoutParams(); windowParams.gravity = Gravity.TOP|Gravity.LEFT; windowParams.x = x - dragPointX + dragOffsetX; windowParams.y = y - dragPointY + dragOffsetY; windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT; windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT; windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; windowParams.format = PixelFormat.TRANSLUCENT; windowParams.windowAnimations = 0; ImageView imageView = new ImageView(getContext()); imageView.setImageBitmap(bm); windowManager = (WindowManager)getContext().getSystemService("window"); windowManager.addView(imageView, windowParams); dragImageView = imageView; } public void onDrag(int x, int y){ if(dragImageView!=null){ windowParams.alpha = 0.8f; windowParams.x = x - dragPointX + dragOffsetX; windowParams.y = y - dragPointY + dragOffsetY; windowManager.updateViewLayout(dragImageView, windowParams); } int tempPosition = pointToPosition(x, y); if(tempPosition!=INVALID_POSITION){ dragPosition = tempPosition; } //滾動 if(y<upScrollBounce||y>downScrollBounce){ //使用setSelection來實現滾動 setSelection(dragPosition); } }
7.重寫onTouchEvent()方法.
@Override public boolean onTouchEvent(MotionEvent ev) { if(dragImageView!=null&&dragPosition!=INVALID_POSITION){ int action = ev.getAction(); switch(action){ case MotionEvent.ACTION_UP: int upX = (int)ev.getX(); int upY = (int)ev.getY(); stopDrag(); onDrop(upX,upY); break; case MotionEvent.ACTION_MOVE: int moveX = (int)ev.getX(); int moveY = (int)ev.getY(); onDrag(moveX,moveY); break; default:break; } return true; } return super.onTouchEvent(ev); }
其中onDrag方法如下:
public void onDrag(int x, int y){ if(dragImageView!=null){ windowParams.alpha = 0.8f; windowParams.x = x - dragPointX + dragOffsetX; windowParams.y = y - dragPointY + dragOffsetY; windowManager.updateViewLayout(dragImageView, windowParams); } int tempPosition = pointToPosition(x, y); if(tempPosition!=INVALID_POSITION){ dragPosition = tempPosition; } //滾動 if(y<upScrollBounce||y>downScrollBounce){ //使用setSelection來實現滾動 setSelection(dragPosition); } }
8.放下影像,數據更新。
在onDrop方法中實現:
public void onDrop(int x, int y){ //為了避免滑動到分割線的時候,返回-1的問題 int tempPosition = pointToPosition(x, y); if(tempPosition!=INVALID_POSITION){ dragPosition = tempPosition; } //超出邊界處理 if(y<getChildAt(0).getTop()){ //超出上邊界 dragPosition = 0; }else if(y>getChildAt(getChildCount()-1).getBottom()||(y>getChildAt(getChildCount()-1).getTop()&&x>getChildAt(getChildCount()-1).getRight())){ //超出下邊界 dragPosition = getAdapter().getCount()-1; } //數據交換 if(dragPosition!=dragSrcPosition&&dragPosition>-1&&dragPosition<getAdapter().getCount()){ DragGridAdapter adapter = (DragGridAdapter)getAdapter(); String dragItem = adapter.getItem(dragSrcPosition); adapter.remove(dragItem); adapter.insert(dragItem, dragPosition); Toast.makeText(getContext(), adapter.getList().toString(), Toast.LENGTH_SHORT).show(); } }
10.最終效果圖如下:
圖1
圖2
這篇文章也算是前面文章的一個補充和擴展。
最近在做一個項目涉及到將包含圖片的簡單網頁下載到本地,方便離線時觀看,在這裡分享一下,大家做下簡單修改就可以用到自己的項目中了。(這裡用到了AQuery庫) 代
APK是Android系統的發布的工程包,很多時候我們想在電腦上而非Android手機上面運行它。下面就提供下Android APK文件在電腦上面運行方法。 首先
什麼是廣播 在Android中,Broadcast是一種廣泛運用的在應用程序之間傳輸信息的機制。我們拿廣播電台來做個比方。我們平常使用收音機收音是這樣的:許許多多
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內置的媒體播放