編輯:關於Android編程
1. 重新GridView控件
package com.whbs.drag.widget;
import com.whbs.drag.DragGridActivity.DragGridAdapter;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ImageView;
public class GragGridView extends GridView{
private static final String TAG = "GragGridView";
//定義基本的成員變量
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 GragGridView(Context context) {
super(context);
}
public GragGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
public GragGridView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
//觸控攔截事件
@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);
}
Log.i(TAG, "[onInterceptTouchEvent] dragSrcPosition:"+dragSrcPosition+",getFirstVisiblePosition():"+getFirstVisiblePosition());
//getFirstVisiblePosition()返回第一個dispaly在界面的view在adapter的位置 可能是0,也可能是4
ViewGroup itemView = (ViewGroup)getChildAt(dragPosition - getFirstVisiblePosition());
//計算按下的坐標相對當前項的位置
dragPointX = x - itemView.getLeft();//在當前項的X位置
dragPointY = y - itemView.getTop();
//當前窗體和屏幕的距離
dragOffsetX = (int) (ev.getRawX()-x);
dragOffsetY = (int) (ev.getRawY() -y);
Log.i(TAG, "[onInterceptTouchEvent] [x:"+x+",y:"+y+"],[rawX:"+ev.getRawX()+",rawY:"+ev.getRawY()+"]");
Log.i(TAG, "[onInterceptTouchEvent] [dragPointX:"+dragPointX+",dragPointY:"+dragPointY+"],[dragOffsetX:"+dragOffsetX+",dragOffsetY:"+dragOffsetY+"]");
//
// upScrollBounce = Math.min(y-scaledTouchSlop, getHeight()/4);
// downScrollBounce = Math.max(y+scaledTouchSlop, getHeight()*3/4);
upScrollBounce = Math.min(y, getHeight()/4);//向上可以滾動的距離
downScrollBounce = Math.max(y, getHeight()*3/4);//向下可以滾動的距離
itemView.setDrawingCacheEnabled(true);
Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());
startDrag(bm,x,y);
}
return super.onInterceptTouchEvent(ev);
}
//開始拖動
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;//計算當前項Left離窗體的距離
windowParams.y = y - dragPointY + dragOffsetY;//計算當前項Top離窗體的距離
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(getContext().WINDOW_SERVICE);
windowManager.addView(imageView, windowParams);
dragImageView = imageView;
}
//停止拖到
public void stopDrag(){
if(dragImageView != null){
windowManager.removeView(dragImageView);
dragImageView = null;
}
}
//拖動
public void onDrag(int x,int y){
if(dragImageView != null){
windowParams.alpha = 0.9f;
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(dragPosition);
}
}
@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;
}
return true;
}
return super.onTouchEvent(ev);
}
//拖到落下
public void onDrop(int x,int y){
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 dragSrcItem = adapter.getItem(dragSrcPosition);
String dragTargetItem = adapter.getItem(dragPosition);
adapter.remove(dragSrcItem);
adapter.insert(dragSrcItem, dragPosition);
adapter.remove(dragTargetItem);
adapter.insert(dragTargetItem, dragSrcPosition);
System.out.println("srcPosition="+dragSrcPosition+" dragPosition="+dragPosition);
//Toast.makeText(getContext(), adapter.getList().toString(), Toast.LENGTH_SHORT).show();
}
}
}
有些在使用越獄工具的朋友反映,使用過程中會提示“沒有找到蘋果設備”,由於這個錯誤提醒導致越獄不能繼續進行。當遇到這種情況我們應該怎麼
綜述 View的繪制流程可以分為三大步,它們分別是measure,layout和draw過程。measure表示View的測量過程,用於測量View的寬度和高度;lay
Android Studio導入Eclipse項目有兩種方法,一種是直接把Eclipse項目導入Android Studio,另一種是在Eclipse項目裡面進行轉換,然
在之前四講中,我們已經由淺入深的認識了適配器,從最簡單的ListView寫起,最後完成了自定義適配器的簡單例子,這一次咱們就上次留下來的問題 再進行更加深入的學習,主要是