【问题标题】:custom drag and drop自定义拖放
【发布时间】:2016-01-27 22:52:56
【问题描述】:

我是一个初学者 android 开发者,我正在尝试构建一个小型的土壤游戏。 为了拖动卡片,我从这里的一个问题中实现了一个自定义视图组,它是一个“DragContainer”。 我的问题是当我拖动线性布局时。我的线性布局拿着卡片 带有 - 边距(与卡片重叠)但是当我开始拖动时,拖动的“阴影”是我没有边距的布局。 这是一个例子

this is the start of the activity, the left is a linear layout with two children and also the right

当我开始拖动时,这就是我所看到的

as you can see the dragged "shadow" is bigger(without the - margin)

这是自定义拖动容器的代码(仅重要的东西):

    public boolean startDragChild(View child, ClipData data,
        Object myLocalState, int flags) {
    setDragTarget(child);
    return child.startDrag(data, new EmptyDragShadowBuilder(child),
            myLocalState, flags);
}

private void setDragTarget(View v) {
    target = v;
    onSetDragTarget(v);
}

/**
 * this is similar to the constructor of DragShadowBuilder
 * 
 * @param v
 */
protected void onSetDragTarget(View v) {

}
    @Override
protected void dispatchDraw(Canvas canvas) {

    super.dispatchDraw(canvas);
    if (mOnDrag && target != null) {
        canvas.save();
        drawDragShadow(canvas);
        canvas.restore();
    }
}

protected void drawDragShadow(Canvas canvas) {
    int h = target.getHeight();
    int w = target.getWidth();
    canvas.translate(mDragX - w / 2, mDragY - h / 2);
    target.draw(canvas);
}

【问题讨论】:

  • 如果您想回答ViewGroup 变体,请解释更多细节。我已阅读但无法理解您的问题。
  • 我看过这个例子,我明白了,但这对我没有帮助,因为它只用于拖动一个图像视图,而不是我需要的线性布局(我尝试使用 android“拖放" API 并且无法使其工作,我看不到为线性布局创建的阴影。这是我的另一个问题的链接 (stackoverflow.com/questions/35015676/…) @PankajNimgade。
  • 和@ghostman 我的问题是拖动的Linearlayout 的阴影不考虑其上设置的边距。 ViewGroup 变体只是为了展示我是如何实现拖放的。

标签: android drag-and-drop android-linearlayout


【解决方案1】:

我想 akon 不需要解释,但我想告诉听众这个问题。 LinearLayout 中的 margins 应该是完整的,因为你会移动 ViewGroup 本身,所以它的孩子不会对它的设计有任何问题, 代码也可在Github

public class DragTestTwoActivity extends AppCompatActivity {

    private LinearLayout source_linearLayout;
    private LinearLayout destination_linearLayout;
    private static final String TAG = "DragTestTwoActivity";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_drag_test_two);

        initializeUI();
    }

    private void initializeUI() {

        source_linearLayout = (LinearLayout) findViewById(R.id.DragTestTwoActivity_Source_LinearLayout);
        destination_linearLayout = (LinearLayout) findViewById(R.id.DragTestActivityActivity_Destination_LinearLayout);

//        source_linearLayout.setOnDragListener(new MyDragListener());
        destination_linearLayout.setOnDragListener(new MyDragListener());

        source_linearLayout.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                ClipData data = ClipData.newPlainText("", "");
                View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(source_linearLayout);
                source_linearLayout.startDrag(data, shadowBuilder, source_linearLayout, 0);
                return true;
            }
        });
    }

    private class MyDragListener implements View.OnDragListener {


        @Override
        public boolean onDrag(View v, DragEvent event) {

            switch (event.getAction()) {

                case DragEvent.ACTION_DRAG_STARTED:
                    Log.d(TAG, "Drag has started");
                    break;
                case DragEvent.ACTION_DRAG_ENDED:
                    Log.d(TAG, "Drag has ended");
                    v.setVisibility(View.VISIBLE);
                    break;
                case DragEvent.ACTION_DRAG_ENTERED:
                    Log.d(TAG, "Drag has entered");
                    break;
                case DragEvent.ACTION_DRAG_LOCATION:
                    Log.d(TAG, "Drag location");
                    break;
                case DragEvent.ACTION_DROP:
                    Log.d(TAG, "Drag has dropped");
                    View source_linear_Layout = (LinearLayout) event.getLocalState();
                    LinearLayout view = (LinearLayout) source_linear_Layout.getParent();
                    view.removeView(source_linear_Layout); // This will remove the imageView where it was

                    LinearLayout linearLayout = (LinearLayout) v;
                    if (v.getId() == R.id.DragTestActivityActivity_Source_LinearLayout) {
                        Log.d(TAG, "This is a source location");

                    } else if (v.getId() == R.id.DragTestActivityActivity_Destination_LinearLayout) {
                        Log.d(TAG, "This is a destination");

                    }
                    linearLayout.addView(source_linear_Layout); // this will add the ImageView to the new location where it was dropped.
                    source_linear_Layout.setVisibility(View.VISIBLE);


                    break;
                case DragEvent.ACTION_DRAG_EXITED:
                    Log.d(TAG, "Drag has exited");
                    break;
            }

            return true;
        }


    }
}

