简体   繁体   English

我如何在Android中创建自定义容器视图?

[英]How would I go about creating a custom container view in Android?

I would like to create a view with a listener that acts sort of like a container or grocery bag. 我想创建一个带有监听器的视图,它有点像容器或杂货袋。 Any image or text that is dragged into it, gets collected and saved into a local database. 拖入其中的任何图像或文本都会被收集并保存到本地数据库中。 Or rather the image name or string gets saved. 或者更确切地说,图像名称或字符串被保存。 I've created custom views before that displayed a custom row of data but I'm not sure how to create a "grocery bag" type of view. 我之前创建了自定义视图,显示了一个自定义的数据行,但我不知道如何创建一个“杂货袋”类型的视图。 I've searched Google for creating a custom container view with listener but couldn't find anything related to what I am looking for. 我搜索过谷歌创建一个带有监听器的自定义容器视图但找不到与我要查找的内容有关的任何内容。 I'm not asking anyone to do it for me, just give me some advice or push in the right direction. 我不是要求任何人为我做这件事,只是给我一些建议或推进正确的方向。

Edit Just to clarify a little more. 编辑只是为了澄清一点。 I already know how to drag and drop a view. 我已经知道如何拖放视图了。 The problem with that is that you can drop anywhere. 问题在于你可以放在任何地方。 What I want is a view that when something is dropped within its bounds, it gets the views' string or tag. 我想要的是一个视图,当某个东西在其边界内被删除时,它会获得视图的字符串或标记。 Regardless of what kind of view that may be. 无论可能是什么样的观点。 Somehow this custom view has to know what kind of view was dropped within its bounds and remove that view on drop. 不知何故,这个自定义视图必须知道在其边界内删除了哪种视图,并在drop上删除该视图。

   <view class="at.calista.quatscha.views.SwipebarLayout"
        android:id="@+id/sbl"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <!-- Top View -->
        <Button android:text="Top" android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>

        <!-- Bottom View -->
        <Button android:text="Bottom" android:id="@+id/Button02" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>

You would need a method that determines whether two views overlap. 您需要一种方法来确定两个视图是否重叠。 For example, something like these methods could work for when the target view and the dragged item view are 2 distinct views in the same container view: 例如,当目标视图和拖动的项目视图在同一容器视图中是2个不同的视图时,类似这些方法的东西可以起作用:

private Rect getScreenBounds(View view)
{
    int[] location = new int[2];
    view.getLocationOnScreen(location);

    return new Rect(location[0], location[1], location[0] + view.getWidth(), location[1] + view.getHeight());
}

private boolean doViewsIntersect(View dropTarget, View item)
{
    Rect dropRect = getScreenBounds(dropTarget);
    Rect itemRect = getScreenBounds(item);

    return Rect.intersects(dropRect, itemRect);
}

However, if the views being dragged are child views on a container, and that container has a special hit area where you want to perform the drop logic, then you can just use that hit area's Rect for the intersect test. 但是,如果被拖动的视图是容器上的子视图,并且该容器具有您想要执行拖放逻辑的特殊命中区域,那么您可以使用该命中区域的Rect进行交叉测试。

To save information on the View , you have a few options: 要保存有关View信息,您有以下几种选择:

  • You can use view.setTag(key, object) and view.getTag(key) to store whatever information you'd like on each item. 您可以使用view.setTag(key, object)view.getTag(key)来存储您在每个项目上的任何信息。
  • If you are using a custom class for the items, you can just add a method to get the data from the view class. 如果要为项使用自定义类,则只需添加一个方法即可从视图类中获取数据。
  • If you are using multiple different classes for the items, you could make an interface, and implement that interface on each draggable view class. 如果为项使用多个不同的类,则可以创建一个接口,并在每个可拖动的视图类上实现该接口。

On an item's release, you could then check whether the areas/views intersect, and if they do, get whatever information you need from the dragged item to process as necessary, either using getTag or the method added to the view. 在项目的发布上,您可以检查区域/视图是否相交,如果它们相交,则可以使用getTag或添加到视图中的方法,根据需要从拖动项目中获取所需的任何信息。

For example, this could be triggered via an onTouchListener , when you receive a MotionEvent.ACTION_UP event. 例如,这可以通过触发onTouchListener ,当您收到MotionEvent.ACTION_UP事件。 Here's an example of a listener that you can add on each item: 以下是您可以在每个项目上添加的侦听器示例:

item.setOnTouchListener(new View.OnTouchListener()
{
    @Override
    public boolean onTouch(View v, MotionEvent event)
    {
        if (event.getActionMasked() == MotionEvent.ACTION_UP)
        {
            if (doViewsIntesect(dropTarget, v))
            {
                Object data = v.getTag(DATA_KEY);
                //process data
                ((ViewGroup) v.getParent()).removeView(v); // to remove the item afterwards
            }
        }
        return false;
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM