this commit adds selecting github emoji from markdown editor (search functionality in progress)

This commit is contained in:
Kosh Sergani 2017-08-17 23:21:17 +08:00
parent aae532bdbb
commit e2da2aef84
16 changed files with 526 additions and 207 deletions

View File

@ -12,203 +12,208 @@ import java.util.List;
* @author Vincent DURMONT [vdurmont@gmail.com]
*/
public class Emoji {
private final String description;
private final boolean supportsFitzpatrick;
private final List<String> aliases;
private final List<String> tags;
private final String unicode;
private final String htmlDec;
private final String htmlHex;
private final String description;
private final boolean supportsFitzpatrick;
private final List<String> aliases;
private final List<String> tags;
private final String unicode;
private final String htmlDec;
private final String htmlHex;
/**
* Constructor for the Emoji.
*
* @param description The description of the emoji
* @param supportsFitzpatrick Whether the emoji supports Fitzpatrick modifiers
* @param aliases the aliases for this emoji
* @param tags the tags associated with this emoji
* @param bytes the bytes that represent the emoji
*/
protected Emoji(
String description,
boolean supportsFitzpatrick,
List<String> aliases,
List<String> tags,
byte... bytes
) {
this.description = description;
this.supportsFitzpatrick = supportsFitzpatrick;
this.aliases = Collections.unmodifiableList(aliases);
this.tags = Collections.unmodifiableList(tags);
/**
* Constructor for the Emoji.
*
* @param description
* The description of the emoji
* @param supportsFitzpatrick
* Whether the emoji supports Fitzpatrick modifiers
* @param aliases
* the aliases for this emoji
* @param tags
* the tags associated with this emoji
* @param bytes
* the bytes that represent the emoji
*/
protected Emoji(
String description,
boolean supportsFitzpatrick,
List<String> aliases,
List<String> tags,
byte... bytes
) {
this.description = description;
this.supportsFitzpatrick = supportsFitzpatrick;
this.aliases = Collections.unmodifiableList(aliases);
this.tags = Collections.unmodifiableList(tags);
int count = 0;
try {
this.unicode = new String(bytes, "UTF-8");
int stringLength = getUnicode().length();
String[] pointCodes = new String[stringLength];
String[] pointCodesHex = new String[stringLength];
int count = 0;
try {
this.unicode = new String(bytes, "UTF-8");
int stringLength = getUnicode().length();
String[] pointCodes = new String[stringLength];
String[] pointCodesHex = new String[stringLength];
for (int offset = 0; offset < stringLength; ) {
final int codePoint = getUnicode().codePointAt(offset);
for (int offset = 0; offset < stringLength; ) {
final int codePoint = getUnicode().codePointAt(offset);
pointCodes[count] = String.format("&#%d;", codePoint);
pointCodesHex[count++] = String.format("&#x%x;", codePoint);
pointCodes[count] = String.format("&#%d;", codePoint);
pointCodesHex[count++] = String.format("&#x%x;", codePoint);
offset += Character.charCount(codePoint);
}
this.htmlDec = stringJoin(pointCodes, count);
this.htmlHex = stringJoin(pointCodesHex, count);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
offset += Character.charCount(codePoint);
}
this.htmlDec = stringJoin(pointCodes, count);
this.htmlHex = stringJoin(pointCodesHex, count);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}
/**
* Method to replace String.join, since it was only introduced in java8
* @param array the array to be concatenated
* @return concatenated String
*/
private String stringJoin(String[] array, int count){
String joined = "";
for(int i = 0; i < count; i++)
joined += array[i];
return joined;
}
/**
* Returns the description of the emoji
*
* @return the description
*/
public String getDescription() {
return this.description;
}
/**
* Returns wether the emoji supports the Fitzpatrick modifiers or not
*
* @return true if the emoji supports the Fitzpatrick modifiers
*/
public boolean supportsFitzpatrick() {
return this.supportsFitzpatrick;
}
/**
* Returns the aliases of the emoji
*
* @return the aliases (unmodifiable)
*/
public List<String> getAliases() {
return this.aliases;
}
/**
* Returns the tags of the emoji
*
* @return the tags (unmodifiable)
*/
public List<String> getTags() {
return this.tags;
}
/**
* Returns the unicode representation of the emoji
*
* @return the unicode representation
*/
public String getUnicode() {
return this.unicode;
}
/**
* Returns the unicode representation of the emoji associated with the
* provided Fitzpatrick modifier.<br>
* If the modifier is null, then the result is similar to
* {@link Emoji#getUnicode()}
*
* @param fitzpatrick the fitzpatrick modifier or null
*
* @return the unicode representation
* @throws UnsupportedOperationException if the emoji doesn't support the
* Fitzpatrick modifiers
*/
public String getUnicode(Fitzpatrick fitzpatrick) {
if (!this.supportsFitzpatrick()) {
throw new UnsupportedOperationException(
"Cannot get the unicode with a fitzpatrick modifier, " +
"the emoji doesn't support fitzpatrick."
);
} else if (fitzpatrick == null) {
return this.getUnicode();
/**
* Method to replace String.join, since it was only introduced in java8
*
* @param array
* the array to be concatenated
* @return concatenated String
*/
private String stringJoin(String[] array, int count) {
String joined = "";
for (int i = 0; i < count; i++)
joined += array[i];
return joined;
}
return this.getUnicode() + fitzpatrick.unicode;
}
/**
* Returns the HTML decimal representation of the emoji
*
* @return the HTML decimal representation
*/
public String getHtmlDecimal() {
return this.htmlDec;
}
/**
* Returns the description of the emoji
*
* @return the description
*/
public String getDescription() {
return this.description;
}
/**
* @deprecated identical to {@link #getHtmlHexadecimal()} for
* backwards-compatibility. Use that instead.
*
* @return the HTML hexadecimal representation
*/
public String getHtmlHexidecimal() {
return this.getHtmlHexadecimal();
}
/**
* Returns wether the emoji supports the Fitzpatrick modifiers or not
*
* @return true if the emoji supports the Fitzpatrick modifiers
*/
public boolean supportsFitzpatrick() {
return this.supportsFitzpatrick;
}
/**
* Returns the HTML hexadecimal representation of the emoji
*
* @return the HTML hexadecimal representation
*/
public String getHtmlHexadecimal() {
return this.htmlHex;
}
/**
* Returns the aliases of the emoji
*
* @return the aliases (unmodifiable)
*/
public List<String> getAliases() {
return this.aliases;
}
@Override
public boolean equals(Object other) {
return !(other == null || !(other instanceof Emoji)) &&
((Emoji) other).getUnicode().equals(getUnicode());
}
/**
* Returns the tags of the emoji
*
* @return the tags (unmodifiable)
*/
public List<String> getTags() {
return this.tags;
}
@Override
public int hashCode() {
return unicode.hashCode();
}
/**
* Returns the unicode representation of the emoji
*
* @return the unicode representation
*/
public String getUnicode() {
return this.unicode;
}
/**
* Returns the String representation of the Emoji object.<br>
* <br>
* Example:<br>
* <code>Emoji {
* description='smiling face with open mouth and smiling eyes',
* supportsFitzpatrick=false,
* aliases=[smile],
* tags=[happy, joy, pleased],
* unicode='😄',
* htmlDec='&amp;#128516;',
* htmlHex='&amp;#x1f604;'
* }</code>
*
* @return the string representation
*/
@Override
public String toString() {
return "Emoji{" +
"description='" + description + '\'' +
", supportsFitzpatrick=" + supportsFitzpatrick +
", aliases=" + aliases +
", tags=" + tags +
", unicode='" + unicode + '\'' +
", htmlDec='" + htmlDec + '\'' +
", htmlHex='" + htmlHex + '\'' +
'}';
}
/**
* Returns the unicode representation of the emoji associated with the
* provided Fitzpatrick modifier.<br>
* If the modifier is null, then the result is similar to
* {@link Emoji#getUnicode()}
*
* @param fitzpatrick
* the fitzpatrick modifier or null
* @return the unicode representation
* @throws UnsupportedOperationException
* if the emoji doesn't support the Fitzpatrick modifiers
*/
public String getUnicode(Fitzpatrick fitzpatrick) {
if (!this.supportsFitzpatrick()) {
throw new UnsupportedOperationException(
"Cannot get the unicode with a fitzpatrick modifier, " +
"the emoji doesn't support fitzpatrick."
);
} else if (fitzpatrick == null) {
return this.getUnicode();
}
return this.getUnicode() + fitzpatrick.unicode;
}
/**
* Returns the HTML decimal representation of the emoji
*
* @return the HTML decimal representation
*/
public String getHtmlDecimal() {
return this.htmlDec;
}
/**
* @return the HTML hexadecimal representation
* @deprecated identical to {@link #getHtmlHexadecimal()} for backwards-compatibility. Use that instead.
*/
public String getHtmlHexidecimal() {
return this.getHtmlHexadecimal();
}
/**
* Returns the HTML hexadecimal representation of the emoji
*
* @return the HTML hexadecimal representation
*/
public String getHtmlHexadecimal() {
return this.htmlHex;
}
@Override
public boolean equals(Object other) {
return !(other == null || !(other instanceof Emoji)) &&
((Emoji) other).getUnicode().equals(getUnicode());
}
@Override
public int hashCode() {
return unicode.hashCode();
}
/**
* Returns the String representation of the Emoji object.<br>
* <br>
* Example:<br>
* <code>Emoji {
* description='smiling face with open mouth and smiling eyes',
* supportsFitzpatrick=false,
* aliases=[smile],
* tags=[happy, joy, pleased],
* unicode='😄',
* htmlDec='&amp;#128516;',
* htmlHex='&amp;#x1f604;'
* }</code>
*
* @return the string representation
*/
@Override
public String toString() {
return "Emoji{" +
"description='" + description + '\'' +
", supportsFitzpatrick=" + supportsFitzpatrick +
", aliases=" + aliases +
", tags=" + tags +
", unicode='" + unicode + '\'' +
", htmlDec='" + htmlDec + '\'' +
", htmlHex='" + htmlHex + '\'' +
'}';
}
}

View File

@ -87,7 +87,7 @@ public class EmojiManager {
return EMOJI_TRIE.getEmoji(unicode);
}
public static Collection<Emoji> getAll() {
public static List<Emoji> getAll() {
return ALL_EMOJIS;
}

View File

@ -0,0 +1,22 @@
package com.fastaccess.ui.adapter
import android.view.ViewGroup
import com.fastaccess.provider.emoji.Emoji
import com.fastaccess.ui.adapter.viewholder.EmojiViewHolder
import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
/**
* Created by kosh on 17/08/2017.
*/
class EmojiAdapter(listener: BaseViewHolder.OnItemClickListener<Emoji>)
: BaseRecyclerAdapter<Emoji, EmojiViewHolder, BaseViewHolder.OnItemClickListener<Emoji>>(listener) {
override fun viewHolder(parent: ViewGroup, viewType: Int): EmojiViewHolder {
return EmojiViewHolder.newInstance(parent, this)
}
override fun onBindView(holder: EmojiViewHolder, position: Int) {
holder.bind(data[position])
}
}

View File

@ -0,0 +1,29 @@
package com.fastaccess.ui.adapter.viewholder
import android.view.View
import android.view.ViewGroup
import butterknife.BindView
import com.fastaccess.R
import com.fastaccess.provider.emoji.Emoji
import com.fastaccess.ui.widgets.FontTextView
import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
/**
* Created by kosh on 17/08/2017.
*/
class EmojiViewHolder private constructor(view: View, adapter: BaseRecyclerAdapter<*, *, *>)
: BaseViewHolder<Emoji>(view, adapter) {
@BindView(R.id.emoji) lateinit var emojiTextView: FontTextView
override fun bind(t: Emoji) {
emojiTextView.text = t.unicode
}
companion object {
fun newInstance(parent: ViewGroup, adapter: BaseRecyclerAdapter<*, *, *>): EmojiViewHolder {
return EmojiViewHolder(getView(parent, R.layout.emoji_row_item), adapter)
}
}
}

View File

@ -1,5 +1,6 @@
package com.fastaccess.ui.modules.editor
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.os.Bundle
@ -22,6 +23,7 @@ import com.fastaccess.R
import com.fastaccess.data.dao.EditReviewCommentModel
import com.fastaccess.data.dao.model.Comment
import com.fastaccess.helper.*
import com.fastaccess.provider.emoji.Emoji
import com.fastaccess.provider.markdown.CachedComments
import com.fastaccess.provider.markdown.MarkDownProvider
import com.fastaccess.ui.base.BaseActivity
@ -36,7 +38,7 @@ import java.util.*
class EditorActivity : BaseActivity<EditorMvp.View, EditorPresenter>(), EditorMvp.View {
val sentFromFastHub: String by lazy {
private val sentFromFastHub: String by lazy {
"\n\n_" + getString(R.string.sent_from_fasthub, AppHelper.getDeviceName(), "",
"[" + getString(R.string.app_name) + "](https://play.google.com/store/apps/details?id=com.fastaccess.github)") + "_"
}
@ -52,13 +54,21 @@ class EditorActivity : BaseActivity<EditorMvp.View, EditorPresenter>(), EditorMv
@BindView(R.id.parentView) lateinit var parentView: View
@BindView(R.id.autocomplete) lateinit var mention: ListView
@State @BundleConstant.ExtraTYpe var extraType: String? = null
@State var itemId: String? = null
@State var login: String? = null
@State var issueNumber: Int = 0
@State var commentId: Long = 0
@State var sha: String? = null
@State var reviewComment: EditReviewCommentModel? = null
@State
@BundleConstant.ExtraTYpe
var extraType: String? = null
@State
var itemId: String? = null
@State
var login: String? = null
@State
var issueNumber: Int = 0
@State
var commentId: Long = 0
@State
var sha: String? = null
@State
var reviewComment: EditReviewCommentModel? = null
override fun layout(): Int = R.layout.editor_layout
@ -203,6 +213,12 @@ class EditorActivity : BaseActivity<EditorMvp.View, EditorPresenter>(), EditorMv
override fun fragmentManager(): FragmentManager = supportFragmentManager
@SuppressLint("SetTextI18n")
override fun onEmojiAdded(emoji: Emoji) {
ViewHelper.showKeyboard(editText)
editText.setText("${editText.text} :${emoji.aliases[0]}:")
}
private fun onCreate() {
val intent = intent
if (intent != null && intent.extras != null) {

View File

@ -4,6 +4,7 @@ import com.fastaccess.data.dao.EditReviewCommentModel
import com.fastaccess.data.dao.model.Comment
import com.fastaccess.helper.BundleConstant
import com.fastaccess.ui.base.mvp.BaseMvp
import com.fastaccess.ui.modules.editor.emoji.EmojiMvp
import com.fastaccess.ui.modules.editor.popup.EditorLinkImageMvp
import com.fastaccess.ui.widgets.markdown.MarkDownLayout
@ -13,7 +14,8 @@ import com.fastaccess.ui.widgets.markdown.MarkDownLayout
interface EditorMvp {
interface View : BaseMvp.FAView, EditorLinkImageMvp.EditorLinkCallback, MarkDownLayout.MarkdownListener {
interface View : BaseMvp.FAView, EditorLinkImageMvp.EditorLinkCallback,
MarkDownLayout.MarkdownListener, EmojiMvp.EmojiCallback {
fun onSendResultAndFinish(commentModel: Comment, isNew: Boolean)
fun onSendMarkDownResult()

View File

@ -0,0 +1,70 @@
package com.fastaccess.ui.modules.editor.emoji
import android.content.Context
import android.os.Bundle
import android.view.View
import butterknife.BindView
import com.fastaccess.R
import com.fastaccess.provider.emoji.Emoji
import com.fastaccess.ui.adapter.EmojiAdapter
import com.fastaccess.ui.base.BaseMvpBottomSheetDialogFragment
import com.fastaccess.ui.widgets.recyclerview.DynamicRecyclerView
import com.fastaccess.ui.widgets.recyclerview.layout_manager.GridManager
import com.fastaccess.ui.widgets.recyclerview.scroll.RecyclerViewFastScroller
/**
* Created by kosh on 17/08/2017.
*/
class EmojiBottomSheet : BaseMvpBottomSheetDialogFragment<EmojiMvp.View, EmojiPresenter>(), EmojiMvp.View {
@BindView(R.id.recycler) lateinit var recycler: DynamicRecyclerView
@BindView(R.id.fastScroller) lateinit var fastScroller: RecyclerViewFastScroller
val adapter: EmojiAdapter by lazy { EmojiAdapter(this) }
var emojiCallback: EmojiMvp.EmojiCallback? = null
override fun onAttach(context: Context) {
super.onAttach(context)
if (parentFragment is EmojiMvp.EmojiCallback) {
emojiCallback = parentFragment as EmojiMvp.EmojiCallback
} else if (context is EmojiMvp.EmojiCallback) {
emojiCallback = context
} else {
throw IllegalArgumentException("${context.javaClass.simpleName} must implement EmojiMvp.EmojiCallback")
}
}
override fun onDetach() {
emojiCallback = null
super.onDetach()
}
override fun fragmentLayout(): Int = R.layout.emoji_popup_layout
override fun providePresenter(): EmojiPresenter = EmojiPresenter()
override fun clearAdapter() {
adapter.clear()
}
override fun onAddEmoji(emoji: Emoji) {
adapter.addItem(emoji)
}
override fun onItemClick(position: Int, v: View?, item: Emoji) {
emojiCallback?.onEmojiAdded(item)
dismiss()
}
override fun onItemLongClick(position: Int, v: View?, item: Emoji?) {}
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
recycler.adapter = adapter
fastScroller.attachRecyclerView(recycler)
presenter.onLoadEmoji()
val gridManager = recycler.layoutManager as GridManager
gridManager.iconSize = resources.getDimensionPixelSize(R.dimen.header_icon_zie)
}
}

View File

@ -0,0 +1,24 @@
package com.fastaccess.ui.modules.editor.emoji
import com.fastaccess.provider.emoji.Emoji
import com.fastaccess.ui.base.mvp.BaseMvp
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
/**
* Created by kosh on 17/08/2017.
*/
interface EmojiMvp {
interface View : BaseMvp.FAView, BaseViewHolder.OnItemClickListener<Emoji> {
fun clearAdapter()
fun onAddEmoji(emoji: Emoji)
}
interface Presenter {
fun onLoadEmoji()
}
interface EmojiCallback {
fun onEmojiAdded(emoji: Emoji)
}
}

View File

@ -0,0 +1,29 @@
package com.fastaccess.ui.modules.editor.emoji
import com.fastaccess.provider.emoji.Emoji
import com.fastaccess.provider.emoji.EmojiManager
import com.fastaccess.ui.base.mvp.presenter.BasePresenter
import io.reactivex.Observable
/**
* Created by kosh on 17/08/2017.
*/
class EmojiPresenter : BasePresenter<EmojiMvp.View>(), EmojiMvp.Presenter {
override fun onLoadEmoji() {
manageObservable(Observable.create<Emoji> { e ->
val emojies = EmojiManager.getAll()
emojies?.let {
it.onEach {
if (!e.isDisposed) {
e.onNext(it)
}
}
}
e.onComplete()
}
.doOnSubscribe { sendToView { it.clearAdapter() } }
.doOnNext { emoji -> sendToView { it.onAddEmoji(emoji) } })
}
}

View File

@ -1,5 +1,6 @@
package com.fastaccess.ui.modules.gists.create.dialog
import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.os.Parcelable
@ -19,6 +20,7 @@ import com.fastaccess.helper.BundleConstant
import com.fastaccess.helper.Bundler
import com.fastaccess.helper.InputHelper
import com.fastaccess.helper.ViewHelper
import com.fastaccess.provider.emoji.Emoji
import com.fastaccess.provider.markdown.MarkDownProvider
import com.fastaccess.ui.base.BaseDialogFragment
import com.fastaccess.ui.modules.gists.create.dialog.AddGistMvp.AddGistFileListener
@ -114,6 +116,12 @@ class AddGistBottomSheetDialog : BaseDialogFragment<AddGistMvp.View, AddGistPres
}
}
@SuppressLint("SetTextI18n")
override fun onEmojiAdded(emoji: Emoji) {
ViewHelper.showKeyboard(editText)
editText.setText("${editText.text} :${emoji.aliases[0]}:")
}
companion object {
val TAG = AddGistBottomSheetDialog::class.java.simpleName!!

View File

@ -2,6 +2,7 @@ package com.fastaccess.ui.modules.gists.create.dialog
import com.fastaccess.data.dao.FilesListModel
import com.fastaccess.ui.base.mvp.BaseMvp
import com.fastaccess.ui.modules.editor.emoji.EmojiMvp
import com.fastaccess.ui.modules.editor.popup.EditorLinkImageMvp
import com.fastaccess.ui.widgets.markdown.MarkDownLayout
@ -10,7 +11,7 @@ import com.fastaccess.ui.widgets.markdown.MarkDownLayout
*/
interface AddGistMvp {
interface View : BaseMvp.FAView, EditorLinkImageMvp.EditorLinkCallback, MarkDownLayout.MarkdownListener
interface View : BaseMvp.FAView, EditorLinkImageMvp.EditorLinkCallback, MarkDownLayout.MarkdownListener, EmojiMvp.EmojiCallback
interface Presenter
interface AddGistFileListener {
fun onFileAdded(file: FilesListModel, position: Int? = -1)

View File

@ -16,6 +16,7 @@ import com.fastaccess.R
import com.fastaccess.helper.InputHelper
import com.fastaccess.helper.ViewHelper
import com.fastaccess.provider.markdown.MarkDownProvider
import com.fastaccess.ui.modules.editor.emoji.EmojiBottomSheet
import com.fastaccess.ui.modules.editor.popup.EditorLinkImageDialogFragment
/**
@ -67,19 +68,21 @@ class MarkDownLayout : LinearLayout {
@OnClick(R.id.headerOne, R.id.headerTwo, R.id.headerThree, R.id.bold, R.id.italic, R.id.strikethrough,
R.id.bullet, R.id.header, R.id.code, R.id.numbered, R.id.quote, R.id.link, R.id.image,
R.id.unCheckbox, R.id.checkbox, R.id.inlineCode)
R.id.unCheckbox, R.id.checkbox, R.id.inlineCode, R.id.addEmoji)
fun onActions(v: View) {
markdownListener?.let {
it.getEditText().let { editText ->
if (!editText.isEnabled) {
Snackbar.make(this, R.string.error_highlighting_editor, Snackbar.LENGTH_SHORT).show()
} else {
if (v.id == R.id.link) {
EditorLinkImageDialogFragment.newInstance(true).show(it.fragmentManager(), "BannerDialogFragment")
} else if (v.id == R.id.image) {
EditorLinkImageDialogFragment.newInstance(false).show(it.fragmentManager(), "BannerDialogFragment")
} else {
onActionClicked(editText, v.id)
when {
v.id == R.id.link -> EditorLinkImageDialogFragment.newInstance(true).show(it.fragmentManager(), "BannerDialogFragment")
v.id == R.id.image -> EditorLinkImageDialogFragment.newInstance(false).show(it.fragmentManager(), "BannerDialogFragment")
v.id == R.id.addEmoji -> {
ViewHelper.hideKeyboard(it.getEditText())
EmojiBottomSheet().show(it.fragmentManager(), "EmojiBottomSheet")
}
else -> onActionClicked(editText, v.id)
}
}
}

View File

@ -30,6 +30,7 @@ public abstract class BaseRecyclerAdapter<M, VH extends BaseViewHolder,
private GuideListener guideListener;
private boolean progressAdded;
protected BaseRecyclerAdapter() {
this(new ArrayList<>());
}
@ -43,6 +44,10 @@ public abstract class BaseRecyclerAdapter<M, VH extends BaseViewHolder,
this.listener = listener;
}
protected BaseRecyclerAdapter(@Nullable P listener) {
this(new ArrayList<>(), listener);
}
protected abstract VH viewHolder(ViewGroup parent, int viewType);
protected abstract void onBindView(VH holder, int position);

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="?android:windowBackground"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="?android:toolbarStyle">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:theme="?android:toolbarStyle"
app:contentInsetStart="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:orientation="horizontal">
<com.fastaccess.ui.widgets.ForegroundImageView
android:id="@+id/search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/search"
android:padding="@dimen/spacing_normal"
android:src="@drawable/ic_search"/>
<com.fastaccess.ui.widgets.FontEditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/transparent"
android:hint="@string/search"
android:paddingEnd="@dimen/spacing_xs_large"
android:paddingStart="@dimen/spacing_xs_large"/>
</LinearLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:windowBackground">
<com.fastaccess.ui.widgets.recyclerview.DynamicRecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="250dp"
app:layoutManager="@string/grid_layout_manager"
app:spanCount="5"/>
<com.fastaccess.ui.widgets.recyclerview.scroll.RecyclerViewFastScroller
android:id="@+id/fastScroller"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignBottom="@+id/recycler"
android:layout_alignParentEnd="true"
android:layout_alignTop="@+id/recycler"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
</LinearLayout>

View File

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="@layout/editor_layout">
<HorizontalScrollView
android:id="@+id/editorIconsHolder"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_weight="1"
android:fadeScrollbars="true"
android:scrollbarFadeDuration="500"
android:scrollbarSize="1dp"
@ -166,7 +166,7 @@
android:layout_height="wrap_content"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/link"
android:padding="@dimen/spacing_normal"
android:padding="@dimen/spacing_micro"
android:src="@drawable/ic_insert_link"/>
@ -183,6 +183,16 @@
</HorizontalScrollView>
<com.fastaccess.ui.widgets.ForegroundImageView
android:id="@+id/addEmoji"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/reactions"
android:padding="@dimen/spacing_normal"
android:src="@drawable/ic_add_emoji"/>
<com.fastaccess.ui.widgets.ForegroundImageView
android:id="@+id/view"
android:layout_width="wrap_content"

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:foreground="?selectableItemBackground"
android:gravity="center"
android:padding="@dimen/spacing_micro">
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/emoji"
style="@style/TextAppearance.AppCompat.Title"
android:layout_width="@dimen/header_icon_zie"
android:layout_height="@dimen/header_icon_zie"
android:gravity="center"
android:textSize="26sp"
tools:text="Hello"/>
</FrameLayout>