2015-07-27 1 views
6

Есть ли способ включить TextView для обнаружения меток разметки и визуализации текста соответственно? Более конкретно, мое приложение содержит TextView, в котором пользователи могут предоставить описание, и часто они будут использовать уценку для форматирования их описания. К сожалению, текст не отображается, и вместо этого мы видим все теги, выписанные в textview.Поддержка Markdown в Android TextView

+0

Не могли бы вы добавить некоторые из ваших кодов. Это поможет нам обнаружить проблему, и вы, скорее всего, получите ответ – Typoheads

+0

http://uncodin.github.io/bypass/, хотя на данный момент он не поддерживается сборкой градиентов, я боюсь, потому что это «апклиб», , –

ответ

4

Я собираюсь предположить, что вы имеете в виду Markdown.

Нет встроенной поддержки Markdown в Android SDK. Вам придется использовать lib, например markdown4j или CommonMark.

1

Взгляните на библиотеку commonmark-java. Я не пробовал это сам, но я думаю, вы могли бы заставить его работать в вашем случае

-2

Если вы хотите сделать HTML, вы можете использовать Html.fromHtml("your string"), для большего количества ресурсов на нитях в Android проверить это link

4

Там нет поддержки унаследует для уценки в TextView, однако, если вам нужна только простая уценку облегченной реализация через простое «регулярное выражение», этот раздел из моего «load readme из корневой папки проекта» в https://github.com/mofosyne/instantReadmeApp поможет.

Обратите внимание, что это не удаляет разметку в тексте, только стилирует линии по-разному. Это может быть хорошим или плохим, в зависимости от вашего приложения.

О, и хорошая вещь? Он стирается в собственном текстовом виде, поэтому текст по-прежнему можно выбрать, как обычный текст.

Конкретно эта линия: https://github.com/mofosyne/instantReadmeApp/blob/master/app/src/main/java/com/github/mofosyne/instantreadme/ReadMe.java#L137

слегка модифицирована ниже: private void updateMainDisplay(String text) к private void style_psudomarkdown_TextView(String text, TextView textview_input), так что вы можете использовать ту же функцию для различных TextViews

