简体   繁体   中英

Cannot use setOnClickListener() and setMovementMethod(new ScrollingMovementMethod()) on TextView

Hey guys this is my problem. I am trying to be able to click on a TextView and detect that touch event (which works if I don't also include the setMovementMethod ). When I include the setMovementMethod , the onClick simply does not work at all. I want to use both to be able to scroll down on my TextView but also to be able to click on it and handle that event. Thanks.

public class SQLView extends Activity implements OnClickListener{

    public static final String KEY_ROWID = "_id";
    public static final String KEY_FRONT = "card_front";
    public static final String KEY_BACK = "card_back";
    private Cursor myCursor;
    private TextView tv, card_info;
    private int iRow;
    private int iFront;
    private int iBack;
    private String info = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sqlview);

        tv = (TextView)findViewById(R.id.flashcard);
        tv.setMovementMethod(new ScrollingMovementMethod());
        tv.setOnClickListener(this);

        Flashcards Cards = new Flashcards(this);
        Cards.open();//open DB

        myCursor = Cards.getCursor();

        iRow = myCursor.getColumnIndex(KEY_ROWID);
        iFront = myCursor.getColumnIndex(KEY_FRONT);
        iBack = myCursor.getColumnIndex(KEY_BACK);

        myCursor.moveToFirst();

        intialize();

        tv.setText(myCursor.getString(iFront));
    }

    private void intialize(){

        Button add = (Button) findViewById(R.id.add_new);
        Button next = (Button) findViewById(R.id.next);
        Button prev = (Button) findViewById(R.id.prev);

        add.setOnClickListener(this);
        next.setOnClickListener(this);
        prev.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()){

            case R.id.next:
                if(myCursor.isLast()){
                    myCursor.moveToFirst();
                    tv.setText(myCursor.getString(iFront));
                }else{
                    myCursor.moveToNext();
                    tv.setText(myCursor.getString(iFront));
                }
                break;

            case R.id.prev:

                if(myCursor.isFirst()){

                    myCursor.moveToLast();
                    tv.setText(myCursor.getString(iFront));
                }else{
                    myCursor.moveToPrevious();
                    tv.setText(myCursor.getString(iFront));
                }
                break;


            case R.id.flashcard:
                if(tv.getText().equals(myCursor.getString(iFront))){
                    tv.setText(myCursor.getString(iBack));
                    break;
                }
                tv.setText(myCursor.getString(iFront));
                break;

            case R.id.add_new:
                Intent list = new Intent("com.example.flashcards.ADD_FLASHCARD");
                startActivity(list);
                break;
        }
    }
}

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

<TextView
    android:id="@+id/flashcard"
    android:layout_width="fill_parent"
    android:layout_height="34dp"
    android:layout_weight="0.17"
    android:gravity="center"
    android:maxLines="300"
    android:scrollbars="vertical"
    android:textSize="30dp" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <Button
        android:id="@+id/add_new"
        android:layout_width="wrap_content"
        android:layout_height="64dp"
        android:layout_weight="0.51"
        android:text="Add New"/>

    <Button
        android:id="@+id/next"
        android:layout_width="wrap_content"
        android:layout_height="64dp"
        android:layout_weight="0.51"
        android:text="Next"/>

    <Button
        android:id="@+id/prev"
        android:layout_width="wrap_content"
        android:layout_height="64dp"
        android:layout_weight="0.51"
        android:text="Previous" />
</LinearLayout>

</LinearLayout>

I wrote a nice class that fixes this for me.

The usage is as such: (textView must contain a link eg click <a href="...">here</a>

ActionableUrlSpan.linkifyTextView(this, textView, new OnClickListener() {
 public void onClick(View v) {
   // Do something
 }
});

ActionableUrlSpan is:

public class ActionableUrlSpan extends URLSpan {

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

    public static void linkifyTextView(Context context, TextView textView,
            final OnClickListener listener) {

        SpannedString spanned = (SpannedString) textView.getText();
        SpannableStringBuilder newSpanned = new SpannableStringBuilder(spanned);

        URLSpan[] spans = newSpanned.getSpans(0, newSpanned.length(), URLSpan.class);
        if (spans.length > 0) {

            URLSpan urlSpan = spans[0];

            int start = newSpanned.getSpanStart(urlSpan);
            int end = newSpanned.getSpanEnd(urlSpan);

            newSpanned.removeSpan(urlSpan);
            newSpanned.setSpan(new ActionableUrlSpan(urlSpan.getURL()) {
                @Override
                public void onClick(View v) {
                    listener.onClick(v);

                    super.onClick(v);
                }
            }, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

            textView.setText(newSpanned);
        } else {
            Log.e("No spans found in url-string " + textView.getText() + " - "
                    + Locale.getDefault());
        }

        MovementMethod m = textView.getMovementMethod();
        if ((m == null) || !(m instanceof LinkMovementMethod)) {
            if (textView.getLinksClickable()) {
                textView.setMovementMethod(LinkMovementMethod.getInstance());
            }
        }
    }
}

You will have to call setFocusable(true) on your view. From the docs :

Be warned that if you want a TextView with a key listener or movement method not to be focusable, or if you want a TextView without a key listener or movement method to be focusable, you must call setFocusable(boolean) again after calling this to get the focusability back the way you want it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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