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

标签 java android drag-and-drop android-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);
    }
}

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

最佳答案

Drag Events 最酷的一点是你可以在父 ViewGroup 中监听它们。扩展 GridView,并覆盖 onDragEvent 以监控 DragEvent.ACTION_DRAG_LOCATION。在那里,获取拖动的 Y 坐标 (event.getY())。确保从 ACTION_DRAG_STARTED 返回 true,否则您将不会在 ACTION_DRAG_LOCATION 中收到事件。

确定您的“命中框”,也许使用 jaibatrik suggests 的技术,或者简单地使用 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"
    };
}

关于java - 拖动项目时滚动 gridview(作为阴影),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16154642/

相关文章:

javascript - 在 Chrome 和 Edge 之间拖放 HTML

java - Android 在一切之上叠加一个 View ?

android - 无法解析com.firebase.firebaseui:firebase-ui-auth:4.3.1

android - 在安卓模拟器上运行google play store

java - 无法使用主机名连接到 Android 服务器

html - 以编程方式创建拖动事件时,dataTransfer 为空

javascript - 调整窗口大小时,可拖动对象会移出容器

java - 如何通过 Eclipse 快捷方式 (ctrl + alt + R) 仅显示 (src) 文件而不显示 (target) 文件?

java - 根据纬度和经度将位置映射到最近的位置

java - Android - 如何以编程方式在 LinearLayout 中添加多个具有不同布局边距的按钮?