`` `

/* 
    Text Styler 
    A crappy psudo markdown styler. Could do with a total revamp. 
*/ 

/* 
* Styling the textview for easier readability 
* */ 
private void style_psudomarkdown_TextView(String text, TextView textview_input) { 
    //TextView mTextView = (TextView) findViewById(R.id.readme_info); 
    TextView mTextView = textview_input; 

    // Let's update the main display 
    // Needs to set as spannable otherwise http://stackoverflow.com/questions/16340681/fatal-exception-string-cant-be-cast-to-spannable 
    mTextView.setText(text, TextView.BufferType.SPANNABLE); 
    // Let's prettify it! 
    changeLineinView_TITLESTYLE(mTextView, "# ", 0xfff4585d, 2f); // Primary Header 
    changeLineinView(mTextView, "\n# ", 0xFFF4A158, 1.5f); // Secondary Header 
    changeLineinView(mTextView, "\n## ", 0xFFF4A158, 1.2f); // Secondary Header 
    changeLineinView(mTextView, "\n---", 0xFFF4A158, 1.2f); // Horizontal Rule 
    changeLineinView(mTextView, "\n>", 0xFF89e24d, 0.9f); // Block Quotes 
    changeLineinView(mTextView, "\n - ", 0xFFA74DE3, 1f); // Classic Markdown List 
    changeLineinView(mTextView, "\n- ", 0xFFA74DE3, 1f); // NonStandard List 

    //spanSetterInView(String startTarget, String endTarget, int typefaceStyle, String fontFamily,TextView tv, int colour, float size) 
    // Limitation of spanSetterInView. Well its not a regular expression... so can't exactly have * list, and *bold* at the same time. 
    spanSetterInView(mTextView, "\n```\n", "\n```\n", Typeface.BOLD,  "monospace", 0xFF45c152, 0.8f, false); // fenced code Blocks (endAtLineBreak=false since this is a multiline block operator) 
    spanSetterInView(mTextView, " **" ,  "** ", Typeface.BOLD,  "", 0xFF89e24d, 1f, true); // Bolding 
    spanSetterInView(mTextView, " *" ,  "* ", Typeface.ITALIC,  "", 0xFF4dd8e2, 1f, true); // Italic 
    spanSetterInView(mTextView, " ***" , "*** ", Typeface.BOLD_ITALIC, "", 0xFF4de25c, 1f, true); // Bold and Italic 
    spanSetterInView(mTextView, " `" ,  "` ", Typeface.BOLD,  "monospace", 0xFF45c152, 0.8f, true); // inline code 
    spanSetterInView(mTextView, "\n " ,  "\n", Typeface.BOLD,  "monospace", 0xFF45c152, 0.7f, true); // classic indented code 
} 

private void changeLineinView(TextView tv, String target, int colour, float size) { 
    String vString = (String) tv.getText().toString(); 
    int startSpan = 0, endSpan = 0; 
    //Spannable spanRange = new SpannableString(vString); 
    Spannable spanRange = (Spannable) tv.getText(); 
    while (true) { 
     startSpan = vString.indexOf(target, endSpan-1);  // ([email protected]#$%) I want to check a character behind in case it is a newline 
     endSpan = vString.indexOf("\n", startSpan+1);  // But at the same time, I do not want to read the point found by startSpan. This is since startSpan may point to a initial newline. 
     ForegroundColorSpan foreColour = new ForegroundColorSpan(colour); 
     // Need a NEW span object every loop, else it just moves the span 
     // Fix: -1 in startSpan or endSpan, indicates that the indexOf has already searched the entire string with not valid match (Lack of endspan check, occoured because of the inclusion of endTarget, which added extra complications) 
     if ((startSpan < 0) || (endSpan < 0)) break;// Need a NEW span object every loop, else it just moves the span 
     // Need to make sure that start range is always smaller than end range. (Solved! Refer to few lines above with ([email protected]#$%)) 
     if (endSpan > startSpan) { 
      //endSpan = startSpan + target.length(); 
      spanRange.setSpan(foreColour, startSpan, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
      // Also wannna bold the span too 
      spanRange.setSpan(new RelativeSizeSpan(size), startSpan, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
      spanRange.setSpan(new StyleSpan(Typeface.BOLD), startSpan, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
     } 
    } 
    tv.setText(spanRange); 
} 

private void changeLineinView_TITLESTYLE(TextView tv, String target, int colour, float size) { 
    String vString = (String) tv.getText().toString(); 
    int startSpan = 0, endSpan = 0; 
    //Spannable spanRange = new SpannableString(vString); 
    Spannable spanRange = (Spannable) tv.getText(); 
    /* 
    * Had to do this, since there is something wrong with this overlapping the "##" detection routine 
    * Plus you only really need one title. 
    */ 
    //while (true) { 
    startSpan = vString.substring(0,target.length()).indexOf(target, endSpan-1); //substring(target.length()) since we only want the first line 
    endSpan = vString.indexOf("\n", startSpan+1); 
    ForegroundColorSpan foreColour = new ForegroundColorSpan(colour); 
    // Need a NEW span object every loop, else it just moves the span 
     /* 
     if (startSpan < 0) 
      break; 
      */ 
    if (!(startSpan < 0)) { // hacky I know, but its to cater to the case where there is no header text 
     // Need to make sure that start range is always smaller than end range. 
     if (endSpan > startSpan) { 
      //endSpan = startSpan + target.length(); 
      spanRange.setSpan(foreColour, startSpan, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
      // Also wannna bold the span too 
      spanRange.setSpan(new RelativeSizeSpan(size), startSpan, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
      spanRange.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), startSpan, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
     } 
    } 
    //} 
    tv.setText(spanRange); 
} 


private void spanSetterInView(TextView tv, String startTarget, String endTarget, int typefaceStyle, String fontFamily, int colour, float size, boolean endAtLineBreak) { 
    String vString = (String) tv.getText().toString(); 
    int startSpan = 0, endSpan = 0; 
    //Spannable spanRange = new SpannableString(vString); 
    Spannable spanRange = (Spannable) tv.getText(); 
    while (true) { 
     startSpan = vString.indexOf(startTarget, endSpan-1);  // ([email protected]#$%) I want to check a character behind in case it is a newline 
     endSpan = vString.indexOf(endTarget, startSpan+1+startTarget.length());  // But at the same time, I do not want to read the point found by startSpan. This is since startSpan may point to a initial newline. We also need to avoid the first patten matching a token from the second pattern. 
     // Since this is pretty powerful, we really want to avoid overmatching it, and limit any problems to a single line. Especially if people forget to type in the closing symbol (e.g. * in bold) 
     if (endAtLineBreak){ 
      int endSpan_linebreak = vString.indexOf("\n", startSpan+1+startTarget.length()); 
      if (endSpan_linebreak < endSpan) { endSpan = endSpan_linebreak; } 
     } 
     // Fix: -1 in startSpan or endSpan, indicates that the indexOf has already searched the entire string with not valid match (Lack of endspan check, occoured because of the inclusion of endTarget, which added extra complications) 
     if ((startSpan < 0) || (endSpan < 0)) break;// Need a NEW span object every loop, else it just moves the span 
     // We want to also include the end "** " characters 
     endSpan += endTarget.length(); 
     // If all is well, we shall set the styles and etc... 
     if (endSpan > startSpan) {// Need to make sure that start range is always smaller than end range. (Solved! Refer to few lines above with ([email protected]#$%)) 
      spanRange.setSpan(new ForegroundColorSpan(colour), startSpan, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
      spanRange.setSpan(new RelativeSizeSpan(size), startSpan, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
      spanRange.setSpan(new StyleSpan(typefaceStyle), startSpan, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
      // Default to normal font family if settings is empty 
      if(!fontFamily.equals("")) spanRange.setSpan(new TypefaceSpan(fontFamily), startSpan, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
     } 
    } 
    tv.setText(spanRange); 
} 

` ``