activity_drag_test_two.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="activities.list.first.DragTestTwoActivity">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:padding="4sp">


        <LinearLayout

            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_margin="4dp"
            android:layout_weight="0.5"
            android:background="#ABABAB"
            android:orientation="vertical"
            android:padding="4dp">

            <LinearLayout
                android:id="@+id/DragTestTwoActivity_Source_LinearLayout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <ImageView
                    android:id="@+id/DragTestTwoActivity_imageView"
                    android:layout_width="wrap_content"
                    android:layout_height="100dp"
                    android:layout_margin="4dp"
                    android:scaleType="centerInside"
                    android:src="@drawable/gohan" />

                <ImageView
                    android:id="@+id/DragTestTwoActivity_imageView2"
                    android:layout_width="wrap_content"
                    android:layout_height="100dp"
                    android:layout_margin="4dp"
                    android:scaleType="centerInside"
                    android:src="@drawable/goku" />
            </LinearLayout>


        </LinearLayout>

        <LinearLayout
            android:id="@+id/DragTestActivityActivity_Destination_LinearLayout"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_margin="4dp"
            android:layout_weight="0.5"
            android:background="#CACACB"
            android:orientation="vertical"
            android:padding="4dp">

        </LinearLayout>


    </LinearLayout>

</LinearLayout>

输出 这就是它的样子......

【讨论】:

  • 首先感谢您的帮助。但我还是有问题。当源线性布局和目标写在 xml 中时,此代码就像魅力一样,但出于我的目的,它并不好,因为我尝试在 java 中创建一个新的线性布局(仅当我开始拖动时)并且它应该只包含视图我暂时需要(为本示例选择的卡片)。当我在从 android 实现“拖放”API 时尝试执行此操作时,创建的阴影不显示(拖动有效,但我看不到阴影)这里是我的一个已经打开的问题的链接
【解决方案2】:

当然,您可以为此目的使用标准视图,但这是不合理的。最好使用SurfaceView(或者如果你知道OpenGL GLSurfaceView)。

【讨论】:

  • 为什么不合理?据我了解,SurfaceView 是用于在另一个线程上绘图,这样主 GUI 不会受到影响……我不明白你在说什么,你能详细说明一下吗?
  • 阅读时在屏幕上绘制视图,然后进行计算大小、背景等操作。
  • 游戏也很难用。自定义实现通常具有更快的速度
  • 它是为 GUI 开发的,而不是用于其他目的。对不起我的英语。
猜你喜欢
  • 2015-03-08
  • 2019-06-10
  • 1970-01-01
  • 2019-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多