Example usage for android.text Spannable getSpans

List of usage examples for android.text Spannable getSpans

Introduction

In this page you can find the example usage for android.text Spannable getSpans.

Prototype

public <T> T[] getSpans(int start, int end, Class<T> type);

Source Link

Document

Return an array of the markup objects attached to the specified slice of this CharSequence and whose type is the specified type or a subclass of it.

Usage

From source file:im.zico.fancy.common.widget.HackyMovementMethod.java

@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
    if (mGray == null) {
        mGray = new BackgroundColorSpan(
                ContextCompat.getColor(widget.getContext(), R.color.alpha_spannable_pressed));
    }/*from www . j av a  2 s. c o m*/

    mIsLinkHit = false;

    int action = event.getAction();

    if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_UP) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        x -= widget.getTotalPaddingLeft();
        y -= widget.getTotalPaddingTop();
        x += widget.getScrollX();
        y += widget.getScrollY();

        int line = widget.getLayout().getLineForVertical(y);
        int offset = widget.getLayout().getOffsetForHorizontal(line, x);

        ClickableSpan[] spans = buffer.getSpans(offset, offset, ClickableSpan.class);

        if (spans.length != 0) {
            int start = buffer.getSpanStart(spans[0]);
            int end = buffer.getSpanEnd(spans[0]);
            mIsLinkHit = true;
            if (action == MotionEvent.ACTION_DOWN) {
                buffer.setSpan(mGray, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            } else if (action == MotionEvent.ACTION_UP) {
                spans[0].onClick(widget);
                buffer.removeSpan(mGray);
            }
            return true;
        }
    } else {
        buffer.removeSpan(mGray);
    }

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

From source file:com.nearnotes.NoteEdit.java

public void toggleChecklist() {
    if (mChecklist) {
        Toast.makeText(getActivity(), "Checklist off", Toast.LENGTH_SHORT).show();
        mChecklist = false;/*  ww  w  .  ja v a2s  .  c o m*/
        mTblAddLayout.removeAllViews();
        mBodyText.removeTextChangedListener(bodyTextWatcher);
        Spannable spannable = (Spannable) mBodyText.getText();
        Object spansToRemove[] = spannable.getSpans(0, spannable.length(), Object.class);
        for (Object span : spansToRemove) {
            if (span instanceof CharacterStyle)
                spannable.removeSpan(span);
        }
    } else {
        Toast.makeText(getActivity(), "Checklist on", Toast.LENGTH_SHORT).show();
        mChecklist = true;
        mBodyText.addTextChangedListener(bodyTextWatcher);

        String tempBoxes = mBodyText.getText().toString();
        if (mBodyText.getLayout() != null) {
            mRealRow = populateBoxes(tempBoxes);

            int row = 0;
            for (NoteRow line : mRealRow) {
                switch (line.getType()) {
                case 0:
                    TableRow inflate = (TableRow) View.inflate(getActivity(), R.layout.table_row_invisible,
                            null);
                    mTblAddLayout.addView(inflate);
                    break;
                case 1:
                    TableRow checkRow = (TableRow) View.inflate(getActivity(), R.layout.table_row, null);
                    CheckBox temp = (CheckBox) checkRow.getChildAt(0);
                    temp.setTag(Integer.valueOf(row));
                    mTblAddLayout.addView(checkRow);
                    temp.setOnClickListener(checkBoxListener);
                    break;
                case 2:
                    TableRow checkRow1 = (TableRow) View.inflate(getActivity(), R.layout.table_row, null);
                    CheckBox temp1 = (CheckBox) checkRow1.getChildAt(0);
                    temp1.setTag(Integer.valueOf(row));
                    temp1.setChecked(true);
                    mTblAddLayout.addView(checkRow1);
                    temp1.setOnClickListener(checkBoxListener);
                    break;
                }

                for (int k = 1; line.getSize() > k; k++) {
                    TableRow inflate = (TableRow) View.inflate(getActivity(), R.layout.table_row_invisible,
                            null);
                    mTblAddLayout.addView(inflate);
                }
                row++;
            }
        }

    }

}

From source file:android.melbournehistorymap.MapsActivity.java