Вышеупомянутая реализация поддерживает только до 2 заголовков (но вы можете легко изменить регулярное выражение для поддержки более двух уровней заголовков).

Это серия на основе текстового вида регулярных выражений, состоящая из двух функций для регулярных выражений, который соответствует всегда линии changeLineinView() и changeLineinView_TITLESTYLE()

многострочной остовному spanSetterInView() функция сделки с ним.

Таким образом, расширение его в соответствии с вашими потребностями, если у вас есть регулярное выражение, которое не противоречит никакому другому синтаксису.

Markdownish Синтаксис:

Это поддерживается синтаксис. Невозможно поддерживать полную уценку, поскольку это всего лишь небольшая взломанная реализация. Но любезно удобно для без излишеств, который легко набирать на клавиатуре мобильного телефона.

# H1 only in first line (Due to technical hacks used) 

## H2 headers as usual 

## Styling 
Like: *italic* **bold** ***bold_italic*** 

## Classic List 
- list item 1 
- list item 2 

## Nonstandard List Syntax 
- list item 1 
- list item 2 

## Block Quotes 
> Quoted stuff 

## codes 
here is inline `literal` codes. Must have space around it. 

    ``` 
    codeblocks 
    Good for ascii art 
    ``` 

    Or 4 space code indent like classic markdown. 
1

Я понимаю, что вы хотите конвертировать String, содержащий Markdown разметку на отформатированную CharSequence, что вы можете использовать в TextView. Два варианта, которые я знаю о:

  • Bypass: Используйте собственную C-библиотеку для разбора текста. К сожалению, проект кажется мертвым.
  • commonmark-spannable-android: Чистая java, на основе очень хорошая библиотека commonmark-java .

Я использовал оба варианта, и, на мой взгляд, второй лучше: не нужно иметь дело с собственными архитектурами, меньшим APK, а производительность неплохая (примерно в 2 раза медленнее в моем случае, с более чем достаточно)

Update: Нашел еще один вариант (это один я использую сейчас):

  • Markwon: Pure Java, а также с помощью commonmark-Java, как синтаксический анализатор, с опциональной поддержкой изображений и таблиц
+0

Кто-нибудь это предоставляет настройки? как в цвет шрифта всех атрибутов и т. д.? – ShahrozKhan91

+0

Markwon позволяет [довольно много настроек] (https://github.com/noties/Markwon/blob/master/docs/SpannableTheme.md). – bwt

+0

Привет @bwt, я пытаюсь библиотеки Markwon в своем приложении, но я застрял с частью обработки ссылок. Мне интересно, как получить текст ссылки для дальнейшего форматирования. Есть ли место, где я могу получить дополнительную информацию об использовании библиотеки Markwon? Буду признателен за любую оказанную помощь. – JoeYo

1

Я могу порекомендовать MarkdownView. Я использую его для загрузки файлов разметки из папки с ресурсами.

Смежные вопросы