拖动gridview时拖动项目(作为阴影)

我正在开发的API> 14,我已经实现了在GridView拖放function。

但是,在将项目拖到屏幕的顶部或底部时, GridView不会滚动。

我希望将它拖动的方向拖动一个项目越来越快,当你移动到边缘和缓慢移动项目回到屏幕的垂直中心。

当然,这种function在任何拖放中都应该是标准的。

无论如何,有没有人知道解决这个问题的最好方法?

更新 :我实际上找不到在互联网上的一个例子,甚至试图用一个拖动的网格项目滚动(我在这里丢失的东西?),更不用说解决我的问题。

你如何得到可拖动的项目(显示为阴影)来滚动gridview? 我正在分配拖动如下:

 int gridChildPosition = position - mGridView.getFirstVisiblePosition(); ViewFlipper gridItem = (ViewFlipper) mGridView.getChildAt(gridChildPosition); ClipData data = ClipData.newPlainText("", ""); DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(gridItem); if (mGridView.startDrag(data, shadowBuilder, gridItem, 0)) { int lastVisiblePosition = mGridView.getLastVisiblePosition() - mGridView.getFirstVisiblePosition(); for (int i=0; i<=lastVisiblePosition; i++) { if (i == gridChildPosition) { continue; } mGridView.getChildAt(i).setOnDragListener(new GridItemDragListener(position)); mGridView.getChildAt(i).setAlpha(0.4f); } } 

上面的代码创build可拖动的阴影,所有其他项目变暗。 但我不确定如何让阴影滚动gridview。

Solutions Collecting From Web of "拖动gridview时拖动项目(作为阴影)"

关于拖动事件很酷的事情是,你也可以在父ViewGroup监听它们。 扩展GridView ,并重写onDragEvent来监视DragEvent.ACTION_DRAG_LOCATION 。 在那里,获取拖动的Y坐标( event.getY() )。 确保从ACTION_DRAG_STARTED返回true,否则ACTION_DRAG_STARTED中将不会收到该事件。

确定你的“点击框”,也许使用jaibatrikbuild议的技术,或者只是使用一定比例的GridView的测量高度。

这可能是最有意义的使用smoothScrollByOffset(int offset) ,这样你可以实现阶梯/指数滚动。 意思是,用户在拖动的项目中保留的时间越长,偏移量就越大。

听起来像是一个开源的库/组件的一个很酷的想法。 😉

编辑:

这里有一个如何做到这一点的例子:

 import android.app.Activity; import android.content.ClipData; import android.content.ClipData.Item; import android.content.Context; import android.os.Bundle; import android.util.Log; import android.view.DragEvent; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemLongClickListener; import android.widget.ArrayAdapter; import android.widget.GridView; public class GridDragActivity extends Activity implements OnItemLongClickListener { private static final String TAG = "GridDragActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyGridView gridView = new MyGridView(this); gridView.setNumColumns(3); gridView.setOnItemLongClickListener(this); gridView.setAdapter(new ArrayAdapter<String>( this, android.R.layout.simple_list_item_1, COUNTRIES)); setContentView(gridView); } @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { ClipData data = ClipData.newPlainText((String) view.getTag(), String.valueOf(position)); View.DragShadowBuilder shadow = new View.DragShadowBuilder(view); view.startDrag(data, shadow, null, 0); return true; } class MyGridView extends GridView { private static final int THRESHHOLD = 200; private static final int OFFSET = 10; public MyGridView(Context context) { super(context); } @Override public boolean onDragEvent(DragEvent event) { int height = getMeasuredHeight(); switch (event.getAction()) { case DragEvent.ACTION_DRAG_STARTED: return true; case DragEvent.ACTION_DRAG_LOCATION: float y = event.getY(); if (height - y < THRESHHOLD) { smoothScrollByOffset(OFFSET); } else if (height - y > height - THRESHHOLD) { smoothScrollByOffset(-OFFSET); } return true; case DragEvent.ACTION_DROP: ClipData data = event.getClipData(); Item item = data.getItemAt(0); int start = Integer.valueOf((String) item.getText()); int end = pointToPosition((int) event.getX(), (int) event.getY()); Log.i(TAG, "DROP started at = " + start + ", ended at = " + end); return true; } return super.onDragEvent(event); } } static final String[] COUNTRIES = new String[] { "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra", "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory", "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burundi", "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde", "Cayman Islands", "Central African Republic", "Chad", "Chile", "China", "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo", "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic", "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland", "Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia", "French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau", "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary" }; } 

我想你需要使用smoothScrollToPosition(int position)smoothScrollByOffset(int offset)方法。 在屏幕的顶部和底部取两个矩形。 如果触摸事件在拖动时在矩形框上收到,则滚动GridView 。 您可以使用getLastVisiblePosition()方法在任何给定的时间获取最后的可见位置。