/**
 * Manipulates the map once available.//from   w w w. j  a  va 2  s . c o  m
 * This callback is triggered when the map is ready to be used.
 * This is where we can add markers or lines, add listeners or move the camera. In this case,
 * we just add a marker near Sydney, Australia.
 * If Google Play services is not installed on the device, the user will be prompted to install
 * it inside the SupportMapFragment. This method will only be triggered once the user has
 * installed Google Play services and returned to the app.
 */
@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    spinner = (ProgressBar) findViewById(R.id.prograssSpinner);
    //check if permission has been granted
    if (ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // Permission has already been granted
        return;
    }
    mMap.setMyLocationEnabled(true);
    mMap.getUiSettings().setZoomControlsEnabled(false);

    double lat;
    double lng;
    final int radius;
    int zoom;

    lat = Double.parseDouble(CurrLat);
    lng = Double.parseDouble(CurrLong);

    //build current location
    LatLng currentLocation = new LatLng(lat, lng);
    final LatLng realLocation = currentLocation;

    if (MELBOURNE.contains(currentLocation)) {
        mMap.getUiSettings().setMyLocationButtonEnabled(true);
        zoom = 17;
    } else {
        mMap.getUiSettings().setMyLocationButtonEnabled(false);
        lat = -37.81161508043379;
        lng = 144.9647320434451;
        zoom = 15;
        currentLocation = new LatLng(lat, lng);
    }

    mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLocation, 13));

    CameraPosition cameraPosition = new CameraPosition.Builder().target(currentLocation) // Sets the center of the map to location user
            .zoom(zoom) // Sets the zoom
            .bearing(0) // Sets the orientation of the camera to east
            .tilt(25) // Sets the tilt of the camera to 30 degrees
            .build(); // Creates a CameraPosition from the builder

    //Animate user to map location, if in Melbourne or outside of Melbourne bounds
    mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition),
            new GoogleMap.CancelableCallback() {
                @Override
                public void onFinish() {
                    updateMap();
                }

                @Override
                public void onCancel() {

                }
            });

    final TextView placeTitle = (TextView) findViewById(R.id.placeTitle);
    final TextView placeVic = (TextView) findViewById(R.id.placeVic);
    final TextView expPlaceTitle = (TextView) findViewById(R.id.expPlaceTitle);
    final TextView expPlaceVic = (TextView) findViewById(R.id.expPlaceVic);
    final TextView expPlaceDescription = (TextView) findViewById(R.id.placeDescription);
    final TextView wikiLicense = (TextView) findViewById(R.id.wikiLicense);
    final TextView expPlaceDistance = (TextView) findViewById(R.id.expPlaceDistance);
    final RelativeLayout tile = (RelativeLayout) findViewById(R.id.tile);
    final TextView fab = (TextView) findViewById(R.id.fab);
    final RelativeLayout distanceCont = (RelativeLayout) findViewById(R.id.distanceContainer);

    //        String license = "Text is available under the <a rel=\"license\" href=\"//en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License\">Creative Commons Attribution-ShareAlike License</a><a rel=\"license\" href=\"//creativecommons.org/licenses/by-sa/3.0/\" style=\"display:none;\"></a>;\n" +
    //                "additional terms may apply.";
    //        wikiLicense.setText(Html.fromHtml(license));
    //        wikiLicense.setMovementMethod(LinkMovementMethod.getInstance());
    //Marker click
    mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {

        @Override
        public boolean onMarkerClick(Marker marker) {
            String title = marker.getTitle();
            mMap.setPadding(0, 0, 0, 620);
            //set clicked marker to full opacity
            marker.setAlpha(1f);
            //set previous marker back to partial opac (if there is a prevMarker
            if (dirtyMarker == 1) {
                prevMarker.setAlpha(0.6f);
            }
            prevMarker = marker;
            dirtyMarker = 1;

            //Set DB helper
            DBHelper myDBHelper = new DBHelper(MapsActivity.this, WikiAPI.DB_NAME, null, WikiAPI.VERSION);

            //Only search for Wiki API requests if no place article returned.
            // **
            //Open DB as readable only.
            SQLiteDatabase db = myDBHelper.getReadableDatabase();
            //Set the query
            String dbFriendlyName = title.replace("\'", "\'\'");
            //Limit by 1 rows
            Cursor cursor = db.query(DBHelper.TABLE_NAME, null, "PLACE_NAME = '" + dbFriendlyName + "'", null,
                    null, null, null, "1");

            //move through each row returned in the query results
            while (cursor.moveToNext()) {

                String place_ID = cursor.getString(cursor.getColumnIndex("PLACE_ID"));
                String placeName = cursor.getString(cursor.getColumnIndex("PLACE_NAME"));
                String placeLoc = cursor.getString(cursor.getColumnIndex("PLACE_LOCATION"));
                String placeArticle = cursor.getString(cursor.getColumnIndex("ARTICLE"));
                String placeLat = cursor.getString(cursor.getColumnIndex("LAT"));
                String placeLng = cursor.getString(cursor.getColumnIndex("LNG"));

                //Get Google Place photos
                //Source: https://developers.google.com/places/android-api/photos
                final String placeId = place_ID;
                Places.GeoDataApi.getPlacePhotos(mGoogleApiClient, placeId)
                        .setResultCallback(new ResultCallback<PlacePhotoMetadataResult>() {
                            @Override
                            public void onResult(PlacePhotoMetadataResult photos) {
                                if (!photos.getStatus().isSuccess()) {
                                    return;
                                }
                                ImageView mImageView = (ImageView) findViewById(R.id.imageView);
                                ImageView mImageViewExpanded = (ImageView) findViewById(R.id.headerImage);
                                TextView txtAttribute = (TextView) findViewById(R.id.photoAttribute);
                                TextView expTxtAttribute = (TextView) findViewById(R.id.expPhotoAttribute);
                                PlacePhotoMetadataBuffer photoMetadataBuffer = photos.getPhotoMetadata();
                                if (photoMetadataBuffer.getCount() > 0) {
                                    // Display the first bitmap in an ImageView in the size of the view
                                    photoMetadataBuffer.get(0).getScaledPhoto(mGoogleApiClient, 600, 200)
                                            .setResultCallback(mDisplayPhotoResultCallback);
                                    //get photo attributions
                                    PlacePhotoMetadata photo = photoMetadataBuffer.get(0);
                                    CharSequence attribution = photo.getAttributions();
                                    if (attribution != null) {
                                        txtAttribute.setText(Html.fromHtml(String.valueOf(attribution)));
                                        expTxtAttribute.setText(Html.fromHtml(String.valueOf(attribution)));
                                        //http://stackoverflow.com/questions/4303160/how-can-i-make-links-in-fromhtml-clickable-android
                                        txtAttribute.setMovementMethod(LinkMovementMethod.getInstance());
                                        expTxtAttribute.setMovementMethod(LinkMovementMethod.getInstance());
                                    } else {
                                        txtAttribute.setText(" ");
                                        expTxtAttribute.setText(" ");
                                    }
                                } else {
                                    //Reset image view as no photo was identified
                                    mImageView.setImageResource(android.R.color.transparent);
                                    mImageViewExpanded.setImageResource(android.R.color.transparent);
                                    txtAttribute.setText(R.string.no_photos);
                                    expTxtAttribute.setText(R.string.no_photos);
                                }
                                photoMetadataBuffer.release();
                            }
                        });

                LatLng destLocation = new LatLng(Double.parseDouble(placeLat), Double.parseDouble(placeLng));
                //Work out distance between current location and place location
                //Source Library: https://github.com/googlemaps/android-maps-utils
                double distance = SphericalUtil.computeDistanceBetween(realLocation, destLocation);
                distance = Math.round(distance);
                distance = distance * 0.001;
                String strDistance = String.valueOf(distance);
                String[] arrDistance = strDistance.split("\\.");
                String unit = "km";
                if (arrDistance[0] == "0") {
                    unit = "m";
                    strDistance = arrDistance[1];
                } else {
                    strDistance = arrDistance[0] + "." + arrDistance[1].substring(0, 1);
                }

                placeArticle = placeArticle
                        .replaceAll("(<div class=\"thumb t).*\\s.*\\s.*\\s.*\\s.*\\s<\\/div>\\s<\\/div>", " ");

                Spannable noUnderlineMessage = new SpannableString(Html.fromHtml(placeArticle));

                //http://stackoverflow.com/questions/4096851/remove-underline-from-links-in-textview-android
                for (URLSpan u : noUnderlineMessage.getSpans(0, noUnderlineMessage.length(), URLSpan.class)) {
                    noUnderlineMessage.setSpan(new UnderlineSpan() {
                        public void updateDrawState(TextPaint tp) {
                            tp.setUnderlineText(false);
                        }
                    }, noUnderlineMessage.getSpanStart(u), noUnderlineMessage.getSpanEnd(u), 0);
                }

                placeArticle = String.valueOf(noUnderlineMessage);
                placeArticle = placeArticle.replaceAll("(\\[\\d\\])", " ");

                placeTitle.setText(placeName);
                expPlaceTitle.setText(placeName);
                placeVic.setText(placeLoc);
                expPlaceVic.setText(placeLoc);
                expPlaceDescription.setText(placeArticle);
                if (MELBOURNE.contains(realLocation)) {
                    expPlaceDistance.setText("Distance: " + strDistance + unit);
                    distanceCont.setVisibility(View.VISIBLE);
                }
            }

            tile.setVisibility(View.VISIBLE);
            fab.setVisibility(View.VISIBLE);
            //Set to true to not show default behaviour.
            return false;
        }
    });

    mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
        @Override
        public void onMapClick(LatLng latLng) {
            int viewStatus = tile.getVisibility();
            if (viewStatus == View.VISIBLE) {
                tile.setVisibility(View.INVISIBLE);
                fab.setVisibility(View.INVISIBLE);
                //set previous marker back to partial opac (if there is a prevMarker
                if (dirtyMarker == 1) {
                    prevMarker.setAlpha(0.6f);
                }
            }

            mMap.setPadding(0, 0, 0, 0);
        }
    });

    FloatingActionButton shareIcon = (FloatingActionButton) findViewById(R.id.shareIcon);
    shareIcon.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //https://www.google.com.au/maps/place/Federation+Square/@-37.8179789,144.9668635,15z

            //Build implicit intent by triggering a SENDTO action, which will capture applications that allow for messages
            //that allow for messages to be sent to a specific user with data
            //http://developer.android.com/reference/android/content/Intent.html#ACTION_SENDTO
            Intent intent = new Intent(Intent.ACTION_SEND);
            intent.setType("text/plain");
            //Build SMS
            String encodedPlace = "empty";
            try {
                encodedPlace = URLEncoder.encode(String.valueOf(expPlaceTitle.getText()), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            intent.putExtra(Intent.EXTRA_TEXT, String.valueOf(expPlaceTitle.getText())
                    + " \n\nhttps://www.google.com.au/maps/place/" + encodedPlace);
            Intent sms = Intent.createChooser(intent, null);
            startActivity(sms);
        }
    });

    TextView fullArticle = (TextView) findViewById(R.id.fullArticle);
    fullArticle.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String wikiPlace = WikiPlace.getName(String.valueOf(expPlaceTitle.getText()));
            String url = "https://en.wikipedia.org/wiki/" + wikiPlace;

            Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
            startActivity(browserIntent);
        }
    });
}

