From ee4f4ff324e62319eb27f5160a86469dc11502f5 Mon Sep 17 00:00:00 2001 From: Nail Shaykhraziev <33224810+nailshaykhraziev@users.noreply.github.com> Date: Thu, 22 Jul 2021 19:13:58 +0300 Subject: [PATCH] Feature/link renderer (#1) * Rename .java to .kt * Add parsing links inside of block * Add colored url spannable --- .../contentful/rich/android/AndroidConfig.kt | 2 + .../android/renderer/views/BlockRenderer.java | 65 ---- .../android/renderer/views/BlockRenderer.kt | 87 +++++ .../renderer/views/EmbeddedLinkRenderer.java | 74 +++-- .../renderer/views/HyperLinkRenderer.java | 54 ++-- .../android/renderer/views/span/UrlSpan.kt | 18 ++ .../contentful/rich/android/sample/Page.kt | 300 ++++++++++-------- .../rich/android/sample/PageAdapter.kt | 7 +- .../android/sample/RichCharSequenceAdapter.kt | 67 ++-- .../android/sample/RichNativeViewAdapter.kt | 55 ++-- 10 files changed, 406 insertions(+), 323 deletions(-) delete mode 100644 android/src/main/java/com/contentful/rich/android/renderer/views/BlockRenderer.java create mode 100644 android/src/main/java/com/contentful/rich/android/renderer/views/BlockRenderer.kt create mode 100644 android/src/main/java/com/contentful/rich/android/renderer/views/span/UrlSpan.kt diff --git a/android/src/main/java/com/contentful/rich/android/AndroidConfig.kt b/android/src/main/java/com/contentful/rich/android/AndroidConfig.kt index e06a735..43e2dfc 100644 --- a/android/src/main/java/com/contentful/rich/android/AndroidConfig.kt +++ b/android/src/main/java/com/contentful/rich/android/AndroidConfig.kt @@ -1,10 +1,12 @@ package com.contentful.rich.android +import androidx.annotation.ColorInt import androidx.annotation.ColorRes import androidx.annotation.FontRes data class AndroidConfig( @ColorRes val textColor: Int = android.R.color.black, + @ColorInt val linkColor: Int? = null, @FontRes val font: Int? = null, val textSizeMultiplier: Float = 0.75f, val marginTop: Int = 0 diff --git a/android/src/main/java/com/contentful/rich/android/renderer/views/BlockRenderer.java b/android/src/main/java/com/contentful/rich/android/renderer/views/BlockRenderer.java deleted file mode 100644 index f599c96..0000000 --- a/android/src/main/java/com/contentful/rich/android/renderer/views/BlockRenderer.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.contentful.rich.android.renderer.views; - -import android.text.SpannableStringBuilder; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.contentful.java.cda.rich.CDARichBlock; -import com.contentful.java.cda.rich.CDARichNode; -import com.contentful.rich.android.AndroidContext; -import com.contentful.rich.android.AndroidProcessor; -import com.contentful.rich.android.AndroidRenderer; -import com.contentful.rich.android.R; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -public class BlockRenderer extends AndroidRenderer { - public BlockRenderer(@Nonnull AndroidProcessor processor) { - super(processor); - } - - @Override public boolean canRender(@Nullable AndroidContext context, @Nonnull CDARichNode node) { - return node instanceof CDARichBlock; - } - - @Nullable @Override public View render(@Nonnull AndroidContext context, @Nonnull CDARichNode node) { - final CDARichBlock block = (CDARichBlock) node; - final View result = inflateRichLayout(context, node); - final ViewGroup content = result.findViewById(R.id.rich_content); - - TextView lastTextView = null; - for (final CDARichNode childNode : block.getContent()) { - final View childView = processor.process(context, childNode); - - if (childView != null) { - if (childView instanceof TextView) { - final TextView childTextView = (TextView) childView; - if (lastTextView != null) { - lastTextView.setText( - new SpannableStringBuilder(lastTextView.getText()).append(childTextView.getText()) - ); - } else { - lastTextView = childTextView; - content.addView(childView); - } - } else { - if (context.getPath() != null && context.getPath().size() > 1) { - final View indented = context.getInflater().inflate(R.layout.rich_indention_layout, null, false); - ((ViewGroup) indented.findViewById(R.id.rich_content)).addView(childView); - content.addView(indented); - } else { - content.addView(childView); - } - } - } - } - - return result; - } - - protected View inflateRichLayout(@Nonnull AndroidContext context, @Nonnull CDARichNode node) { - return context.getInflater().inflate(R.layout.rich_block_layout, null, false); - } -} diff --git a/android/src/main/java/com/contentful/rich/android/renderer/views/BlockRenderer.kt b/android/src/main/java/com/contentful/rich/android/renderer/views/BlockRenderer.kt new file mode 100644 index 0000000..fcfa0e5 --- /dev/null +++ b/android/src/main/java/com/contentful/rich/android/renderer/views/BlockRenderer.kt @@ -0,0 +1,87 @@ +package com.contentful.rich.android.renderer.views + +import android.text.SpannableStringBuilder +import android.text.Spanned +import android.text.method.LinkMovementMethod +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import com.contentful.java.cda.rich.CDARichBlock +import com.contentful.java.cda.rich.CDARichHyperLink +import com.contentful.java.cda.rich.CDARichNode +import com.contentful.rich.android.AndroidContext +import com.contentful.rich.android.AndroidProcessor +import com.contentful.rich.android.AndroidRenderer +import com.contentful.rich.android.R +import com.contentful.rich.android.renderer.views.span.UrlSpan + +open class BlockRenderer( + processor: AndroidProcessor +) : AndroidRenderer(processor) { + + override fun canRender(context: AndroidContext?, node: CDARichNode): Boolean = node is CDARichBlock + + override fun render(context: AndroidContext, node: CDARichNode): View? { + val block = node as CDARichBlock + val result = inflateRichLayout(context, node) + val content = result.findViewById(R.id.rich_content) + var lastTextView: TextView? = null + block.content.forEach { childNode -> + val childView = processor.process(context, childNode!!) + if (childView != null) { + when { + childView is TextView -> { + lastTextView?.let { + it.text = SpannableStringBuilder(it.text).append(" ").append(childView.text) + } ?: run { + lastTextView = childView + content.addView(childView) + } + } + childNode is CDARichHyperLink -> { + val childLayout = childView.findViewById(R.id.rich_content) + if (childLayout.childCount > 0) { + val childTextView = childLayout.getChildAt(0) as TextView + val span = UrlSpan(childNode.data as String) + val text = lastTextView?.let { + SpannableStringBuilder(it.text).append(" ").append(childTextView.text) + } ?: SpannableStringBuilder(childTextView.text) + + context.config?.linkColor?.let { + span.textColor = it + } + + text.setSpan( + span, + lastTextView?.text?.length?.plus(1) ?: 0, + text.length, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + + lastTextView?.let { + it.movementMethod = LinkMovementMethod.getInstance() + it.text = text + } ?: run { + childTextView.text = text + lastTextView = childTextView + content.addView(childView) + } + } + } + context.path?.size ?: 0 > 1 -> { + val indented = context.inflater.inflate(R.layout.rich_indention_layout, null, false) + (indented.findViewById(R.id.rich_content) as ViewGroup).addView(childView) + content.addView(indented) + } + else -> content.addView(childView) + } + } + } + return result + } + + protected open fun inflateRichLayout( + context: AndroidContext, + node: CDARichNode + ): View = context.inflater.inflate(R.layout.rich_block_layout, null, false) +} diff --git a/android/src/main/java/com/contentful/rich/android/renderer/views/EmbeddedLinkRenderer.java b/android/src/main/java/com/contentful/rich/android/renderer/views/EmbeddedLinkRenderer.java index dc088fa..fc3c61e 100644 --- a/android/src/main/java/com/contentful/rich/android/renderer/views/EmbeddedLinkRenderer.java +++ b/android/src/main/java/com/contentful/rich/android/renderer/views/EmbeddedLinkRenderer.java @@ -20,50 +20,54 @@ import static com.contentful.rich.android.renderer.chars.EmbeddedLinkRenderer.defaultBitmapProvider; public class EmbeddedLinkRenderer extends BlockRenderer { - private final BitmapProvider provider; - public EmbeddedLinkRenderer(@Nonnull AndroidProcessor processor) { - this(processor, defaultBitmapProvider); - } + private final BitmapProvider provider; - public EmbeddedLinkRenderer(@Nonnull AndroidProcessor processor, BitmapProvider provider) { - super(processor); - this.provider = provider; - } + public EmbeddedLinkRenderer(@Nonnull AndroidProcessor processor) { + this(processor, defaultBitmapProvider); + } + + public EmbeddedLinkRenderer(@Nonnull AndroidProcessor processor, BitmapProvider provider) { + super(processor); + this.provider = provider; + } - @Override public boolean canRender(@Nullable AndroidContext context, @Nonnull CDARichNode node) { - return node instanceof CDARichEmbeddedInline; - } + @Override + public boolean canRender(@Nullable AndroidContext context, @Nonnull CDARichNode node) { + return node instanceof CDARichEmbeddedInline; + } - @Override protected View inflateRichLayout(@Nonnull AndroidContext context, @Nonnull CDARichNode node) { - final View embedded = context.getInflater().inflate(R.layout.rich_embedded_layout, null, false); - final ViewGroup content = embedded.findViewById(R.id.rich_content); + @Nonnull + @Override + protected View inflateRichLayout(@Nonnull AndroidContext context, @Nonnull CDARichNode node) { + final View embedded = context.getInflater().inflate(R.layout.rich_embedded_layout, null, false); + final ViewGroup content = embedded.findViewById(R.id.rich_content); - final CDARichEmbeddedInline link = (CDARichEmbeddedInline) node; - final Object data = link.getData(); + final CDARichEmbeddedInline link = (CDARichEmbeddedInline) node; + final Object data = link.getData(); - final View toBeEmbedded; - if (data instanceof CDAEntry) { - final CDAEntry entry = (CDAEntry) data; + final View toBeEmbedded; + if (data instanceof CDAEntry) { + final CDAEntry entry = (CDAEntry) data; - final TextView textView = new TextView(context.getAndroidContext()); - textView.setText(entry.getField("title")); + final TextView textView = new TextView(context.getAndroidContext()); + textView.setText(entry.getField("title")); - toBeEmbedded = textView; - } else if (data instanceof CDAAsset) { - final CDAAsset asset = (CDAAsset) data; - final ImageView image = new ImageView(context.getAndroidContext()); - image.setImageBitmap(provider.provide(context.getAndroidContext(), asset)); + toBeEmbedded = textView; + } else if (data instanceof CDAAsset) { + final CDAAsset asset = (CDAAsset) data; + final ImageView image = new ImageView(context.getAndroidContext()); + image.setImageBitmap(provider.provide(context.getAndroidContext(), asset)); - toBeEmbedded = image; - } else { - final TextView textView = new TextView(context.getAndroidContext()); - textView.setText("⚠️"); + toBeEmbedded = image; + } else { + final TextView textView = new TextView(context.getAndroidContext()); + textView.setText("⚠️"); - toBeEmbedded = textView; - } + toBeEmbedded = textView; + } - content.addView(toBeEmbedded, 0); - return embedded; - } + content.addView(toBeEmbedded, 0); + return embedded; + } } diff --git a/android/src/main/java/com/contentful/rich/android/renderer/views/HyperLinkRenderer.java b/android/src/main/java/com/contentful/rich/android/renderer/views/HyperLinkRenderer.java index db40e80..d460b53 100644 --- a/android/src/main/java/com/contentful/rich/android/renderer/views/HyperLinkRenderer.java +++ b/android/src/main/java/com/contentful/rich/android/renderer/views/HyperLinkRenderer.java @@ -18,30 +18,34 @@ import javax.annotation.Nullable; public class HyperLinkRenderer extends BlockRenderer { - public HyperLinkRenderer(@Nonnull AndroidProcessor processor) { - super(processor); - } - - @Override public boolean canRender(@Nullable AndroidContext context, @Nonnull CDARichNode node) { - return node instanceof CDARichHyperLink && ((CDARichHyperLink) node).getData() instanceof String; - } - - @Override protected View inflateRichLayout(@Nonnull AndroidContext context, @Nonnull CDARichNode node) { - final View inflate = context.getInflater().inflate(R.layout.rich_hyperlink_layout, null, false); - inflate.setOnClickListener(v -> HyperLinkRenderer.this.onClick(context, node)); - return inflate; - } - - public void onClick(AndroidContext context, CDARichNode node) { - final Context androidContext = context.getAndroidContext(); - final Uri uri = Uri.parse((String) ((CDARichHyperLink) node).getData()); - - final Intent intent = new Intent(Intent.ACTION_VIEW, uri); - intent.putExtra(Browser.EXTRA_APPLICATION_ID, androidContext.getPackageName()); - try { - androidContext.startActivity(intent); - } catch (ActivityNotFoundException e) { - Log.w("URLSpan", "Activity was not found for intent, " + intent.toString()); + + public HyperLinkRenderer(@Nonnull AndroidProcessor processor) { + super(processor); + } + + @Override + public boolean canRender(@Nullable AndroidContext context, @Nonnull CDARichNode node) { + return node instanceof CDARichHyperLink && ((CDARichHyperLink) node).getData() instanceof String; + } + + @Nonnull + @Override + protected View inflateRichLayout(@Nonnull AndroidContext context, @Nonnull CDARichNode node) { + final View inflate = context.getInflater().inflate(R.layout.rich_block_layout, null, false); + inflate.setOnClickListener(v -> HyperLinkRenderer.this.onClick(context, node)); + return inflate; + } + + public void onClick(AndroidContext context, CDARichNode node) { + final Context androidContext = context.getAndroidContext(); + final Uri uri = Uri.parse((String) ((CDARichHyperLink) node).getData()); + + final Intent intent = new Intent(Intent.ACTION_VIEW, uri); + intent.putExtra(Browser.EXTRA_APPLICATION_ID, androidContext.getPackageName()); + try { + androidContext.startActivity(intent); + } catch (ActivityNotFoundException e) { + Log.w("URLSpan", "Activity was not found for intent, " + intent.toString()); + } } - } } diff --git a/android/src/main/java/com/contentful/rich/android/renderer/views/span/UrlSpan.kt b/android/src/main/java/com/contentful/rich/android/renderer/views/span/UrlSpan.kt new file mode 100644 index 0000000..dea6994 --- /dev/null +++ b/android/src/main/java/com/contentful/rich/android/renderer/views/span/UrlSpan.kt @@ -0,0 +1,18 @@ +package com.contentful.rich.android.renderer.views.span + +import android.text.TextPaint +import android.text.style.URLSpan +import androidx.annotation.ColorInt + +class UrlSpan(url: String) : URLSpan(url) { + + @ColorInt + var textColor: Int? = null + + override fun updateDrawState(ds: TextPaint) { + textColor?.also { + ds.linkColor = it + } + super.updateDrawState(ds) + } +} diff --git a/android_sample/src/main/java/com/contentful/rich/android/sample/Page.kt b/android_sample/src/main/java/com/contentful/rich/android/sample/Page.kt index 558ba83..6dd8271 100644 --- a/android_sample/src/main/java/com/contentful/rich/android/sample/Page.kt +++ b/android_sample/src/main/java/com/contentful/rich/android/sample/Page.kt @@ -11,153 +11,173 @@ import java.lang.reflect.Field data class Page(val name: String, val document: CDARichDocument) val PAGES = mutableListOf( - Page(name = "Text with Marks", - document = CDARichDocument().addAll( - text("Normal Text"), - text("BoldText", listOf(CDARichMarkBold())), - text("Italic", listOf(CDARichMarkItalic())), - text("Underline", listOf(CDARichMarkUnderline())), - text("final String code;", listOf(CDARichMarkCode())), - text("CustomText", listOf(CDARichMarkCustom("custom"))), - CDARichHorizontalRule(), - text("All in all", - listOf( - CDARichMarkCustom("custom"), - CDARichMarkItalic(), - CDARichMarkBold(), - CDARichMarkCode(), - CDARichMarkUnderline() - ) - ) - ) - ), - Page(name = "Headings", - document = CDARichDocument().addAll( - *(1 until 7).map { - CDARichHeading(it).addAll(text("Heading level $it")) - }.toTypedArray() + Page( + name = "Text with Marks", + document = CDARichDocument().addAll( + text("Normal Text"), + text("BoldText", listOf(CDARichMarkBold())), + text("Italic", listOf(CDARichMarkItalic())), + text("Underline", listOf(CDARichMarkUnderline())), + text("final String code;", listOf(CDARichMarkCode())), + text("CustomText", listOf(CDARichMarkCustom("custom"))), + CDARichHorizontalRule(), + text( + "All in all", + listOf( + CDARichMarkCustom("custom"), + CDARichMarkItalic(), + CDARichMarkBold(), + CDARichMarkCode(), + CDARichMarkUnderline() ) - ), - Page(name = "Lists", - document = CDARichDocument().addAll( - CDARichOrderedList().addAll( - CDARichListItem().addAll(text("first item")), - CDARichListItem().addAll(text("second item")), - CDARichListItem().addAll(text("third item")) - ), - CDARichUnorderedList().addAll( - CDARichListItem().addAll(text("first item")), - CDARichListItem().addAll(text("second item")), - CDARichListItem().addAll(text("third item")) - ), - CDARichUnorderedList().addAll( - CDARichListItem().addAll(text("first item")), - CDARichListItem().addAll( - text("second item"), - CDARichOrderedList().addAll( - CDARichListItem().addAll(text("first nested item")), - CDARichListItem().addAll(text("second nested item")), - CDARichListItem().addAll(text("third nested item")) - ) - ), - CDARichListItem().addAll(text("third item")) - ), - CDARichOrderedList().addAll( - CDARichListItem().addAll(text("first item")), - CDARichListItem().addAll( - text("second item"), - CDARichUnorderedList().addAll( - CDARichListItem().addAll(text("first nested item")), - CDARichListItem().addAll(text("second nested item")), - CDARichListItem().addAll(text("third nested item")) - ) - ), - CDARichListItem().addAll(text("third item")) - ), - CDARichOrderedList().addAll( - CDARichListItem().addAll(text("first item")), - CDARichListItem().addAll( - text("second item"), - CDARichOrderedList().addAll( - CDARichListItem().addAll(text("first nested item")), - CDARichListItem().addAll(text("second nested item")), - CDARichListItem().addAll(text("third nested item")) - ) - ), - CDARichListItem().addAll(text("third item")) - ), - CDARichUnorderedList().addAll( - CDARichListItem().addAll(text("first item")), - CDARichListItem().addAll( - text("second item"), - CDARichOrderedList().addAll( - CDARichListItem().addAll(text("first nested item")), - CDARichListItem().addAll(text("second nested item")), - CDARichListItem().addAll(text("third nested item")) - ) - ), - CDARichListItem().addAll(text("third item")) - ), - CDARichList("1").addAll( - CDARichListItem().addAll(text("one")), - CDARichList("A").addAll( - CDARichListItem().addAll(text("two")), - CDARichList("a").addAll( - CDARichListItem().addAll(text("three")), - CDARichList("I").addAll( - CDARichListItem().addAll(text("four")) - ) - ) - ) - ), - CDARichUnorderedList().addAll( - CDARichListItem().addAll(text("one")), - CDARichUnorderedList().addAll( - CDARichListItem().addAll(text("two")), - CDARichUnorderedList().addAll( - CDARichListItem().addAll(text("three")), - CDARichUnorderedList().addAll( - CDARichListItem().addAll(text("four")) - ) - ) - ) + ) + ) + ), + Page( + name = "Headings", + document = CDARichDocument().addAll( + *(1 until 7).map { + CDARichHeading(it).addAll(text("Heading level $it")) + }.toTypedArray() + ) + ), + Page( + name = "Lists", + document = CDARichDocument().addAll( + CDARichOrderedList().addAll( + CDARichListItem().addAll(text("first item")), + CDARichListItem().addAll(text("second item")), + CDARichListItem().addAll(text("third item")) + ), + CDARichUnorderedList().addAll( + CDARichListItem().addAll(text("first item")), + CDARichListItem().addAll(text("second item")), + CDARichListItem().addAll(text("third item")) + ), + CDARichUnorderedList().addAll( + CDARichListItem().addAll(text("first item")), + CDARichListItem().addAll( + text("second item"), + CDARichOrderedList().addAll( + CDARichListItem().addAll(text("first nested item")), + CDARichListItem().addAll(text("second nested item")), + CDARichListItem().addAll(text("third nested item")) + ) + ), + CDARichListItem().addAll(text("third item")) + ), + CDARichOrderedList().addAll( + CDARichListItem().addAll(text("first item")), + CDARichListItem().addAll( + text("second item"), + CDARichUnorderedList().addAll( + CDARichListItem().addAll(text("first nested item")), + CDARichListItem().addAll(text("second nested item")), + CDARichListItem().addAll(text("third nested item")) + ) + ), + CDARichListItem().addAll(text("third item")) + ), + CDARichOrderedList().addAll( + CDARichListItem().addAll(text("first item")), + CDARichListItem().addAll( + text("second item"), + CDARichOrderedList().addAll( + CDARichListItem().addAll(text("first nested item")), + CDARichListItem().addAll(text("second nested item")), + CDARichListItem().addAll(text("third nested item")) + ) + ), + CDARichListItem().addAll(text("third item")) + ), + CDARichUnorderedList().addAll( + CDARichListItem().addAll(text("first item")), + CDARichListItem().addAll( + text("second item"), + CDARichOrderedList().addAll( + CDARichListItem().addAll(text("first nested item")), + CDARichListItem().addAll(text("second nested item")), + CDARichListItem().addAll(text("third nested item")) + ) + ), + CDARichListItem().addAll(text("third item")) + ), + CDARichList("1").addAll( + CDARichListItem().addAll(text("one")), + CDARichList("A").addAll( + CDARichListItem().addAll(text("two")), + CDARichList("a").addAll( + CDARichListItem().addAll(text("three")), + CDARichList("I").addAll( + CDARichListItem().addAll(text("four")) ) + ) ) - ), - Page(name = "Quotes", - document = CDARichDocument().addAll( - CDARichBlock().addAll( - text("Quotes from "), - text("Famous", listOf(CDARichMark.CDARichMarkBold())), - text(" People", listOf(CDARichMark.CDARichMarkItalic())) - ), - CDARichQuote().addAll( - text("You know you’re in love when you can’t fall asleep because reality is finally better than your dreams."), - text("- Dr. Suess", listOf(CDARichMark.CDARichMarkItalic())) - ), - CDARichQuote().addAll( - text("I’m selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can’t handle me at my worst, then you sure as hell don’t deserve me at my best."), - text("- Marilyn Monroe", listOf(CDARichMark.CDARichMarkItalic())) - ), - CDARichQuote().addAll( - text("Twenty years from now you will be more disappointed by the things that you didn’t do than by the ones you did do."), - text("- Mark Twain", listOf(CDARichMark.CDARichMarkItalic())) + ), + CDARichUnorderedList().addAll( + CDARichListItem().addAll(text("one")), + CDARichUnorderedList().addAll( + CDARichListItem().addAll(text("two")), + CDARichUnorderedList().addAll( + CDARichListItem().addAll(text("three")), + CDARichUnorderedList().addAll( + CDARichListItem().addAll(text("four")) ) + ) ) + ) + ) + ), + Page( + name = "Quotes", + document = CDARichDocument().addAll( + CDARichBlock().addAll( + text("Quotes from "), + text("Famous", listOf(CDARichMarkBold())), + text(" People", listOf(CDARichMarkItalic())) + ), + CDARichQuote().addAll( + text("You know you’re in love when you can’t fall asleep because reality is finally better than your dreams."), + text("- Dr. Suess", listOf(CDARichMarkItalic())) + ), + CDARichQuote().addAll( + text("I’m selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can’t handle me at my worst, then you sure as hell don’t deserve me at my best."), + text("- Marilyn Monroe", listOf(CDARichMarkItalic())) + ), + CDARichQuote().addAll( + text("Twenty years from now you will be more disappointed by the things that you didn’t do than by the ones you did do."), + text("- Mark Twain", listOf(CDARichMarkItalic())) + ) + ) - ), - Page(name = "Links", document = CDARichDocument().addAll( + ), + Page( + name = "Links", document = CDARichDocument().addAll( + CDARichParagraph().addAll( + CDARichHyperLink("https://www.google.com/search?hl=en&site=imghp&tbm=isch&source=hp&q=dogs") + .addAll(text("Hyperlink to first item")), + text("Normal Text"), CDARichHyperLink("https://www.google.com/search?hl=en&site=imghp&tbm=isch&source=hp&q=cats") - .addAll(text("Hyperlink to cats")), - CDARichEmbeddedInline(mockCDAEntry()) - .addAll(text(" Embedded entry")), - CDARichEmbeddedBlock(mockCDAAsset()) - .addAll(text(" Embedded asset")) - ) + .addAll(text("Hyperlink to cats")), + text("Second Text"), + CDARichHyperLink("https://github.com/contentful/contentful.java") + .addAll(text("OMEGA LUL")), + text("Third Text"), + CDARichHyperLink("https://www.google.com/search?hl=en&site=imghp&tbm=isch&source=hp&q=fish") + .addAll(text("Hyperlink to fish")), + ), + text("Normal Text"), + CDARichHyperLink("https://www.google.com/search?hl=en&site=imghp&tbm=isch&source=hp&q=cats") + .addAll(text("Hyperlink to cats")), + CDARichEmbeddedInline(mockCDAEntry()) + .addAll(text(" Embedded entry")), + CDARichEmbeddedBlock(mockCDAAsset()) + .addAll(text(" Embedded asset")) ) + ) ) -fun text(name: String, marks:List = listOf()) = CDARichText(name, marks) +fun text(name: String, marks: List = listOf()) = CDARichText(name, marks) fun T.addAll(vararg elements: CDARichNode): T { elements.forEach { this.content.add(it) } @@ -179,10 +199,12 @@ fun mockCDAAsset(): CDAAsset { mockSysAndFields(asset) asset.attrs()["id"] = "fake_id" - asset.setField("en-US", "file", mapOf( + asset.setField( + "en-US", "file", mapOf( "url" to "https://www.contentful.com/assets/images/favicons/favicon.png", "contentType" to "image/png" - )) + ) + ) return asset } diff --git a/android_sample/src/main/java/com/contentful/rich/android/sample/PageAdapter.kt b/android_sample/src/main/java/com/contentful/rich/android/sample/PageAdapter.kt index ef549f6..9960f65 100644 --- a/android_sample/src/main/java/com/contentful/rich/android/sample/PageAdapter.kt +++ b/android_sample/src/main/java/com/contentful/rich/android/sample/PageAdapter.kt @@ -8,8 +8,9 @@ import android.widget.ArrayAdapter import androidx.appcompat.widget.ThemedSpinnerAdapter import kotlinx.android.synthetic.main.dropdown_item.view.* -class PageAdapter(context: Context, objects: Array) : - ArrayAdapter(context, R.layout.appbar_item, objects), ThemedSpinnerAdapter { +class PageAdapter( + context: Context, objects: Array +) : ArrayAdapter(context, R.layout.appbar_item, objects), ThemedSpinnerAdapter { private val mDropDownHelper: ThemedSpinnerAdapter.Helper = ThemedSpinnerAdapter.Helper(context) @@ -46,4 +47,4 @@ class PageAdapter(context: Context, objects: Array) : override fun setDropDownViewTheme(theme: Resources.Theme?) { mDropDownHelper.dropDownViewTheme = theme } -} \ No newline at end of file +} diff --git a/android_sample/src/main/java/com/contentful/rich/android/sample/RichCharSequenceAdapter.kt b/android_sample/src/main/java/com/contentful/rich/android/sample/RichCharSequenceAdapter.kt index 7dc42f8..e56a0b9 100644 --- a/android_sample/src/main/java/com/contentful/rich/android/sample/RichCharSequenceAdapter.kt +++ b/android_sample/src/main/java/com/contentful/rich/android/sample/RichCharSequenceAdapter.kt @@ -16,12 +16,13 @@ import com.contentful.rich.android.AndroidContext import com.contentful.rich.android.AndroidProcessor import kotlinx.android.synthetic.main.sample_item.view.* -class RichCharSequenceAdapter(pageIndex: Int, private val androidContext: Context) : RecyclerView.Adapter() { +class RichCharSequenceAdapter(pageIndex: Int, private val androidContext: Context) : + RecyclerView.Adapter() { private val page: Page = PAGES[pageIndex] private val inflater: LayoutInflater = LayoutInflater.from(androidContext) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PageFragment.Holder = - PageFragment.Holder(inflater.inflate(R.layout.sample_item, parent, false)) + PageFragment.Holder(inflater.inflate(R.layout.sample_item, parent, false)) override fun onBindViewHolder(holder: PageFragment.Holder, position: Int) { val item = page.document.content[position] @@ -29,41 +30,41 @@ class RichCharSequenceAdapter(pageIndex: Int, private val androidContext: Contex val processor = AndroidProcessor.creatingCharSequences() processor.overrideRenderer( - { _, node -> node is CDARichHyperLink && node.data is CDAEntry }, - { _, node -> - val data = (node as CDARichHyperLink).data as CDAEntry - val text = androidContext.resources.getString(R.string.hyperlink_entry_inline, data.id()) - val message = androidContext.resources.getString(R.string.hyperlink_entry_inline_clicked, data.id()) + { _, node -> node is CDARichHyperLink && node.data is CDAEntry }, + { _, node -> + val data = (node as CDARichHyperLink).data as CDAEntry + val text = androidContext.resources.getString(R.string.hyperlink_entry_inline, data.id()) + val message = androidContext.resources.getString(R.string.hyperlink_entry_inline_clicked, data.id()) - SpannableStringBuilder(text).apply { - setSpan( - object : ClickableSpan() { - override fun onClick(widget: View) { - androidContext.toast(message) - } - }, 0, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE - ) - }.toString() - } + SpannableStringBuilder(text).apply { + setSpan( + object : ClickableSpan() { + override fun onClick(widget: View) { + androidContext.toast(message) + } + }, 0, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE + ) + }.toString() + } ) processor.overrideRenderer( - { _, node -> node is CDARichHyperLink && node.data is CDAAsset }, - { _, node -> - val data = (node as CDARichHyperLink).data as CDAAsset - val text = androidContext.resources.getString(R.string.hyperlink_asset_inline, data.id()) - val message = androidContext.resources.getString(R.string.hyperlink_asset_inline_clicked, data.id()) + { _, node -> node is CDARichHyperLink && node.data is CDAAsset }, + { _, node -> + val data = (node as CDARichHyperLink).data as CDAAsset + val text = androidContext.resources.getString(R.string.hyperlink_asset_inline, data.id()) + val message = androidContext.resources.getString(R.string.hyperlink_asset_inline_clicked, data.id()) - SpannableStringBuilder(text).apply { - setSpan( - object : ClickableSpan() { - override fun onClick(widget: View) { - androidContext.toast(message) - } - }, 0, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE - ) - }.toString() - } + SpannableStringBuilder(text).apply { + setSpan( + object : ClickableSpan() { + override fun onClick(widget: View) { + androidContext.toast(message) + } + }, 0, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE + ) + }.toString() + } ) val text = processor.process(context, item) ?: "???" @@ -73,4 +74,4 @@ class RichCharSequenceAdapter(pageIndex: Int, private val androidContext: Contex } override fun getItemCount(): Int = page.document.content.size -} \ No newline at end of file +} diff --git a/android_sample/src/main/java/com/contentful/rich/android/sample/RichNativeViewAdapter.kt b/android_sample/src/main/java/com/contentful/rich/android/sample/RichNativeViewAdapter.kt index f273e70..3d5f290 100644 --- a/android_sample/src/main/java/com/contentful/rich/android/sample/RichNativeViewAdapter.kt +++ b/android_sample/src/main/java/com/contentful/rich/android/sample/RichNativeViewAdapter.kt @@ -5,6 +5,7 @@ import android.view.LayoutInflater import android.view.ViewGroup import android.widget.TextView import android.widget.Toast +import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView import com.contentful.java.cda.CDAAsset import com.contentful.java.cda.CDAEntry @@ -14,48 +15,56 @@ import com.contentful.rich.android.AndroidContext import com.contentful.rich.android.AndroidProcessor import kotlinx.android.synthetic.main.sample_item.view.* -class RichNativeViewAdapter(pageIndex: Int, private val androidContext: Context) : RecyclerView.Adapter() { +class RichNativeViewAdapter( + pageIndex: Int, + private val androidContext: Context +) : RecyclerView.Adapter() { + private val page: Page = PAGES[pageIndex] private val inflater: LayoutInflater = LayoutInflater.from(androidContext) - private val context = AndroidContext(androidContext, AndroidConfig( - textColor = android.R.color.holo_red_dark, - marginTop = 8 - )) + private val context = AndroidContext( + androidContext, AndroidConfig( + textColor = android.R.color.holo_red_dark, + linkColor = ContextCompat.getColor(androidContext, android.R.color.holo_green_light), + marginTop = 8 + ) + ) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PageFragment.Holder = - PageFragment.Holder(inflater.inflate(R.layout.sample_item, parent, false)) + PageFragment.Holder(inflater.inflate(R.layout.sample_item, parent, false)) override fun onBindViewHolder(holder: PageFragment.Holder, position: Int) { val item = page.document.content[position] val processor = AndroidProcessor.creatingNativeViews() processor.overrideRenderer( - { _, node -> node is CDARichHyperLink && node.data is CDAEntry }, - { _, node -> - val data = (node as CDARichHyperLink).data as CDAEntry - TextView(androidContext).apply { - text = resources.getString(R.string.hyperlink_entry_inline, data.id()) - setOnClickListener { - androidContext.toast(resources.getString(R.string.hyperlink_entry_inline_clicked, data.id())) - } + { _, node -> node is CDARichHyperLink && node.data is CDAEntry }, + { _, node -> + val data = (node as CDARichHyperLink).data as CDAEntry + TextView(androidContext).apply { + text = resources.getString(R.string.hyperlink_entry_inline, data.id()) + setOnClickListener { + androidContext.toast(resources.getString(R.string.hyperlink_entry_inline_clicked, data.id())) } } + } ) processor.overrideRenderer( - { _, node -> node is CDARichHyperLink && node.data is CDAAsset }, - { _, node -> - val data = (node as CDARichHyperLink).data as CDAAsset - TextView(androidContext).apply { - text = resources.getString(R.string.hyperlink_asset_inline, data.id()) - setOnClickListener { - androidContext.toast(resources.getString(R.string.hyperlink_asset_inline_clicked, data.id())) - } + { _, node -> node is CDARichHyperLink && node.data is CDAAsset }, + { _, node -> + val data = (node as CDARichHyperLink).data as CDAAsset + TextView(androidContext).apply { + text = resources.getString(R.string.hyperlink_asset_inline, data.id()) + setOnClickListener { + androidContext.toast(resources.getString(R.string.hyperlink_asset_inline_clicked, data.id())) } } + } ) - val view = processor.process(context, item) ?: TextView(this.androidContext).apply { setText(R.string.error_no_view) } + val view = + processor.process(context, item) ?: TextView(this.androidContext).apply { setText(R.string.error_no_view) } holder.itemView.sample_item_card.removeAllViews() holder.itemView.sample_item_card.addView(view)