Android:在RelativeLayout的中心膨胀一个Movable按钮

时间:2014-12-20 02:37:57

标签: android ontouchlistener android-inflate layout-gravity ontouch

我想在relativelayout(Container)的中心膨胀一个可移动按钮,这样当触摸它时,它可以在Container内移动,即屏幕。

代码如下:

public void inflate_floating_btn(int k)
    {
        floatButton = new Button(this);
        floatButton.setId(k);
        floatButton.setTag(k);
        final int id_ = floatButton.getId();
        floatButton.setEnabled(true);
        floatButton.setText("hello");   
        floatButton.setTextColor(Color.BLACK);
        floatButton.setBackgroundResource(R.drawable.transparent_btn);

        RelativeLayout.LayoutParams testLP = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        testLP.addRule(RelativeLayout.CENTER_IN_PARENT);
        floatButton.setLayoutParams(testLP);

        Container.addView(floatButton);

        floatButton.setOnTouchListener(new View.OnTouchListener()
        {
          public boolean onTouch(View v, MotionEvent e)
          {
            final int X = (int) e.getRawX();
            final int Y = (int) e.getRawY();
              switch(e.getAction() & MotionEvent.ACTION_MASK)
              {
                    case MotionEvent.ACTION_DOWN:
                        RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
                        _xDelta = X - lParams.leftMargin;
                        _yDelta = Y - lParams.topMargin;
                        break;
                    case MotionEvent.ACTION_UP:
                        break;
                    case MotionEvent.ACTION_POINTER_DOWN:
                        break;
                    case MotionEvent.ACTION_POINTER_UP:
                        break;
                    case MotionEvent.ACTION_MOVE:                       
                        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
                        layoutParams.leftMargin = Math.max((X - _xDelta), 0);
                        layoutParams.topMargin = Math.max((Y - _yDelta),0);
                        layoutParams.rightMargin = 0;
                        layoutParams.bottomMargin = 0;
                        v.setLayoutParams(layoutParams);
                        break;
              }

              Container.invalidate();
              return false;
          }
        });
    }

按钮可以在屏幕中央充气。但触摸时无法移动。

如果替换

    RelativeLayout.LayoutParams testLP = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    testLP.addRule(RelativeLayout.CENTER_IN_PARENT);
    floatButton.setLayoutParams(testLP);

通过

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.setMargins(1, 1, 1, 1);

按钮现在可以在触摸时移动,但在relativelayout的左上角充气。

问题:

如何改进代码,使移动按钮可以在屏幕中心充气,并在触摸时移动?

谢谢!

1 个答案:

答案 0 :(得分:0)

不要在移动时更改视图边距,只需设置视图的绝对坐标。

drag_button_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

DragButtonFragment.java

public class DragButtonFragment extends Fragment {

    View root;
    float lastX, lastY;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        root = inflater.inflate(R.layout.drag_button_fragment, container, false);
        return root;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        addDragButton();
    }

    private void addDragButton() {
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.WRAP_CONTENT,
                RelativeLayout.LayoutParams.WRAP_CONTENT);
        layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
        Button dragButton = new Button(getActivity());
        dragButton.setLayoutParams(layoutParams);
        dragButton.setText("Drag Me!");
        dragButton.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent ev) {
                final int action = MotionEventCompat.getActionMasked(ev);
                if (action == MotionEvent.ACTION_DOWN) {
                    lastX = ev.getRawX();
                    lastY = ev.getRawY();
                } else if (action == MotionEvent.ACTION_MOVE) {
                    float thisX = ev.getRawX();
                    float thisY = ev.getRawY();
                    v.setX(v.getX() + (thisX - lastX));
                    v.setY(v.getY() + (thisY - lastY));
                    v.invalidate();
                    lastX = thisX;
                    lastY = thisY;
                }
                return false;
            }
        });

        ((ViewGroup) root).addView(dragButton);
    }
}

您正在寻找的唯一缺失的部分是将拖动的视图保留在屏幕内,这应该只是使用getX()getWidth()getY()和{{ 1 {} getHeight()root