Monodroid - 通过触摸事件拖动视图?

发布于 2024-12-06 09:30:55 字数 2834 浏览 4 评论 0原文

我想拖动视图。到目前为止,我尝试使用 LinearLayout 和边距以及 AbsoluteLayout。

AbsoluteLayout 示例:

button.Touch = (clickedView, motionEvent) =>
{
   Button b = (Button)clickedView;
   if (motionEvent.Action == MotionEventActions.Move)
   {                    
        AbsoluteLayout.LayoutParams layoutParams = new AbsoluteLayout.LayoutParams(100, 35, (int)motionEvent.GetX(), (int)motionEvent.GetY());
        b.LayoutParameters = layoutParams;                    
   }
   return true;
};

在我尝试的每种情况下,我都会得到一个奇怪的行为。原因如下。我拖动的视图跟随我的手指,但总是在两个位置之间跳转。一个位置击中了我的手指,另一个位置位于我手指左上方的某个位置。如果我只是将当前位置写入文本视图(不移动视图),则坐标将按预期运行。但如果我也移动视图,它们就会再次跳跃。 我怎样才能避免这种情况?

编辑:我对我的问题使用了声音评论来实现 monodroid 的工作拖动(它是为链接站点中的 Java/Android SDK 完成的)。也许有一天其他人有兴趣这样做,所以这是我的解决方案:

[Activity(Label = "Draging", MainLauncher = true, Icon = "@drawable/icon")]
public class Activity1 : Activity
{
    private View selectedItem = null;
    private int offset_x = 0;
    private int offset_y = 0;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.Main);

        ViewGroup vg = (ViewGroup)FindViewById(Resource.Id.vg);
        vg.Touch = (element, motionEvent) =>
        {
            switch (motionEvent.Action)
            {
                case MotionEventActions.Move:
                    int x = (int)motionEvent.GetX() - offset_x;
                    int y = (int)motionEvent.GetY() - offset_y;
                    int w = WindowManager.DefaultDisplay.Width - 100; 
                    int h = WindowManager.DefaultDisplay.Height - 100; 
                    if (x > w)
                        x = w;
                    if (y > h)
                        y = h;
                    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                        new ViewGroup.MarginLayoutParams(
                            LinearLayout.LayoutParams.WrapContent,
                            LinearLayout.LayoutParams.WrapContent));
                    lp.SetMargins(x, y, 0, 0);
                    selectedItem.LayoutParameters = lp;
                    break;
                default:
                    break;
            }
            return true;
        };

        ImageView img = FindViewById<ImageView>(Resource.Id.img);
        img.Touch = (element, motionEvent) =>
        {
            switch (motionEvent.Action)
            {
                case MotionEventActions.Down:
                    offset_x = (int)motionEvent.GetX();
                    offset_y = (int)motionEvent.GetY();
                    selectedItem = element;
                    break;
                default:
                    break;
            }
            return false;
        };
    }        
}

I want to drag a view. Until now i tried it with a LinearLayout and margins and with a AbsoluteLayout.

AbsoluteLayout example:

button.Touch = (clickedView, motionEvent) =>
{
   Button b = (Button)clickedView;
   if (motionEvent.Action == MotionEventActions.Move)
   {                    
        AbsoluteLayout.LayoutParams layoutParams = new AbsoluteLayout.LayoutParams(100, 35, (int)motionEvent.GetX(), (int)motionEvent.GetY());
        b.LayoutParameters = layoutParams;                    
   }
   return true;
};

In every case I tried I got a curios behaviour. Here's why. The view i'm dragging follows my finger but jumps always between two positions. One postition hits my finger the other is somewhere to my fingers left-top. If I'm just writing my current position into a textview (without moving the view) the coordinates behave as expected. But if i'm also moving the view they are jumping again.
How can i avoid this?

EDIT: I used sounds comment on my question to implement a working draging for monodroid (it is done for Java/Android SDK in the linked site). Maybe others are interested in doing that some day, so here's my solution:

[Activity(Label = "Draging", MainLauncher = true, Icon = "@drawable/icon")]
public class Activity1 : Activity
{
    private View selectedItem = null;
    private int offset_x = 0;
    private int offset_y = 0;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.Main);

        ViewGroup vg = (ViewGroup)FindViewById(Resource.Id.vg);
        vg.Touch = (element, motionEvent) =>
        {
            switch (motionEvent.Action)
            {
                case MotionEventActions.Move:
                    int x = (int)motionEvent.GetX() - offset_x;
                    int y = (int)motionEvent.GetY() - offset_y;
                    int w = WindowManager.DefaultDisplay.Width - 100; 
                    int h = WindowManager.DefaultDisplay.Height - 100; 
                    if (x > w)
                        x = w;
                    if (y > h)
                        y = h;
                    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                        new ViewGroup.MarginLayoutParams(
                            LinearLayout.LayoutParams.WrapContent,
                            LinearLayout.LayoutParams.WrapContent));
                    lp.SetMargins(x, y, 0, 0);
                    selectedItem.LayoutParameters = lp;
                    break;
                default:
                    break;
            }
            return true;
        };

        ImageView img = FindViewById<ImageView>(Resource.Id.img);
        img.Touch = (element, motionEvent) =>
        {
            switch (motionEvent.Action)
            {
                case MotionEventActions.Down:
                    offset_x = (int)motionEvent.GetX();
                    offset_y = (int)motionEvent.GetY();
                    selectedItem = element;
                    break;
                default:
                    break;
            }
            return false;
        };
    }        
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文