use of android.text.style.ClickableSpan in project Signal-Android by WhisperSystems.
the class SignalPinReminderDialog method show.
public static void show(@NonNull Context context, @NonNull Launcher launcher, @NonNull Callback mainCallback) {
if (!SignalStore.kbsValues().hasPin()) {
throw new AssertionError("Must have a PIN!");
}
Log.i(TAG, "Showing PIN reminder dialog.");
AlertDialog dialog = new AlertDialog.Builder(context, ThemeUtil.isDarkTheme(context) ? R.style.Theme_Signal_AlertDialog_Dark_Cornered_ColoredAccent : R.style.Theme_Signal_AlertDialog_Light_Cornered_ColoredAccent).setView(R.layout.kbs_pin_reminder_view).setCancelable(false).setOnCancelListener(d -> RegistrationLockReminders.scheduleReminder(context, false)).create();
WindowManager windowManager = ServiceUtil.getWindowManager(context);
Display display = windowManager.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
dialog.show();
dialog.getWindow().setLayout((int) (metrics.widthPixels * .80), ViewGroup.LayoutParams.WRAP_CONTENT);
EditText pinEditText = (EditText) DialogCompat.requireViewById(dialog, R.id.pin);
TextView pinStatus = (TextView) DialogCompat.requireViewById(dialog, R.id.pin_status);
TextView reminder = (TextView) DialogCompat.requireViewById(dialog, R.id.reminder);
View skip = DialogCompat.requireViewById(dialog, R.id.skip);
View submit = DialogCompat.requireViewById(dialog, R.id.submit);
SpannableString reminderText = new SpannableString(context.getString(R.string.KbsReminderDialog__to_help_you_memorize_your_pin));
SpannableString forgotText = new SpannableString(context.getString(R.string.KbsReminderDialog__forgot_pin));
ViewUtil.focusAndShowKeyboard(pinEditText);
ViewCompat.setAutofillHints(pinEditText, HintConstants.AUTOFILL_HINT_PASSWORD);
switch(SignalStore.pinValues().getKeyboardType()) {
case NUMERIC:
pinEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
break;
case ALPHA_NUMERIC:
pinEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
break;
}
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(@NonNull View widget) {
dialog.dismiss();
launcher.launch(CreateKbsPinActivity.getIntentForPinChangeFromForgotPin(context), CreateKbsPinActivity.REQUEST_NEW_PIN);
}
};
forgotText.setSpan(clickableSpan, 0, forgotText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
reminder.setText(new SpannableStringBuilder(reminderText).append(" ").append(forgotText));
reminder.setMovementMethod(LinkMovementMethod.getInstance());
PinVerifier.Callback callback = getPinWatcherCallback(context, dialog, pinEditText, pinStatus, mainCallback);
PinVerifier verifier = new V2PinVerifier();
skip.setOnClickListener(v -> {
dialog.dismiss();
mainCallback.onReminderDismissed(callback.hadWrongGuess());
});
submit.setEnabled(false);
submit.setOnClickListener(v -> {
Editable pinEditable = pinEditText.getText();
verifier.verifyPin(pinEditable == null ? null : pinEditable.toString(), callback);
});
pinEditText.addTextChangedListener(new SimpleTextWatcher() {
private final String localHash = Objects.requireNonNull(SignalStore.kbsValues().getLocalPinHash());
@Override
public void onTextChanged(String text) {
if (text.length() >= KbsConstants.MINIMUM_PIN_LENGTH) {
submit.setEnabled(true);
if (PinHashing.verifyLocalPinHash(localHash, text)) {
dialog.dismiss();
mainCallback.onReminderCompleted(text, callback.hadWrongGuess());
}
} else {
submit.setEnabled(false);
}
}
});
}
use of android.text.style.ClickableSpan in project Signal-Android by WhisperSystems.
the class GroupDescriptionUtil method setText.
/**
* Set a group description.
*
* @param description full description
* @param emojiTextView Text view to update with description
* @param linkify flag indicating if web urls should be linkified
* @param moreClick Callback for when truncating and need to show more via another means. Required to enable truncating.
*/
public static void setText(@NonNull Context context, @NonNull EmojiTextView emojiTextView, @NonNull String description, boolean linkify, @Nullable Runnable moreClick) {
boolean shouldEllipsize = moreClick != null;
String scrubbedDescription = shouldEllipsize ? description.replaceAll("\\n", " ") : description;
SpannableString descriptionSpannable = new SpannableString(scrubbedDescription);
if (linkify) {
int linkPattern = Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS;
boolean hasLinks = LinkifyCompat.addLinks(descriptionSpannable, linkPattern);
if (hasLinks) {
Stream.of(descriptionSpannable.getSpans(0, descriptionSpannable.length(), URLSpan.class)).filterNot(url -> LinkPreviewUtil.isLegalUrl(url.getURL())).forEach(descriptionSpannable::removeSpan);
URLSpan[] urlSpans = descriptionSpannable.getSpans(0, descriptionSpannable.length(), URLSpan.class);
for (URLSpan urlSpan : urlSpans) {
int start = descriptionSpannable.getSpanStart(urlSpan);
int end = descriptionSpannable.getSpanEnd(urlSpan);
URLSpan span = new LongClickCopySpan(urlSpan.getURL());
descriptionSpannable.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
if (shouldEllipsize) {
ClickableSpan style = new ClickableSpan() {
@Override
public void onClick(@NonNull View widget) {
moreClick.run();
}
@Override
public void updateDrawState(@NonNull TextPaint ds) {
ds.setTypeface(Typeface.DEFAULT_BOLD);
}
};
emojiTextView.setEllipsize(TextUtils.TruncateAt.END);
emojiTextView.setMaxLines(2);
SpannableString overflowText = new SpannableString(context.getString(R.string.ManageGroupActivity_more));
overflowText.setSpan(style, 0, overflowText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
emojiTextView.setOverflowText(overflowText);
}
emojiTextView.setText(descriptionSpannable);
}
use of android.text.style.ClickableSpan in project Douya by DreaminginCodeZH.
the class ClickableMovementMethod method onTouchEvent.
@Override
public boolean onTouchEvent(@NonNull TextView widget, @Nullable Spannable buffer, @NonNull MotionEvent event) {
int action = event.getActionMasked();
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);
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link.length > 0) {
if (action == MotionEvent.ACTION_UP) {
link[0].onClick(widget);
} else {
Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0]));
}
return true;
} else {
Selection.removeSelection(buffer);
}
}
return false;
}
use of android.text.style.ClickableSpan in project IITB-App by wncc.
the class EventFragment method inflateViews.
private void inflateViews(final Event event) {
if (getActivity() == null || getView() == null)
return;
eventPicture = (ImageView) getActivity().findViewById(R.id.event_picture_2);
final TextView eventTitle = (TextView) getActivity().findViewById(R.id.event_page_title);
final TextView eventDate = (TextView) getActivity().findViewById(R.id.event_page_date);
final TextView eventDescription = (TextView) getActivity().findViewById(R.id.event_page_description);
goingButton = getActivity().findViewById(R.id.going_button);
interestedButton = getActivity().findViewById(R.id.interested_button);
final ImageButton navigateButton = getActivity().findViewById(R.id.navigate_button);
final ImageButton webEventButton = getActivity().findViewById(R.id.web_event_button);
final ImageButton shareEventButton = getActivity().findViewById(R.id.share_event_button);
if (event.isEventBigImage() || !creatingView) {
Picasso.get().load(event.getEventImageURL()).into(eventPicture);
} else {
Picasso.get().load(Utils.resizeImageUrl(event.getEventImageURL())).into(eventPicture);
}
eventTitle.setText(event.getEventName());
Timestamp timestamp = event.getEventStartTime();
Date Date = new Date(timestamp.getTime());
SimpleDateFormat simpleDateFormatDate = new SimpleDateFormat("dd MMM");
SimpleDateFormat simpleDateFormatTime = new SimpleDateFormat("HH:mm");
// Check for minimal event
if (event.getEventDescription() == null) {
refreshEvent(event);
return;
}
Utils.getMarkwon().setMarkdown(eventDescription, event.getEventDescription());
final List<CardInterface> cardList = new ArrayList<>(event.getEventOfferedAchievements());
cardList.addAll(event.getEventBodies());
final RecyclerView bodyRecyclerView = getActivity().findViewById(R.id.body_card_recycler_view);
GenericAdapter genericAdapter = new GenericAdapter(cardList, this);
bodyRecyclerView.setAdapter(genericAdapter);
bodyRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
// Common
final String timing = simpleDateFormatDate.format(Date) + " | " + simpleDateFormatTime.format(Date);
StringBuilder eventVenueName = new StringBuilder();
for (Venue venue : event.getEventVenues()) {
eventVenueName.append(", ").append(venue.getVenueShortName());
}
// Make the venues clickable
if (eventVenueName.length() > 0) {
// Get the whole string
SpannableString ss = new SpannableString(eventVenueName.toString().substring(2));
// Make each venue clickable
int i = 0;
for (final Venue venue : event.getEventVenues()) {
int length = venue.getVenueShortName().length();
ClickableSpan cs = new ClickableSpan() {
@Override
public void onClick(@NonNull View widget) {
MapFragment mapFragment = MapFragment.newInstance(MapFragment.getPassableName(venue.getVenueShortName()));
((MainActivity) getActivity()).updateFragment(mapFragment);
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
if (getActivity() == null || !isAdded())
return;
ds.setColor(getResources().getColor(R.color.primaryTextColor));
ds.setUnderlineText(false);
}
};
ss.setSpan(cs, i, i + length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
i += length + 2;
}
// Setup the text view
eventDate.setText(TextUtils.concat(timing + " | ", ss));
eventDate.setMovementMethod(LinkMovementMethod.getInstance());
} else {
eventDate.setText(TextUtils.concat(timing));
}
interestedButton.setOnClickListener(getInterestedButtonOnClickListener());
goingButton.setOnClickListener(getGoingButtonOnClickListener());
updateGoingInterestedButtonsAppearance(event.getEventUserUes());
if (!event.getEventVenues().isEmpty()) {
if (event.getEventVenues().get(0).getVenueLatitude() == 0) {
navigateButton.setVisibility(View.GONE);
} else {
navigateButton.setOnClickListener(v -> {
Venue primaryVenue = event.getEventVenues().get(0);
Uri gmmIntentUri = Uri.parse("google.navigation:q=" + primaryVenue.getVenueLatitude() + "," + primaryVenue.getVenueLongitude() + "(" + primaryVenue.getVenueName() + ")");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
startActivity(mapIntent);
});
}
} else {
navigateButton.setVisibility(View.GONE);
}
shareEventButton.setOnClickListener(new View.OnClickListener() {
String shareUrl = ShareURLMaker.getEventURL(event);
@Override
public void onClick(View view) {
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("text/plain");
i.putExtra(Intent.EXTRA_SUBJECT, "Sharing URL");
i.putExtra(Intent.EXTRA_TEXT, shareUrl);
startActivity(Intent.createChooser(i, "Share URL"));
}
});
if (event.getEventWebsiteURL() != null && !event.getEventWebsiteURL().isEmpty()) {
webEventButton.setVisibility(View.VISIBLE);
webEventButton.setOnClickListener(new View.OnClickListener() {
String eventwebURL = event.getEventWebsiteURL();
@Override
public void onClick(View view) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(eventwebURL));
startActivity(browserIntent);
}
});
}
eventPicture.setOnClickListener(v -> zoomImageFromThumb(eventPicture));
mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime);
final FloatingActionButton fab = getView().findViewById(R.id.edit_fab);
if (((MainActivity) getActivity()).editEventAccess(event)) {
fab.show();
NestedScrollView nsv = getView().findViewById(R.id.event_scrollview);
nsv.setOnScrollChangeListener((NestedScrollView.OnScrollChangeListener) (v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
if (scrollY > oldScrollY)
fab.hide();
else
fab.show();
});
}
fab.setOnClickListener(v -> {
WebViewFragment webViewFragment = new WebViewFragment();
Bundle bundle = new Bundle();
bundle.putString(Constants.WV_TYPE, Constants.WV_TYPE_UPDATE_EVENT);
bundle.putString(Constants.WV_ID, event.getEventID());
webViewFragment.setArguments(bundle);
((MainActivity) getActivity()).updateFragment(webViewFragment);
});
}
use of android.text.style.ClickableSpan in project IITB-App by wncc.
the class MapFragment method setSubHeading.
private void setSubHeading(Marker marker) {
SpannableStringBuilder result = new SpannableStringBuilder("");
result.append(marker.getName());
if (marker instanceof Room) {
Room room = (Room) marker;
String tag = room.tag;
if (!"Inside".equals(tag)) {
tag += ",";
} else {
tag = "in";
}
Marker parent = data.get(room.parentKey);
final String parentKey = parent.getName();
String parentName = parent.getName();
if (!parent.getShortName().equals("0"))
parentName = parent.getShortName();
result.append(" - " + tag + " ");
int start = result.length();
result.append(parentName);
int end = result.length();
result.append(" ");
ClickableSpan parentSpan = new ClickableSpan() {
@Override
public void onClick(View widget) {
editText.setText(parentKey);
dismissCard();
displayMap();
}
@Override
public void updateDrawState(TextPaint p) {
p.setColor(Color.rgb(19, 140, 190));
p.setUnderlineText(true);
}
};
result.setSpan(parentSpan, start, end, SpannableStringBuilder.SPAN_INCLUSIVE_INCLUSIVE);
ClickableSpan restSpan1 = new ClickableSpan() {
private TextPaint ds;
@Override
public void onClick(View widget) {
updateDrawState(ds);
widget.invalidate();
// newCardTouchListener.toggleExpansion();
}
@Override
public void updateDrawState(TextPaint ds) {
ds.bgColor = Color.TRANSPARENT;
ds.setUnderlineText(false);
this.ds = ds;
}
};
ClickableSpan restSpan2 = new ClickableSpan() {
private TextPaint ds;
@Override
public void onClick(View widget) {
updateDrawState(ds);
widget.invalidate();
// newCardTouchListener.toggleExpansion();
}
@Override
public void updateDrawState(TextPaint ds) {
ds.bgColor = Color.TRANSPARENT;
ds.setUnderlineText(false);
this.ds = ds;
}
};
result.setSpan(restSpan1, 0, start, SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE);
result.setSpan(restSpan2, end, end + 1, SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE);
placeSubHeadTextView.setMovementMethod(LinkMovementMethod.getInstance());
// placeSubHeadTextView.setHighlightColor(Color.TRANSPARENT);
placeSubHeadTextView.setOnClickListener(null);
} else {
placeSubHeadTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// newCardTouchListener.toggleExpansion();
}
});
}
placeSubHeadTextView.setText(result);
}
Aggregations