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

Java 拖动项目时滚动gridview(作为阴影),java,android,drag-and-drop,android-gridview,Java,Android,Drag And Drop,Android Gridview,我正在为api>14进行开发,并在GridView上实现了拖放功能 但是,将项目拖动到屏幕顶部或底部时,GridView不会滚动 我想让它在你拖动一个项目的方向上滚动,当你移动到边缘时越快,当你将项目移回屏幕的垂直中心时越慢 当然,这种功能在任何拖放中都应该是标准的吗 不管怎样,有人知道最好的方法吗 更新: 实际上,我在互联网上找不到一个例子,它甚至试图用一个拖动的网格项滚动(我在这里遗漏了什么吗?),更不用说解决我的问题了 如何让可拖动项(显示为阴影)滚动gridview?我按如下方式分配阻力

我正在为api>14进行开发,并在
GridView
上实现了拖放功能

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

我想让它在你拖动一个项目的方向上滚动,当你移动到边缘时越快,当你将项目移回屏幕的垂直中心时越慢

当然,这种功能在任何拖放中都应该是标准的吗

不管怎样,有人知道最好的方法吗

更新: 实际上,我在互联网上找不到一个例子,它甚至试图用一个拖动的网格项滚动(我在这里遗漏了什么吗?),更不用说解决我的问题了

如何让可拖动项(显示为阴影)滚动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);
    }
}
int-gridChildPosition=position-mGridView.getFirstVisiblePosition();
ViewFlipper gridItem=(ViewFlipper)mGridView.getChildAt(gridChildPosition);
ClipData data=ClipData.newPlainText(“,”);
DragShadowBuilder shadowBuilder=新视图。DragShadowBuilder(gridItem);
if(mGridView.startDrag(数据、shadowBuilder、gridItem、0)){
int lastVisiblePosition=mGridView.getLastVisiblePosition()-mGridView.getFirstVisiblePosition();

对于(int i=0;i我认为您需要使用方法
smoothScrollToPosition(int-position)
smoothScrollByOffset(int-offset)
GridView的
。在屏幕的顶部和底部取两个矩形。如果拖动时在这些矩形上接收到触摸事件,则滚动
GridView
。您可以使用
getLastVisiblePosition()在任何给定时间获取最后可见的位置
方法。

拖动事件的酷之处在于,您也可以在父视图组中侦听它们。扩展
GridView
,并覆盖
onDragEvent
以监视
拖动事件。操作\u拖动位置
。在那里,获取Y坐标(
event.getY()
)请确保从
操作拖动开始时返回true,否则您将不会在
操作拖动位置收到事件

确定您的“点击框”,可能使用的技术,或简单地使用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"
    };
}
导入android.app.Activity;
导入android.content.ClipData;
导入android.content.ClipData.Item;
导入android.content.Context;
导入android.os.Bundle;
导入android.util.Log;
导入android.view.DragEvent;
导入android.view.view;
导入android.widget.AdapterView;
导入android.widget.AdapterView.OnItemLongClickListener;
导入android.widget.ArrayAdapter;
导入android.widget.GridView;
公共类GridDragActivity扩展了活动实现OnItemLongClickListener{
私有静态最终字符串标记=“GridDragActivity”;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
MyGridView gridView=新的MyGridView(此);
gridView.setNumColumns(3);
setOnItemLongClickListener(这个);
setAdapter(新的ArrayAdapter(
这
android.R.layout.simple\u list\u item\u 1,
国家);
setContentView(gridView);
}
@凌驾
公共布尔值长单击(AdapterView父对象、视图、整型位置、,
长id){
ClipData data=ClipData.newPlainText((字符串)视图.getTag(),
字符串.valueOf(position));
View.DragShadowBuilder shadow=新视图.DragShadowBuilder(视图);
view.startDrag(数据,阴影,null,0);
返回true;
}
类MyGridView扩展了GridView{
私有静态最终int阈值=200;
专用静态最终整数偏移=10;
公共MyGridView(上下文){
超级(上下文);
}
@凌驾
公共事件(DrageEvent事件){
int height=getMeasuredHeight();
开关(event.getAction()){
案例DrageEvent.ACTION\u DRAG\u已启动:
返回true;
case DragEvent.ACTION\u拖动位置:
float y=event.getY();
if(高度-y<阈值){
smoothScrollByOffset(偏移量);
}否则如果(高度-y>高度-阈值){
smoothScrollByOffset(-OFFSET);
}
返回true;
案例DrageEvent.ACTION_DROP:
ClipData data=event.getClipData();
Item=data.getItemAt(0);
int start=Integer.valueOf((String)item.getText());
int end=pointToPosition((int)event.getX(),(int)event.getY());
Log.i(标签,“从=“+start+”,在=“+end”)开始放置,在=“+end”结束放置);
返回true;
}
返回super.onDragEvent(事件);
}
}
静态最终字符串[]国家/地区=新字符串[]{
“阿富汗”、“阿尔巴尼亚”、“阿尔及利亚”、“美属萨摩亚”、“安道尔”,
“安哥拉”、“安圭拉”、“南极洲”、“安提瓜和巴布达”、“阿根廷”,
“亚美尼亚”、“阿鲁巴”、“澳大利亚”、“奥地利”、“阿塞拜疆”,
“巴林”、“孟加拉国”、“巴巴多斯”、“白俄罗斯”、“比利时”,
“伯利兹”、“贝宁”、“百慕大”、“不丹”、“玻利维亚”,
“波斯尼亚和黑塞哥维那”,