From 96ca96fa70321fc379029d667577b75bdc6e3a8e Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Wed, 6 Feb 2019 15:44:46 +0300 Subject: [PATCH] Working on documentation. Table rendering sample --- docs/docs/core/images.md | 124 ++++++++++++++++++ docs/docs/core/theme.md | 17 +++ .../ru/noties/markwon/ext/tables/Table.java | 21 +-- .../markwon/recycler/MarkwonAdapter.java | 8 +- .../markwon/recycler/MarkwonAdapterImpl.java | 32 ++--- .../noties/markwon/recycler/SimpleEntry.java | 2 +- sample/src/main/AndroidManifest.xml | 2 +- .../sample/recycler/RecyclerActivity.java | 34 ++++- .../markwon/sample/recycler/TableEntry.java | 2 +- .../markwon/sample/recycler/TableEntry2.java | 121 +++++++++++++++++ .../sample/recycler/TableEntryView.java | 3 +- .../res/layout/adapter_default_entry.xml | 4 +- .../res/layout/adapter_fenced_code_block.xml | 8 +- .../res/layout/adapter_table_block.xml | 1 - .../res/layout/adapter_table_block_2.xml | 18 +++ .../res/layout/view_table_entry_cell.xml | 6 +- .../res/layout/view_table_entry_row.xml | 2 +- .../src/main/res/drawable/bg_table_cell.xml | 6 + 18 files changed, 357 insertions(+), 54 deletions(-) create mode 100644 sample/src/main/java/ru/noties/markwon/sample/recycler/TableEntry2.java create mode 100644 sample/src/main/recycler/res/layout/adapter_table_block_2.xml create mode 100644 sample/src/main/res/drawable/bg_table_cell.xml diff --git a/docs/docs/core/images.md b/docs/docs/core/images.md index e8c87380..4450f6ad 100644 --- a/docs/docs/core/images.md +++ b/docs/docs/core/images.md @@ -1 +1,125 @@ # Images + +Starting with `Markwon` comes with `ImagesPlugin` +which supports `http(s)`, `file` and `data` schemes and default media +decoder (for simple images, no [SVG](/docs/image/svg.md) or [GIF](/docs/image/gif.md) which +are defined in standalone modules). + +## ImagesPlugin + +`ImagePlugin` takes care of _obtaining_ image resource, decoding it and displaying it in a `TextView`. + +:::warning +Although `core` artifact contains `ImagesPlugin` one must +still **explicitly** register the `ImagesPlugin` on resulting `Markwon` +instance. +```java +final Markwon markwon = Markwon.builder(context) + .usePlugin(ImagesPlugin.create()) +``` +::: + +There are 2 factory methods to obtain `ImagesPlugin`: +* `ImagesPlugin#create(Context)` +* `ImagesPlugin#createWithAssets(Context)` + +The first one `#create(Context)` configures: +* `FileSchemeHandler` that allows obtaining images from `file://` uris +* `DataUriSchemeHandler` that allows _inlining_ images with `data:` + scheme (`data:image/svg+xml;base64,MTIz`) +* `NetworkSchemeHandler` that allows obtaining images from `http://` and `https://` uris + (internally it uses `HttpURLConnection`) +* `ImageMediaDecoder` which _tries_ to decode all encountered images as regular ones (png, jpg, etc) + +The second one `#createWithAssets(Context)` does the same but also adds support +for images that reside in `assets` folder of your application and +referenced by `file:///android_asset/{path}` uri. + +`ImagesPlugin` also _prepares_ a TextView to display images. Due to asynchronous +nature of image loading, there must be a way to invalidate resulting Spanned +content after an image is loaded. + +:::warning +Images come with few limitations. For of all, they work with a **TextView only**. +This is due to the fact that there is no way to invalidate a `Spanned` content +by itself (without context in which it is displayed). So, if `Markwon` is used, +for example, to display a `Toast` with an image: + +```java +final Spanned spanned = markwon.toMarkdown("Hello ![alt](https://my.image/1.JPG)"); +Toast.makeText(context, spanned, Toast.LENGTH_LONG).show(); +``` + +Image _probably_ won't be displayed. As a workaround for `Toast` a custom `View` +can be used: + +```java +final Spanned spanned = markwon.toMarkdown("Hello ![alt](https://my.image/1.JPG)"); + +final View view = createToastView(); +final TextView textView = view.findViewById(R.id.text_view); +markwon.setParsedMarkdown(textView, spanned); + +final Toast toast = new Toast(context); +toast.setView(view); +// other Toast configurations +toast.show(); +``` +::: + +## SchemeHandler + +To add support for different schemes (or customize provided) a `SchemeHandler` must be used. + +```java +final Markwon markwon = Markwon.builder(context) + .usePlugin(ImagesPlugin.create(context)) + .usePlugin(new AbstractMarkwonPlugin() { + @Override + public void configureImages(@NonNull AsyncDrawableLoader.Builder builder) { + // example only, Markwon doesn't come with a ftp scheme handler + builder.addSchemeHandler("ftp", new FtpSchemeHandler()); + } + }) + .build(); +``` + +It's a class to _convert_ an URI into an `InputStream`: + +```java +public abstract class SchemeHandler { + + @Nullable + public abstract ImageItem handle(@NonNull String raw, @NonNull Uri uri); +} +``` + +`ImageItem` is a holder class for resulting `InputStream` and (optional) +content type: + +```java +public class ImageItem { + + private final String contentType; + private final InputStream inputStream; + + /* rest omitted */ +} +``` + +Based on `contentType` returned a corresponding `MediaDecoder` will be matched. +If no `MediaDecoder` can handle given `contentType` then a default media decoder will +be used. + +## MediaDecoder + +:::tip +If you are using [html](/docs/html/) you do not have to additionally setup +images displayed via `` tag, as `HtmlPlugin` automatically uses configured +image loader. But images referenced in HTML come with additional support for +sizes, which is not supported natively by markdown, allowing absolute or relative sizes: + +```html + +``` +::: \ No newline at end of file diff --git a/docs/docs/core/theme.md b/docs/docs/core/theme.md index b904fbbe..93c31e85 100644 --- a/docs/docs/core/theme.md +++ b/docs/docs/core/theme.md @@ -2,6 +2,23 @@ Here is the list of properties that can be configured via `MarkwonTheme.Builder` class. +:::tip +Starting with there is no need to manually construct a `MarkwonTheme`. +Instead a `Plugin` should be used: +```java +final Markwon markwon = Markwon.builder(context) + .usePlugin(new AbstractMarkwonPlugin() { + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder + .codeTextColor(Color.BLACK) + .codeBackgroundColor(Color.GREEN); + } + }) + .build(); +``` +::: + ## Link color Controls the color of a [link](#) diff --git a/markwon-ext-tables/src/main/java/ru/noties/markwon/ext/tables/Table.java b/markwon-ext-tables/src/main/java/ru/noties/markwon/ext/tables/Table.java index 85e1cfa4..12fee872 100644 --- a/markwon-ext-tables/src/main/java/ru/noties/markwon/ext/tables/Table.java +++ b/markwon-ext-tables/src/main/java/ru/noties/markwon/ext/tables/Table.java @@ -10,7 +10,6 @@ import org.commonmark.ext.gfm.tables.TableHead; import org.commonmark.ext.gfm.tables.TableRow; import org.commonmark.node.AbstractVisitor; import org.commonmark.node.CustomNode; -import org.commonmark.node.Node; import java.util.ArrayList; import java.util.List; @@ -160,21 +159,13 @@ public class Table { final TableCell cell = (TableCell) customNode; - final Node firstChild = cell.getFirstChild(); - - // need to investigate why... (most likely initial node is modified by someone) - if (firstChild != null) { - - if (pendingRow == null) { - pendingRow = new ArrayList<>(2); - } - - // let's TRY to not visit this node but instead try to render its first child - - pendingRow.add(new Table.Column(alignment(cell.getAlignment()), markwon.render(firstChild))); - pendingRowIsHeader = cell.isHeader(); + if (pendingRow == null) { + pendingRow = new ArrayList<>(2); } + pendingRow.add(new Table.Column(alignment(cell.getAlignment()), markwon.render(cell))); + pendingRowIsHeader = cell.isHeader(); + return; } @@ -215,6 +206,4 @@ public class Table { return out; } } - - } diff --git a/markwon-recycler/src/main/java/ru/noties/markwon/recycler/MarkwonAdapter.java b/markwon-recycler/src/main/java/ru/noties/markwon/recycler/MarkwonAdapter.java index e37c2a75..5d6ddc8b 100644 --- a/markwon-recycler/src/main/java/ru/noties/markwon/recycler/MarkwonAdapter.java +++ b/markwon-recycler/src/main/java/ru/noties/markwon/recycler/MarkwonAdapter.java @@ -67,7 +67,7 @@ public abstract class MarkwonAdapter extends RecyclerView.Adapter defaultEntry) { + public static MarkwonAdapter create(@NonNull Entry defaultEntry) { return new MarkwonAdapterImpl.BuilderImpl().defaultEntry(defaultEntry).build(); } @@ -109,7 +109,7 @@ public abstract class MarkwonAdapter extends RecyclerView.Adapter Builder include( @NonNull Class node, - @NonNull Entry entry); + @NonNull Entry entry); /** * Specify which {@link Entry} to use for all non-explicitly registered nodes @@ -119,7 +119,7 @@ public abstract class MarkwonAdapter extends RecyclerView.Adapter defaultEntry); + Builder defaultEntry(@NonNull Entry defaultEntry); /** * Specify which layout {@link SimpleEntry} will use to render all non-explicitly @@ -156,7 +156,7 @@ public abstract class MarkwonAdapter extends RecyclerView.Adapter { + public interface Entry { @NonNull H createHolder(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent); diff --git a/markwon-recycler/src/main/java/ru/noties/markwon/recycler/MarkwonAdapterImpl.java b/markwon-recycler/src/main/java/ru/noties/markwon/recycler/MarkwonAdapterImpl.java index afd1aa71..0e29c2d4 100644 --- a/markwon-recycler/src/main/java/ru/noties/markwon/recycler/MarkwonAdapterImpl.java +++ b/markwon-recycler/src/main/java/ru/noties/markwon/recycler/MarkwonAdapterImpl.java @@ -15,8 +15,8 @@ import ru.noties.markwon.Markwon; class MarkwonAdapterImpl extends MarkwonAdapter { - private final SparseArray> entries; - private final Entry defaultEntry; + private final SparseArray> entries; + private final Entry defaultEntry; private final Reducer reducer; private LayoutInflater layoutInflater; @@ -26,8 +26,8 @@ class MarkwonAdapterImpl extends MarkwonAdapter { @SuppressWarnings("WeakerAccess") MarkwonAdapterImpl( - @NonNull SparseArray> entries, - @NonNull Entry defaultEntry, + @NonNull SparseArray> entries, + @NonNull Entry defaultEntry, @NonNull Reducer reducer) { this.entries = entries; this.defaultEntry = defaultEntry; @@ -67,7 +67,7 @@ class MarkwonAdapterImpl extends MarkwonAdapter { layoutInflater = LayoutInflater.from(parent.getContext()); } - final Entry entry = getEntry(viewType); + final Entry entry = getEntry(viewType); return entry.createHolder(layoutInflater, parent); } @@ -78,7 +78,7 @@ class MarkwonAdapterImpl extends MarkwonAdapter { final Node node = nodes.get(position); final int viewType = getNodeViewType(node.getClass()); - final Entry entry = getEntry(viewType); + final Entry entry = getEntry(viewType); entry.bindHolder(markwon, holder, node); } @@ -107,7 +107,7 @@ class MarkwonAdapterImpl extends MarkwonAdapter { public long getItemId(int position) { final Node node = nodes.get(position); final int type = getNodeViewType(node.getClass()); - final Entry entry = getEntry(type); + final Entry entry = getEntry(type); return entry.id(node); } @@ -122,7 +122,7 @@ class MarkwonAdapterImpl extends MarkwonAdapter { } @NonNull - private Entry getEntry(int viewType) { + private Entry getEntry(int viewType) { return viewType == 0 ? defaultEntry : entries.get(viewType); @@ -130,26 +130,26 @@ class MarkwonAdapterImpl extends MarkwonAdapter { static class BuilderImpl implements Builder { - private final SparseArray> entries = new SparseArray<>(3); + private final SparseArray> entries = new SparseArray<>(3); - private Entry defaultEntry; + private Entry defaultEntry; private Reducer reducer; @NonNull @Override public Builder include( @NonNull Class node, - @NonNull Entry entry) { + @NonNull Entry entry) { //noinspection unchecked - entries.append(node.hashCode(), (Entry) entry); + entries.append(node.hashCode(), (Entry) entry); return this; } @NonNull @Override - public Builder defaultEntry(@NonNull Entry defaultEntry) { + public Builder defaultEntry(@NonNull Entry defaultEntry) { //noinspection unchecked - this.defaultEntry = (Entry) defaultEntry; + this.defaultEntry = (Entry) defaultEntry; return this; } @@ -157,7 +157,7 @@ class MarkwonAdapterImpl extends MarkwonAdapter { @Override public Builder defaultEntry(int layoutResId) { //noinspection unchecked - this.defaultEntry = (Entry) (Entry) new SimpleEntry(layoutResId); + this.defaultEntry = (Entry) (Entry) new SimpleEntry(layoutResId); return this; } @@ -174,7 +174,7 @@ class MarkwonAdapterImpl extends MarkwonAdapter { if (defaultEntry == null) { //noinspection unchecked - defaultEntry = (Entry) (Entry) new SimpleEntry(); + defaultEntry = (Entry) (Entry) new SimpleEntry(); } if (reducer == null) { diff --git a/markwon-recycler/src/main/java/ru/noties/markwon/recycler/SimpleEntry.java b/markwon-recycler/src/main/java/ru/noties/markwon/recycler/SimpleEntry.java index a966ec94..03ce5e56 100644 --- a/markwon-recycler/src/main/java/ru/noties/markwon/recycler/SimpleEntry.java +++ b/markwon-recycler/src/main/java/ru/noties/markwon/recycler/SimpleEntry.java @@ -21,7 +21,7 @@ import ru.noties.markwon.Markwon; * @since 3.0.0 */ @SuppressWarnings("WeakerAccess") -public class SimpleEntry implements MarkwonAdapter.Entry { +public class SimpleEntry implements MarkwonAdapter.Entry { public static final Spannable.Factory NO_COPY_SPANNABLE_FACTORY = new NoCopySpannableFactory(); diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml index d3c2b0e1..d1442bf0 100644 --- a/sample/src/main/AndroidManifest.xml +++ b/sample/src/main/AndroidManifest.xml @@ -8,8 +8,8 @@ diff --git a/sample/src/main/java/ru/noties/markwon/sample/recycler/RecyclerActivity.java b/sample/src/main/java/ru/noties/markwon/sample/recycler/RecyclerActivity.java index 23c5777e..c230aa6c 100644 --- a/sample/src/main/java/ru/noties/markwon/sample/recycler/RecyclerActivity.java +++ b/sample/src/main/java/ru/noties/markwon/sample/recycler/RecyclerActivity.java @@ -11,27 +11,29 @@ import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import org.commonmark.ext.gfm.tables.TableBlock; +import org.commonmark.ext.gfm.tables.TablesExtension; import org.commonmark.node.FencedCodeBlock; +import org.commonmark.parser.Parser; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.util.Collections; import ru.noties.debug.AndroidLogDebugOutput; import ru.noties.debug.Debug; import ru.noties.markwon.AbstractMarkwonPlugin; import ru.noties.markwon.Markwon; import ru.noties.markwon.MarkwonConfiguration; +import ru.noties.markwon.MarkwonVisitor; import ru.noties.markwon.core.CorePlugin; -import ru.noties.markwon.ext.tables.TablePlugin; import ru.noties.markwon.html.HtmlPlugin; import ru.noties.markwon.image.ImagesPlugin; import ru.noties.markwon.image.svg.SvgPlugin; import ru.noties.markwon.recycler.MarkwonAdapter; import ru.noties.markwon.recycler.SimpleEntry; import ru.noties.markwon.sample.R; -import ru.noties.markwon.syntax.SyntaxHighlightPlugin; import ru.noties.markwon.urlprocessor.UrlProcessor; import ru.noties.markwon.urlprocessor.UrlProcessorRelativeToAbsolute; @@ -54,7 +56,7 @@ public class RecyclerActivity extends Activity { // with `@+id/text` id .include(FencedCodeBlock.class, new SimpleEntry(R.layout.adapter_fenced_code_block)) // create own implementation of entry for different rendering - .include(TableBlock.class, new TableEntry()) + .include(TableBlock.class, new TableEntry2()) // specify default entry (for all other blocks) .defaultEntry(new SimpleEntry(R.layout.adapter_default_entry)) .build(); @@ -81,15 +83,35 @@ public class RecyclerActivity extends Activity { .usePlugin(CorePlugin.create()) .usePlugin(ImagesPlugin.createWithAssets(context)) .usePlugin(SvgPlugin.create(context.getResources())) - // although we will be rendering table differently we still need - // to register commonmark-java tables extension (which TablePlugin does) - .usePlugin(TablePlugin.create(context)) + .usePlugin(new AbstractMarkwonPlugin() { + @Override + public void configureParser(@NonNull Parser.Builder builder) { + // it's important NOT to use TablePlugin + // the only thing we want from it is commonmark-java parser extension + builder.extensions(Collections.singleton(TablesExtension.create())); + } + }) .usePlugin(HtmlPlugin.create()) +// .usePlugin(SyntaxHighlightPlugin.create()) .usePlugin(new AbstractMarkwonPlugin() { @Override public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { builder.urlProcessor(new UrlProcessorInitialReadme()); } + + @Override + public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) { + builder.on(FencedCodeBlock.class, (visitor, fencedCodeBlock) -> { + // we actually won't be applying code spans here, as our custom view will + // draw background and apply mono typeface + // + // NB the `trim` operation on literal (as code will have a new line at the end) + final CharSequence code = visitor.configuration() + .syntaxHighlight() + .highlight(fencedCodeBlock.getInfo(), fencedCodeBlock.getLiteral().trim()); + visitor.builder().append(code); + }); + } }) .build(); } diff --git a/sample/src/main/java/ru/noties/markwon/sample/recycler/TableEntry.java b/sample/src/main/java/ru/noties/markwon/sample/recycler/TableEntry.java index 8e3070e3..900ce719 100644 --- a/sample/src/main/java/ru/noties/markwon/sample/recycler/TableEntry.java +++ b/sample/src/main/java/ru/noties/markwon/sample/recycler/TableEntry.java @@ -17,7 +17,7 @@ import ru.noties.markwon.recycler.MarkwonAdapter; import ru.noties.markwon.sample.R; // do not use in real applications, this is just a showcase -public class TableEntry implements MarkwonAdapter.Entry { +public class TableEntry implements MarkwonAdapter.Entry { private final Map cache = new HashMap<>(2); diff --git a/sample/src/main/java/ru/noties/markwon/sample/recycler/TableEntry2.java b/sample/src/main/java/ru/noties/markwon/sample/recycler/TableEntry2.java new file mode 100644 index 00000000..dcf8d061 --- /dev/null +++ b/sample/src/main/java/ru/noties/markwon/sample/recycler/TableEntry2.java @@ -0,0 +1,121 @@ +package ru.noties.markwon.sample.recycler; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.support.annotation.NonNull; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TableLayout; +import android.widget.TableRow; +import android.widget.TextView; + +import org.commonmark.ext.gfm.tables.TableBlock; + +import java.util.HashMap; +import java.util.Map; + +import ru.noties.markwon.Markwon; +import ru.noties.markwon.ext.tables.Table; +import ru.noties.markwon.recycler.MarkwonAdapter; +import ru.noties.markwon.sample.R; + +public class TableEntry2 implements MarkwonAdapter.Entry { + + private final Map map = new HashMap<>(3); + + @NonNull + @Override + public TableHolder createHolder(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) { + return new TableHolder(inflater.inflate(R.layout.adapter_table_block_2, parent, false)); + } + + @Override + public void bindHolder(@NonNull Markwon markwon, @NonNull TableHolder holder, @NonNull TableBlock node) { + + Table table = map.get(node); + if (table == null) { + table = Table.parse(markwon, node); + map.put(node, table); + } + + // check if this exact TableBlock was already + final TableLayout layout = holder.layout; + if (table == null + || table == layout.getTag(R.id.table_layout)) { + return; + } + + layout.setTag(R.id.table_layout, table); + layout.removeAllViews(); + layout.setBackgroundResource(R.drawable.bg_table_cell); + + final Context context = layout.getContext(); + final LayoutInflater inflater = LayoutInflater.from(context); + + TableRow tableRow; + TextView textView; + + for (Table.Row row : table.rows()) { + tableRow = new TableRow(context); + for (Table.Column column : row.columns()) { + textView = (TextView) inflater.inflate(R.layout.view_table_entry_cell, tableRow, false); + textView.setGravity(textGravity(column.alignment())); + markwon.setParsedMarkdown(textView, column.content()); + textView.getPaint().setFakeBoldText(row.header()); + textView.setBackgroundResource(R.drawable.bg_table_cell); + tableRow.addView(textView); + } + layout.addView(tableRow); + } + } + + @Override + public long id(@NonNull TableBlock node) { + return node.hashCode(); + } + + @Override + public void clear() { + map.clear(); + } + + static class TableHolder extends MarkwonAdapter.Holder { + + final TableLayout layout; + + TableHolder(@NonNull View itemView) { + super(itemView); + + this.layout = requireView(R.id.table_layout); + } + } + + // we will use gravity instead of textAlignment because min sdk is 16 (textAlignment starts at 17) + @SuppressLint("RtlHardcoded") + private static int textGravity(@NonNull Table.Alignment alignment) { + + final int gravity; + + switch (alignment) { + + case LEFT: + gravity = Gravity.LEFT; + break; + + case CENTER: + gravity = Gravity.CENTER_HORIZONTAL; + break; + + case RIGHT: + gravity = Gravity.RIGHT; + break; + + default: + throw new IllegalStateException("Unknown table alignment: " + alignment); + } + + return gravity | Gravity.CENTER_VERTICAL; + } +} diff --git a/sample/src/main/java/ru/noties/markwon/sample/recycler/TableEntryView.java b/sample/src/main/java/ru/noties/markwon/sample/recycler/TableEntryView.java index 09c2e771..df789728 100644 --- a/sample/src/main/java/ru/noties/markwon/sample/recycler/TableEntryView.java +++ b/sample/src/main/java/ru/noties/markwon/sample/recycler/TableEntryView.java @@ -54,7 +54,6 @@ public class TableEntryView extends LinearLayout { rowEvenBackgroundColor = array.getColor(R.styleable.TableEntryView_tev_rowEvenBackgroundColor, 0); - final int stroke = array.getDimensionPixelSize(R.styleable.TableEntryView_tev_borderWidth, 0); // half of requested @@ -124,6 +123,8 @@ public class TableEntryView extends LinearLayout { textView.setText(column.content()); textView.getPaint().setFakeBoldText(row.header()); } + + group.requestLayout(); } @NonNull diff --git a/sample/src/main/recycler/res/layout/adapter_default_entry.xml b/sample/src/main/recycler/res/layout/adapter_default_entry.xml index 1d302e96..e9fb8929 100644 --- a/sample/src/main/recycler/res/layout/adapter_default_entry.xml +++ b/sample/src/main/recycler/res/layout/adapter_default_entry.xml @@ -1,5 +1,6 @@ \ No newline at end of file + android:textSize="16sp" + tools:text="Hello" /> \ No newline at end of file diff --git a/sample/src/main/recycler/res/layout/adapter_fenced_code_block.xml b/sample/src/main/recycler/res/layout/adapter_fenced_code_block.xml index ddc2c802..e823fb09 100644 --- a/sample/src/main/recycler/res/layout/adapter_fenced_code_block.xml +++ b/sample/src/main/recycler/res/layout/adapter_fenced_code_block.xml @@ -14,11 +14,15 @@ android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:background="#0f000000" + android:fontFamily="monospace" android:lineSpacingExtra="2dip" + android:paddingLeft="16dip" android:paddingTop="8dip" + android:paddingRight="16dip" android:paddingBottom="8dip" android:textAppearance="?android:attr/textAppearanceMedium" - android:textSize="16sp" - tools:text="# Hello there! and taskjs" /> + android:textSize="14sp" + tools:text="# Hello there! and tasks" /> \ No newline at end of file diff --git a/sample/src/main/recycler/res/layout/adapter_table_block.xml b/sample/src/main/recycler/res/layout/adapter_table_block.xml index 4f0536e5..3358ca5a 100644 --- a/sample/src/main/recycler/res/layout/adapter_table_block.xml +++ b/sample/src/main/recycler/res/layout/adapter_table_block.xml @@ -5,7 +5,6 @@ android:layout_height="wrap_content" android:clipChildren="false" android:clipToPadding="false" - android:fillViewport="true" android:paddingLeft="16dip" android:paddingTop="8dip" android:paddingRight="16dip" diff --git a/sample/src/main/recycler/res/layout/adapter_table_block_2.xml b/sample/src/main/recycler/res/layout/adapter_table_block_2.xml new file mode 100644 index 00000000..6cdb3be6 --- /dev/null +++ b/sample/src/main/recycler/res/layout/adapter_table_block_2.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/sample/src/main/recycler/res/layout/view_table_entry_cell.xml b/sample/src/main/recycler/res/layout/view_table_entry_cell.xml index 1c41e218..6261bacb 100644 --- a/sample/src/main/recycler/res/layout/view_table_entry_cell.xml +++ b/sample/src/main/recycler/res/layout/view_table_entry_cell.xml @@ -1,10 +1,10 @@ \ No newline at end of file diff --git a/sample/src/main/res/drawable/bg_table_cell.xml b/sample/src/main/res/drawable/bg_table_cell.xml new file mode 100644 index 00000000..9a2b40b8 --- /dev/null +++ b/sample/src/main/res/drawable/bg_table_cell.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file