編輯: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
這篇文章也算是前面文章的一個補充和擴展。
Android下保存簡單網頁到本地(包括簡單圖片鏈接轉換)實現代碼
最近在做一個項目涉及到將包含圖片的簡單網頁下載到本地,方便離線時觀看,在這裡分享一下,大家做下簡單修改就可以用到自己的項目中了。(這裡用到了AQuery庫) 代
Android APK文件在電腦(PC虛擬機)上面運行方法
APK是Android系統的發布的工程包,很多時候我們想在電腦上而非Android手機上面運行它。下面就提供下Android APK文件在電腦上面運行方法。 首先
Android中的廣播(BroadCast)詳細介紹
什麼是廣播 在Android中,Broadcast是一種廣泛運用的在應用程序之間傳輸信息的機制。我們拿廣播電台來做個比方。我們平常使用收音機收音是這樣的:許許多多
Android MediaPlayer(多媒體播放)
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內置的媒體播放