From source file:com.nearnotes.NoteEdit.java

/**
 * Populates the checkboxes on the side by analyzing the current text from
 * the body of the note./* ww  w.ja  va2  s  .c  o  m*/
 * 
 * @param currentString
 *            the current body of the note.
 * 
 */
public ArrayList<NoteRow> populateBoxes(String currentString) {

    // Load ArrayList<String> mLines with the current bodytext seperated into seperate lines.
    mLines = Arrays.asList(currentString.split(System.getProperty("line.separator")));

    // row counter to determine what the current line number is for the for loop
    int row = 0;

    // realRow counter to determine what line of text in the actual display we are on
    // used to get the number of characters on each line
    int realRow = 0;
    int activeRow = 0;
    int finishedCount = 0;

    ArrayList<NoteRow> tempRealRow = new ArrayList<NoteRow>();
    for (String line : mLines) {
        NoteRow temp = new NoteRow(0, 1, row); // Create a note row object with rowType of 0 (invisible), lineSize of 1 and the current row number

        if (!line.isEmpty()) {
            activeRow++;
            temp.setType(1); // Set the NoteRow object to 1 (visible)

            // Determine how many lines the note takes up
            int internalCounter = 0;
            try {
                float lineLength = (float) line.length();
                for (int k = 0; (lineLength
                        / (getFloatLineEnd(realRow + k) - getFloatLineEnd(realRow - 1))) > 1; k++) {
                    internalCounter++;
                }
            } catch (NullPointerException e) {
                e.printStackTrace();
            }

            // Detemine if the note is supposed to be checked and set the NoteRow object to 2 (Checked)
            if (line.startsWith("[X]")) {
                finishedCount++;
                int spanstart = 0;
                StrikethroughSpan STRIKE_THROUGH_SPAN = new StrikethroughSpan();
                Spannable spannable = (Spannable) mBodyText.getText();
                // TableRow checkRow1 = (TableRow) View.inflate(getActivity(), R.layout.table_row, null);

                for (int j = 0; j < row; j++) {
                    spanstart += mLines.get(j).length() + 1;
                }

                Object spansToRemove[] = spannable.getSpans(spanstart, spanstart + mLines.get(row).length(),
                        Object.class);
                for (Object span : spansToRemove) {
                    if (span instanceof CharacterStyle)
                        spannable.removeSpan(span);
                }

                spannable.setSpan(STRIKE_THROUGH_SPAN, spanstart, spanstart + mLines.get(row).length(),
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                temp.setType(2);
            }

            temp.setSize(1 + internalCounter); // Set the amount of rows the note takes up
            realRow = realRow + internalCounter; // Determine the real line on the display text we are on
        }

        tempRealRow.add(temp); // NoteRow object has been finalized - add to the ListArray<NoteRow>
        realRow++; // Increase the noteRow and the displayRow for the next line
        row++;
    }

    if (finishedCount == activeRow && finishedCount != 0) {

        SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity());
        boolean useListPref = sharedPref.getBoolean("pref_key_use_checklist_default", false);
        String stringlistPref = sharedPref.getString("pref_key_checklist_listPref", "2");
        int listPref = Integer.parseInt(stringlistPref);

        ChecklistDialog newFragment = new ChecklistDialog();
        if (mRowId == null) {
            saveState();
        }
        Bundle args = new Bundle();
        args.putLong("_id", mRowId);
        args.putBoolean("useDefault", useListPref);
        args.putInt("listPref", listPref);
        newFragment.setArguments(args);
        if (listPref == 2 && useListPref) {
            return tempRealRow;
        }
        if (getFragmentManager().findFragmentByTag("MyDialog") == null) {
            newFragment.show(getFragmentManager(), "MyDialog");
        }

    }

    return tempRealRow;
}

