拖放和TextView的的OnClick

问题描述 投票:2回答:9

我创建拖放文本视图,我需要这个文本视图也可以点击。我的代码,按照以下:

     <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/root"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/bg_grey"
        android:orientation="vertical" >

        <GridView
            android:id="@+id/gridview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:background="@color/bg_grey"
            android:clickable="true"
            android:columnWidth="100dp"
            android:gravity="center"
            android:horizontalSpacing="10dp"
            android:numColumns="2"
            android:stretchMode="columnWidth"
            android:verticalSpacing="10dp" />

        <TextView
            android:id="@+id/drag_drop_button"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_marginLeft="255dp"
            android:layout_marginTop="155dp"
            android:background="@drawable/circle_button"
            android:clickable="true"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:gravity="center"
            android:text="@string/brand"
            android:textColor="@color/sign_blue"
            android:textSize="15sp"
            android:textStyle="bold" />

    </FrameLayout>


class ButtonDragListener implements OnDragListener {
        Drawable normalShape = getResources().getDrawable(
                R.drawable.circle_button);

        @Override
        public boolean onDrag(View v, DragEvent event) {
            int action = event.getAction();
            switch (event.getAction()) {
            case DragEvent.ACTION_DRAG_STARTED:
                // do nothing
                break;
            case DragEvent.ACTION_DRAG_ENTERED:
                // do nothing
                break;
            case DragEvent.ACTION_DRAG_EXITED:
                // do nothing
                break;
            case DragEvent.ACTION_DROP:
                // Dropped, reassign View to ViewGroup
                View view = (View) event.getLocalState();
                view.setX(event.getX());
                view.setY(event.getY());
                ViewGroup owner = (ViewGroup) view.getParent();
                owner.removeView(view);
                FrameLayout container = (FrameLayout) v;
                container.addView(view);
                view.setVisibility(View.VISIBLE);
                break;
            case DragEvent.ACTION_DRAG_ENDED:
                // do nothing
                break;
            default:
                break;
            }
            return true;
        }
    }

        private final class ButtonTouchListener implements OnTouchListener {

            private static final int MAX_CLICK_DURATION = 200;
            private long startClickTime;

            public boolean onTouch(View view, MotionEvent motionEvent) {
                if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                    startClickTime = Calendar.getInstance().getTimeInMillis();
                    ClipData data = ClipData.newPlainText("", "");
                    DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(
                            view);
                    view.startDrag(data, shadowBuilder, view, 0);
                    view.setVisibility(View.VISIBLE);

                } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
                    long clickDuration = Calendar.getInstance().getTimeInMillis()
                            - startClickTime;

                    if (clickDuration < MAX_CLICK_DURATION){ 
                        view.performClick();
                    }
                }
                return true;
            }
        }

        private final class ButtonOnClickListener implements OnClickListener {

            @Override
            public void onClick(View v) {
                Log.e(TAG, "ALOHAAAAA");

            }

        }

        TextView dragDrop = (TextView) view.findViewById(R.id.drag_drop_button);
            dragDrop.setAlpha(0.7f);
            dragDrop.setOnClickListener(new ButtonOnClickListener());
            dragDrop.setOnTouchListener(new ButtonTouchListener());
        frameLayout = (FrameLayout) view.findViewById(R.id.root);
        frameLayout.setOnDragListener(new ButtonDragListener());

但是MotionEvent.ACTION_UP永远不会被调用,我也想移动view.performClick()MotionEvent_ACTION_DOWN,点击听众打电话罚款,但每当我拖动文本查看点击听者也运行。我也有setOnTouchListenersetOnClickListener直接从TextView的,但结果是一样的。

我需要在这里是平滑拖拽和点击也功能。请告知我在做什么错在这里。谢谢你,真的很感激任何一种帮助。

android drag-and-drop onclicklistener ontouchlistener
9个回答
3
投票

我有你,你的解决方案不是很帮助我同样的问题,所以我想出了这个解决方案,它基于以前的解决方案。

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (Math.abs(event.getX() - mX) < MAX_X_MOVE || Math.abs(event.getY() - mY) < MAX_Y_MOVE) {
                v.performClick();
            } else {
                ClipData clipData = ClipData.newPlainText("", "");
                View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
                v.startDrag(clipData, shadowBuilder, v, 0);
                v.setVisibility(View.INVISIBLE);

                mX = event.getX();
                mY = event.getY();
            }

            return true;
        }
        return false;
    }

2
投票

这是一种地方虽然有提供解决方案的问题,但也必须考虑这些解决方案将如何满足您的需求。对于我来说,我使用了上述观点,并与自己的解决方案,适合我的需求上来。

  /**
   * Max value of X to move before we declare that we are going to do
   * drag. 
   */
   private static final float MAX_X_MOVE = 120;

  /**
   * Max value of Y to move before we declare that we are going to do 
   * drag.
   */
   private static final float MAX_Y_MOVE = 120;

   private final static int NONE = 0;

   private final static int DRAG = 1;

   private int m_mode = NONE;

   icon.setOnTouchListener(new View.OnTouchListener() {
     @Override
     public boolean onTouch(View v, MotionEvent event) {

        final int action = event.getAction();

         switch (action){
           case MotionEvent.ACTION_DOWN:
            m_mode = NONE;
           break;

           case MotionEvent.ACTION_MOVE:
             if (Math.abs(event.getX()) > MAX_X_MOVE || 
                 Math.abs(event.getY()) > MAX_Y_MOVE) {
                 m_mode = DRAG;
                 _startDragOnFling();
             }
           break;

           case MotionEvent.ACTION_UP:
              if(m_mode == DRAG){
               break;
              }
              v.performClick();
           break;
         }

        return true;
      }
   });

1
投票

