2014-11-08 13 views
5

Potrzebuję klikalnego span, aby uzyskać zarówno normalne kliknięcie, jak i długie kliknięcia w mojej aplikacji i dowiedziałem się (In Android - How can I register only long clicks using a ClickableSpan), że mogę rozszerzyć klasę LinkMovementMethod i Klasa ClickableSpan pozwala to zrobić, ale obecnie długie i krótkie kliknięcia działają, ale długie kliknięcie zamiast uruchamiania akcji z długim kliknięciem, gdy przedmiot został naciśnięty wystarczająco długo, będzie czekać, aż zwolnisz przedmiot do strzału. Tu jest mój kodu dla rozszerzonych klas:Długie kliknięcie nieaktywnego spacji, dopóki nie zostanie zwolnione kliknięcie.

LinkMovementClass

import android.text.Layout; 
import android.text.Selection; 
import android.text.Spannable; 
import android.text.method.LinkMovementMethod; 
import android.text.method.MovementMethod; 
import android.view.MotionEvent; 
import android.widget.TextView; 

public class LongClickLinkMovementMethod extends LinkMovementMethod { 

private Long lastClickTime = 0l; 
private int lastX = 0; 
private int lastY = 0; 
@Override 
public boolean onTouchEvent(TextView widget, Spannable buffer, 
          MotionEvent event) { 
    int action = event.getAction(); 

    if (action == MotionEvent.ACTION_UP || 
      action == MotionEvent.ACTION_DOWN) { 
     int x = (int) event.getX(); 
     int y = (int) event.getY(); 
     lastX = x; 
     lastY = y; 
     int deltaX = Math.abs(x-lastX); 
     int deltaY = Math.abs(y-lastY); 

     x -= widget.getTotalPaddingLeft(); 
     y -= widget.getTotalPaddingTop(); 

     x += widget.getScrollX(); 
     y += widget.getScrollY(); 

     Layout layout = widget.getLayout(); 
     int line = layout.getLineForVertical(y); 
     int off = layout.getOffsetForHorizontal(line, x); 

     LongClickableSpan[] link = buffer.getSpans(off, off, LongClickableSpan.class); 

     if (link.length != 0) { 
      if (action == MotionEvent.ACTION_UP) { 
       if (System.currentTimeMillis() - lastClickTime < 1000) 
        link[0].onClick(widget); 
       else if (deltaX < 10 && deltaY < 10) 
        link[0].onLongClick(widget); 
      } else if (action == MotionEvent.ACTION_DOWN) { 
       Selection.setSelection(buffer, 
         buffer.getSpanStart(link[0]), 
         buffer.getSpanEnd(link[0])); 
       lastClickTime = System.currentTimeMillis(); 
      } 
      return true; 
     } 
    } 

    return super.onTouchEvent(widget, buffer, event); 
} 


public static MovementMethod getInstance() { 
    if (sInstance == null) 
     sInstance = new LongClickLinkMovementMethod(); 

    return sInstance; 
} 
    private static LongClickLinkMovementMethod sInstance; 
} 

LongClickableSpanClass

import android.text.style.ClickableSpan; 
import android.view.View; 

public abstract class LongClickableSpan extends ClickableSpan { 

    abstract public void onLongClick(View view); 
} 

Rzeczywista realizacja