From source file:android.support.text.emoji.EmojiProcessor.java

/**
 * Checks a given CharSequence for emojis, and adds EmojiSpans if any emojis are found.
 * <p>/* w w  w  . j a v  a  2  s .com*/
 * <ul>
 * <li>If no emojis are found, {@code charSequence} given as the input is returned without
 * any changes. i.e. charSequence is a String, and no emojis are found, the same String is
 * returned.</li>
 * <li>If the given input is not a Spannable (such as String), and at least one emoji is found
 * a new {@link android.text.Spannable} instance is returned. </li>
 * <li>If the given input is a Spannable, the same instance is returned. </li>
 * </ul>
 *
 * @param charSequence CharSequence to add the EmojiSpans, cannot be {@code null}
 * @param start start index in the charSequence to look for emojis, should be greater than or
 *              equal to {@code 0}, also less than {@code charSequence.length()}
 * @param end end index in the charSequence to look for emojis, should be greater than or
 *            equal to {@code start} parameter, also less than {@code charSequence.length()}
 * @param maxEmojiCount maximum number of emojis in the {@code charSequence}, should be greater
 *                      than or equal to {@code 0}
 * @param replaceAll whether to replace all emoji with {@link EmojiSpan}s
 */
CharSequence process(@NonNull final CharSequence charSequence, @IntRange(from = 0) int start,
        @IntRange(from = 0) int end, @IntRange(from = 0) int maxEmojiCount, final boolean replaceAll) {
    final boolean isSpannableBuilder = charSequence instanceof SpannableBuilder;
    if (isSpannableBuilder) {
        ((SpannableBuilder) charSequence).beginBatchEdit();
    }

    try {
        Spannable spannable = null;
        // if it is a spannable already, use the same instance to add/remove EmojiSpans.
        // otherwise wait until the the first EmojiSpan found in order to change the result
        // into a Spannable.
        if (isSpannableBuilder || charSequence instanceof Spannable) {
            spannable = (Spannable) charSequence;
        }

        if (spannable != null) {
            final EmojiSpan[] spans = spannable.getSpans(start, end, EmojiSpan.class);
            if (spans != null && spans.length > 0) {
                // remove existing spans, and realign the start, end according to spans
                // if start or end is in the middle of an emoji they should be aligned
                final int length = spans.length;
                for (int index = 0; index < length; index++) {
                    final EmojiSpan span = spans[index];
                    final int spanStart = spannable.getSpanStart(span);
                    final int spanEnd = spannable.getSpanEnd(span);
                    // Remove span only when its spanStart is NOT equal to current end.
                    // During add operation an emoji at index 0 is added with 0-1 as start and
                    // end indices. Therefore if there are emoji spans at [0-1] and [1-2]
                    // and end is 1, the span between 0-1 should be deleted, not 1-2.
                    if (spanStart != end) {
                        spannable.removeSpan(span);
                    }
                    start = Math.min(spanStart, start);
                    end = Math.max(spanEnd, end);
                }
            }
        }

        if (start == end || start >= charSequence.length()) {
            return charSequence;
        }

        // calculate max number of emojis that can be added. since getSpans call is a relatively
        // expensive operation, do it only when maxEmojiCount is not unlimited.
        if (maxEmojiCount != EmojiCompat.EMOJI_COUNT_UNLIMITED && spannable != null) {
            maxEmojiCount -= spannable.getSpans(0, spannable.length(), EmojiSpan.class).length;
        }
        // add new ones
        int addedCount = 0;
        final ProcessorSm sm = new ProcessorSm(mMetadataRepo.getRootNode());

        int currentOffset = start;
        int codePoint = Character.codePointAt(charSequence, currentOffset);

        while (currentOffset < end && addedCount < maxEmojiCount) {
            final int action = sm.check(codePoint);

            switch (action) {
            case ACTION_ADVANCE_BOTH:
                start += Character.charCount(Character.codePointAt(charSequence, start));
                currentOffset = start;
                if (currentOffset < end) {
                    codePoint = Character.codePointAt(charSequence, currentOffset);
                }
                break;
            case ACTION_ADVANCE_END:
                currentOffset += Character.charCount(codePoint);
                if (currentOffset < end) {
                    codePoint = Character.codePointAt(charSequence, currentOffset);
                }
                break;
            case ACTION_FLUSH:
                if (replaceAll || !hasGlyph(charSequence, start, currentOffset, sm.getFlushMetadata())) {
                    if (spannable == null) {
                        spannable = new SpannableString(charSequence);
                    }
                    addEmoji(spannable, sm.getFlushMetadata(), start, currentOffset);
                    addedCount++;
                }
                start = currentOffset;
                break;
            }
        }

        // After the last codepoint is consumed the state machine might be in a state where it
        // identified an emoji before. i.e. abc[women-emoji] when the last codepoint is consumed
        // state machine is waiting to see if there is an emoji sequence (i.e. ZWJ).
        // Need to check if it is in such a state.
        if (sm.isInFlushableState() && addedCount < maxEmojiCount) {
            if (replaceAll || !hasGlyph(charSequence, start, currentOffset, sm.getCurrentMetadata())) {
                if (spannable == null) {
                    spannable = new SpannableString(charSequence);
                }
                addEmoji(spannable, sm.getCurrentMetadata(), start, currentOffset);
                addedCount++;
            }
        }
        return spannable == null ? charSequence : spannable;
    } finally {
        if (isSpannableBuilder) {
            ((SpannableBuilder) charSequence).endBatchEdit();
        }
    }
}