我有我自己的问题的解决方案,我修改了我的课ButtonTouchListener按如下:

    private final class ButtonTouchListener implements OnTouchListener {

    private static final float MAX_X_MOVE = 70;
    private static final float MAX_Y_MOVE = 70;

    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            ClipData data = ClipData.newPlainText("", "");
            DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(
                    view);
            view.startDrag(data, shadowBuilder, view, 0);
            view.setVisibility(View.VISIBLE);

             float offset_x = motionEvent.getX(); 
             float offset_y = motionEvent.getY();


                Log.d(TAG,"OFFSET X = "+offset_x); 
                Log.d(TAG,"OFFSET Y = "+offset_y); 


                if (offset_x < MAX_X_MOVE && offset_y < MAX_Y_MOVE) { 
                    Log.d(TAG,"Here we go"); 
                    view.performClick(); 
                    }


            return true;

        } else {
            return false;
        }

    }

}

请注意,我越来越指针x和y的事件,这帮助我指示的TextView是否移动太远,如果它走得比MAX_X_MOVE和MAX_Y_MOVE会被认为是一个阻力运动。也许这可以帮助别人谁遇到同样的问题。任何更好的解决方案,请欢迎:)


1
投票

它已经发布了阻力监听器,你可以写的TextView setonClickListener方法..

链接在这里..

How to drag the TextView to the correct target other TextView

对于的onClick ..

textView.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // your code

        }
    });

0
投票

它只是一个想法,设置的onClick在XML TextView的,并调用的onClick方法为好。

android:onClick="onClickTextView"
public void onClickTextView()

{
// your actions
}

0
投票

试试这个,只是一个想法。你希望工作。

TextView dragDrop = (TextView) view.findViewById(R.id.drag_drop_button);
dragDrop.setAlpha(0.7f);
dragDrop.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View arg0) {
                        // TODO Auto-generated method stub

                    }
                });

0
投票

在我的应用程序,一系列按钮可以点击或拖动。要做到这一点我有

  • 在定义XML按钮与“点击”属性引用在我的主要活性的方法(在您的应用程序,附加一个“View.OnClickListener”到你的TextView代替)
  • 定义的“OnDragListener”(因为所有拖动事件都在一个单独的“OnDragListener”连接到下降的目标视图处理,它只是返回true)
  • 所定义的“OnLongClickListener”
  • 覆盖了“的onClick()”在我的主要活动(我不记得这是记录)
  • 分配了“OnLongClickListener”的按钮
  • 分配了“OnDragListener”的按钮

这是我的实现:

@Override
public void onClick(View v) {  }

class ScDragListenerForButton implements OnDragListener {
    @Override
    public boolean onDrag(View v, DragEvent event) {
        return true;
    }
}

ScDragListenerForButton mDragListenerForButton = new ScDragListenerForButton();

View.OnLongClickListener onLongClickListener = new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        Button b = (Button) v;
        ClipData.Item item = new ClipData.Item(b.getText());
        String[] mimeTypes = {ClipDescription.MIMETYPE_TEXT_PLAIN};

        ClipData dragData = new ClipData(b.getText(), mimeTypes, item);
        View.DragShadowBuilder myShadow = new View.DragShadowBuilder(v);

        if (Build.VERSION.SDK_INT < VERSION_CODES.N) {
            v.startDrag(dragData, myShadow, null, 0);
        } else {
            v.startDragAndDrop(dragData, myShadow, null, 0);
        }
        return true;
    }
};

button1.setOnLongClickListener(onLongClickListener);
button1.setOnDragListener(mDragListenerForButton);

0
投票

尝试这个:

public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
  float dX;
  float dY;
  int lastAction;

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

    final View dragView = findViewById(R.id.draggable_view);
    dragView.setOnTouchListener(this);
  }

  @Override
  public boolean onTouch(View view, MotionEvent event) {
    switch (event.getActionMasked()) {
      case MotionEvent.ACTION_DOWN:
        dX = view.getX() - event.getRawX();
        dY = view.getY() - event.getRawY();
        lastAction = MotionEvent.ACTION_DOWN;
        break;

      case MotionEvent.ACTION_MOVE:
        view.setY(event.getRawY() + dY);
        view.setX(event.getRawX() + dX);
        lastAction = MotionEvent.ACTION_MOVE;
        break;

      case MotionEvent.ACTION_UP:
        if (lastAction == MotionEvent.ACTION_DOWN)
          Toast.makeText(DraggableView.this, "Clicked!", Toast.LENGTH_SHORT).show();
        break;

      default:
        return false;
    }
    return true;
  }
}

和XML:

<ImageButton
        android:id="@+id/draggable_view"
        android:background="@mipmap/ic_launcher"
        android:layout_gravity="bottom|right"
        android:layout_marginBottom="20dp"
        android:layout_marginEnd="20dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

你可以做任何视图可拖动和点击。


0
投票

尝试这个:

        public class MainActivity extends AppCompatActivity implements View.OnTouchListener, View.OnDragListener , View.OnClickListener {

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

            final View dragView = findViewById(R.id.draggable_view);
            dragView.setOnTouchListener(this);
            dragView.setOnclickListener(this);

          }

     @Override
        public boolean onTouch(View v, MotionEvent event) {

            //if move detected it start Drag event and it's handler or click wil be handled by click listener
            if(event.getAction()  == MotionEvent.ACTION_MOVE){
                View.DragShadowBuilder mShadow = new View.DragShadowBuilder(v);

                    dragView = v;
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        v.startDragAndDrop(null, mShadow, null, 0);
                    } else {
                        v.startDrag(null, mShadow, null, 0);
                    }
                 }
       return false;
    }

 @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.draggable_view:{
                showToast("click detected");
            }
            break;
           }
       }
}
© www.soinside.com 2019 - 2024. All rights reserved.