LongClickableSpan eruptionText = new LongClickableSpan() { 

           @Override 
           public void onClick(View tvEruptions) { 
            LinkFunctions.link_eruption_detail(getApplicationContext(),PostErupionID); 
           } 

           @Override 
           public void onLongClick(View tvEruptions) { 
            if(SignedInUserID != 0) { 
             DialogFragment newFragment = new Dialogs.QuickActionsDialogFragment(); 
             // Supply num input as an argument. 
             Bundle args = new Bundle(); 
             args.putLong("eruptionID", PostErupionID); 
             newFragment.setArguments(args); 
             newFragment.show(getFragmentManager(), "QuickActions"); 
            } 
           } 

          }; 
          ss.setSpan(eruptionText, startpos[(int) j], endpos[(int) j], Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 

Odpowiedz

5

Wiem, że to pytanie jest stare i prawdopodobnie OP został już rozwiązany problem, ale zrobiłem kilka poprawek na oryginalnej LongClickLinkMovementMethod ognia po raz zdał zamiast kiedy zwolnić Tap

import android.os.Handler; 
import android.text.Layout; 
import android.text.Selection; 
import android.text.Spannable; 
import android.text.method.LinkMovementMethod; 
import android.text.method.MovementMethod; 
import android.view.MotionEvent; 
import android.widget.TextView; 


public class LongClickLinkMovementMethod extends LinkMovementMethod { 

    private Handler mLongClickHandler; 
    private static int LONG_CLICK_TIME = 1000; 
    private boolean mIsLongPressed = false; 

    @Override 
    public boolean onTouchEvent(final TextView widget, Spannable buffer, 
           MotionEvent event) { 
     int action = event.getAction(); 

     if(action == MotionEvent.ACTION_CANCEL){ 
      if(mLongClickHandler!=null){ 
       mLongClickHandler.removeCallbacksAndMessages(null); 
      } 
     } 

     if (action == MotionEvent.ACTION_UP || 
       action == MotionEvent.ACTION_DOWN) { 
      int x = (int) event.getX(); 
      int y = (int) event.getY(); 

      x -= widget.getTotalPaddingLeft(); 
      y -= widget.getTotalPaddingTop(); 

      x += widget.getScrollX(); 
      y += widget.getScrollY(); 

      Layout layout = widget.getLayout(); 
      int line = layout.getLineForVertical(y); 
      int off = layout.getOffsetForHorizontal(line, x); 

      final LongClickableSpan[] link = buffer.getSpans(off, off, LongClickableSpan.class); 

      if (link.length != 0) { 
       if (action == MotionEvent.ACTION_UP) { 
        if(mLongClickHandler!=null){ 
         mLongClickHandler.removeCallbacksAndMessages(null); 
        } 
        if(!mIsLongPressed) { 
         link[0].onClick(widget); 
        } 
        mIsLongPressed = false; 
       } else { 
        Selection.setSelection(buffer, 
          buffer.getSpanStart(link[0]), 
          buffer.getSpanEnd(link[0])); 
        mLongClickHandler.postDelayed(new Runnable() { 
         @Override 
         public void run() { 
          link[0].onLongClick(widget); 
          mIsLongPressed = true; 
         } 
        },LONG_CLICK_TIME); 
       } 
       return true; 
      } 
     } 

     return super.onTouchEvent(widget, buffer, event); 
    } 


    public static MovementMethod getInstance() { 
     if (sInstance == null) { 
      sInstance = new LongClickLinkMovementMethod(); 
      sInstance.mLongClickHandler = new Handler(); 
     } 

     return sInstance; 
    } 
    private static LongClickLinkMovementMethod sInstance; 
} 

Więc basicaly to używa Handler'a do wywoływania zdarzenia z długim kliknięciem po 1000ms

3

Prostym sposobem jest użycie View.setTag. Przykładem

Kod:

tv.setOnLongClickListener(new OnLongClickListener() { 

    @Override 
    public boolean onLongClick(View v) { 
     Toast.makeText(getApplicationContext(), "onLongClick", Toast.LENGTH_SHORT).show(); 
     v.setTag("Test"); 
     return true; 
    } 
}); 

private static class NonLongClickableUrlSpan extends URLSpan { 

    public NonLongClickableUrlSpan(String url) { 
     super(url); 
    } 

    @Override 
    public void onClick(View widget) { 
     if (widget.getTag() != null) { 
      widget.setTag(null); 
      return; 
     } 
     super.onClick(widget); 
    } 
} 
Powiązane problemy