如何创建一个自定义的拖影? [英] How to create a custom drag shadow?

查看:140
本文介绍了如何创建一个自定义的拖影?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要达到什么样的:

我想创建一个拖放在Android的拖放功能。我想使用一个特定的布局,一拖影(从拖动对象本身不同)。

I want to create a drag and drop functionality in Android. I'd like to use a specific layout (different from the dragged object itself) as a drag shadow.

什么导致我收到代替:

无论是我的方法按预期工作 - 我最终没有明显的拖影都(虽然目标确实接收到滴)

Neither of my approaches works as expected - I end up with no visible drag shadow at all (although the target does receive the drop).

我的尝试:

我试过

  • 充气 drag_item 布局中的活动,然后将它作为参数传递给阴影生成器的构造
  • inflating the drag_item layout in the activity, then passing it as an argument to the shadow builder's constructor

  • 膨胀的影子建筑工地 onDrawShadow 方法 drag_item 布局,然后在画布
  • inflating the drag_item layout in the shadow builder's onDrawShadow method, then drawing it on the canvas

布局:

我的活动布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:id="@+id/container"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              tools:context="com.example.app.DragDropTestActivity"
              tools:ignore="MergeRootFrame">
    <TextView
        android:id="@+id/tvReceiver"
        android:text="Drop here"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <Button
        android:id="@+id/btnDragged"
        android:layout_height="wrap_content"
        android:text="Drag me"
        android:layout_width="match_parent"/>
</LinearLayout>

我要为一拖影使用的布局:

The layout I want to use as a drag shadow:

dragged_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Dragged Item"/>
</LinearLayout>

来源$ C ​​$ C:

这里的code有两种方法(重presented由 1 BuilderOne 2 BuilderTwo ,分别):

Here's the code with both approaches (represented by 1, BuilderOne and 2, BuilderTwo, respectively):

package com.example.app;

import android.graphics.Canvas;
import android.graphics.Point;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;

public class DragDropTestActivity extends ActionBarActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_drag_drop_test);
        Button dragged = (Button) findViewById(R.id.btnDragged);

        dragged.setOnTouchListener(
            new View.OnTouchListener()
            {
                @Override
                public boolean onTouch(View v, MotionEvent event)
                {
                    if (event.getAction() != MotionEvent.ACTION_DOWN) {
                        return false;
                    }
                    LayoutInflater inflater = getLayoutInflater();

                    int approach = 1;    
                    // both approaches fail
                    switch (approach) {
                        case 1: {
                            View draggedItem = inflater.inflate(R.layout.dragged_item, null);
                            BuilderOne builder = new BuilderOne(draggedItem);
                            v.startDrag(null, builder, null, 0);
                            break;
                        }
                        case 2: {
                            BuilderTwo builder = new BuilderTwo(inflater, v);
                            v.startDrag(null, builder, null, 0);
                            break;
                        }
                    }

                    return true;
                }
            });
    }

我的 BuilderOne 类:

    public static class BuilderOne extends View.DragShadowBuilder
    {
        public BuilderOne(View view)
        {
            super(view);
        }

        @Override
        public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint)
        {
            super.onProvideShadowMetrics(
                shadowSize,
                shadowTouchPoint);
        }
    }

BuilderTwo 类:

    public static class BuilderTwo extends View.DragShadowBuilder
    {
        final LayoutInflater inflater;

        public BuilderTwo(LayoutInflater inflater, View view)
        {
            super(view);
            this.inflater = inflater;
        }

        @Override
        public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint)
        {
            super.onProvideShadowMetrics(
                shadowSize,
                shadowTouchPoint);
        }

        @Override
        public void onDrawShadow(Canvas canvas)
        {
            final View draggedItem = inflater.inflate(R.layout.dragged_item, null);
            if (draggedItem != null) {
                draggedItem.draw(canvas);
            }
        }
    }
}

问:

我该怎么办错了?

更新:

赏金补充说。

推荐答案

Kurty是正确的,你不应该需要继承 DragShadowBuilder 在这种情况下。我的想法是,你传递给视图中的 DragShadowBuilder 实际上并不存在的布局,因此它不会呈现。

Kurty is correct in that you shouldn't need to subclass DragShadowBuilder in this case. My thought is that the view you're passing to the DragShadowBuilder doesn't actually exist in the layout, and therefore it doesn't render.

而不是传递作为第二个参数 inflater.inflate ,尝试实际添加的膨胀查看的层次结构的某个地方,然后将它传递到正规 DragShadowBuilder

Rather than passing null as the second argument to inflater.inflate, try actually adding the inflated View to the hierarchy somewhere, and then passing it to a regular DragShadowBuilder:

View dragView = findViewById(R.id.dragged_item);
mDragShadowBuilder = new DragShadowBuilder(dragView);
v.startDrag(null, mDragShadowBuilder, null, 0);

修改

我知道,具有 dragged_item 视图渲染所有的时间是不是你想要的,但如果它的工作原理那么至少我们知道问题出在哪里并能寻找一个解决方案,那不是!

I'm aware that having the dragged_item view being rendered all the time isn't what you want, but if it works then at least we know where the problem is and can look for a solution to that instead!

这篇关于如何创建一个自定义的拖影?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