From source file:com.hippo.nimingban.ui.ListActivity.java

private Spanned fixURLSpan(Spanned spanned) {
    Spannable spannable;
    if (spanned instanceof Spannable) {
        spannable = (Spannable) spanned;
    } else {/*from www.  ja  va  2s  .  c om*/
        spannable = new SpannableString(spanned);
    }

    URLSpan[] urlSpans = spannable.getSpans(0, spanned.length(), URLSpan.class);
    if (urlSpans == null) {
        return spanned;
    }

    for (URLSpan urlSpan : urlSpans) {
        String url = urlSpan.getURL();
        if (TextUtils.isEmpty(url)) {
            spannable.removeSpan(urlSpan);
        }

        try {
            new URL(url);
        } catch (MalformedURLException e) {
            URL absoluteUrl;
            // It might be relative path
            try {
                // Use absolute url
                absoluteUrl = new URL(new URL(ACUrl.HOST), url);
                int start = spannable.getSpanStart(urlSpan);
                int end = spannable.getSpanEnd(urlSpan);
                spannable.removeSpan(urlSpan);
                spannable.setSpan(new URLSpan(absoluteUrl.toString()), start, end,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            } catch (MalformedURLException e1) {
                // Can't get url
                spannable.removeSpan(urlSpan);
            }
        }
    }

    return spannable;
}

From source file:org.proninyaroslav.libretorrent.fragments.DetailTorrentFragment.java

@Override
public void onShow(final AlertDialog dialog) {
    if (dialog == null) {
        return;//  ww  w .  j ava  2  s. c om
    }

    if (getFragmentManager().findFragmentByTag(TAG_ADD_TRACKERS_DIALOG) != null) {
        final TextInputEditText field = (TextInputEditText) dialog
                .findViewById(R.id.multiline_text_input_dialog);
        final TextInputLayout fieldLayout = (TextInputLayout) dialog
                .findViewById(R.id.layout_multiline_text_input_dialog);

        /* Dismiss error label if user has changed the text */
        if (field != null && fieldLayout != null) {
            field.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                    /* Nothing */
                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    fieldLayout.setErrorEnabled(false);
                    fieldLayout.setError(null);

                    /* Clear selection of invalid url */
                    Spannable text = field.getText();
                    ForegroundColorSpan[] errorSpans = text.getSpans(0, text.length(),
                            ForegroundColorSpan.class);
                    for (ForegroundColorSpan span : errorSpans) {
                        text.removeSpan(span);
                    }
                }

                @Override
                public void afterTextChanged(Editable s) {
                    /* Nothing */
                }
            });
        }

        /*
         * It is necessary in order to the dialog is not closed by
         * pressing add/replace button if the text checker gave a false result
         */
        Button addButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
        Button replaceButton = dialog.getButton(AlertDialog.BUTTON_NEGATIVE);

        addButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (field != null && fieldLayout != null) {
                    String text = field.getText().toString();
                    List<String> urls = Arrays.asList(text.split(Utils.getLineSeparator()));

                    if (checkEditTextField(urls, fieldLayout, field)) {
                        addTrackersRequest(new ArrayList<>(urls), false);

                        dialog.dismiss();
                    }
                }
            }
        });

        replaceButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (field != null && fieldLayout != null) {
                    String text = field.getText().toString();
                    List<String> urls = Arrays.asList(text.split(Utils.getLineSeparator()));

                    if (checkEditTextField(urls, fieldLayout, field)) {
                        addTrackersRequest(new ArrayList<>(urls), true);

                        dialog.dismiss();
                    }
                }
            }
        });

        /* Inserting links from the clipboard */
        String clipboard = Utils.getClipboard(activity.getApplicationContext());

        if (clipboard != null && field != null) {
            List<String> urls = Arrays.asList(clipboard.split(Utils.getLineSeparator()));
            ArrayList<String> validUrls = new ArrayList<>();

            for (String url : urls) {
                if (Utils.isValidTrackerUrl(url)) {
                    validUrls.add(url);
                }
            }

            field.setText(TextUtils.join(Utils.getLineSeparator(), validUrls));
        }

    } else if (getFragmentManager().findFragmentByTag(TAG_SPEED_LIMIT_DIALOG) != null) {
        TextInputEditText upload = (TextInputEditText) dialog.findViewById(R.id.upload_limit);
        TextInputEditText download = (TextInputEditText) dialog.findViewById(R.id.download_limit);

        if (upload != null && download != null) {
            int minSpeedLimit = 0;
            int maxSpeedLimit = Integer.MAX_VALUE;
            InputFilter[] filter = new InputFilter[] { new InputFilterMinMax(minSpeedLimit, maxSpeedLimit) };

            upload.setFilters(filter);
            if (TextUtils.isEmpty(upload.getText())) {
                upload.setText((uploadSpeedLimit != -1 ? Integer.toString(uploadSpeedLimit / 1024)
                        : Integer.toString(minSpeedLimit)));
            }

            download.setFilters(filter);
            if (TextUtils.isEmpty(download.getText())) {
                download.setText((downloadSpeedLimit != -1 ? Integer.toString(downloadSpeedLimit / 1024)
                        : Integer.toString(minSpeedLimit)));
            }
        }
    }
}

From source file:cgeo.geocaching.CacheDetailActivity.java

private static void fixTextColor(final Spannable spannable, final int backgroundColor) {
    final ForegroundColorSpan[] spans = spannable.getSpans(0, spannable.length(), ForegroundColorSpan.class);

    for (final ForegroundColorSpan span : spans) {
        if (ColorUtils.getContrastRatio(span.getForegroundColor(), backgroundColor) < CONTRAST_THRESHOLD) {
            final int start = spannable.getSpanStart(span);
            final int end = spannable.getSpanEnd(span);

            //  Assuming that backgroundColor can be either white or black,
            // this will set opposite background color (white for black and black for white)
            spannable.setSpan(new BackgroundColorSpan(backgroundColor ^ 0x00ffffff), start, end,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }/*from w  ww .  j ava 2  s . c  o  m*/
    }
}

From source file:com.android.ex.chips.RecipientEditTextView.java

/**
 * Instead of filtering on the entire contents of the edit box, this subclass method filters on the range from {@link Tokenizer#findTokenStart} to {@link #getSelectionEnd} if the length of that range meets or exceeds {@link #getThreshold} and makes sure that the range is not already a Chip.
 *///from   w w  w.j  av a  2s  .  com
@Override
protected void performFiltering(final CharSequence text, final int keyCode) {
    final boolean isCompletedToken = isCompletedToken(text);
    if (enoughToFilter() && !isCompletedToken) {
        final int end = getSelectionEnd();
        final int start = mTokenizer.findTokenStart(text, end);
        // If this is a RecipientChip, don't filter
        // on its contents.
        final Spannable span = getSpannable();
        final DrawableRecipientChip[] chips = span.getSpans(start, end, DrawableRecipientChip.class);
        if (chips != null && chips.length > 0)
            return;
    } else if (isCompletedToken)
        return;
    super.performFiltering(text, keyCode);
}

From source file:org.openintents.notepad.NoteEditor.java

@Override
protected void onResume() {
    super.onResume();
    if (DEBUG) {/*from   ww w. ja va 2s . com*/
        Log.d(TAG, "onResume");
    }

    if (DEBUG) {
        Log.d(TAG, "mDecrypted: " + mDecryptedText);
    }

    // Set auto-link on or off, based on the current setting.
    int autoLink = PreferenceActivity.getAutoLinkFromPreference(this);

    mText.setAutoLinkMask(autoLink);

    mEncrypted = 0;

    if (mState == STATE_EDIT || (mState == STATE_INSERT) || mState == STATE_EDIT_EXTERNAL_NOTE) {
        getNoteFromContentProvider();
    } else if (mState == STATE_EDIT_NOTE_FROM_SDCARD) {
        getNoteFromFile();
    }

    if (mEncrypted == 0 || mDecryptedText != null) {
        applyInsertText();
    }

    // Make sure that we don't use the link movement method.
    // Instead, we need a blend between the arrow key movement (for regular
    // navigation) and
    // the link movement (so the user can click on links).
    mText.setMovementMethod(new ArrowKeyMovementMethod() {
        public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
            // This block is copied and pasted from LinkMovementMethod's
            // onTouchEvent (without the part that actually changes the
            // selection).
            int action = event.getAction();

            if (action == MotionEvent.ACTION_UP) {
                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);

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

                if (link.length != 0) {
                    link[0].onClick(widget);
                    return true;
                }
            }

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

    setTheme(loadTheme());

    startupSearch();
}