├── .gitignore ├── .idea ├── .gitignore ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── compiler.xml ├── jarRepositories.xml ├── misc.xml └── runConfigurations.xml ├── APK └── FitWidthTextView_1.2.0.apk ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── cc │ │ └── fitwidth │ │ └── widget │ │ ├── FitWidthTextView.kt │ │ ├── MainActivity.kt │ │ ├── MyClickSpan.kt │ │ └── emoji │ │ ├── EmojiManager.java │ │ ├── EmojiRange.java │ │ ├── GoogleEmoji.java │ │ ├── GoogleEmojiProvider.java │ │ ├── category │ │ ├── ActivitiesCategory.java │ │ ├── ActivitiesCategoryChunk0.java │ │ ├── AnimalsAndNatureCategory.java │ │ ├── AnimalsAndNatureCategoryChunk0.java │ │ ├── CategoryUtils.java │ │ ├── FlagsCategory.java │ │ ├── FlagsCategoryChunk0.java │ │ ├── FlagsCategoryChunk1.java │ │ ├── FoodAndDrinkCategory.java │ │ ├── FoodAndDrinkCategoryChunk0.java │ │ ├── ObjectsCategory.java │ │ ├── ObjectsCategoryChunk0.java │ │ ├── SmileysAndPeopleCategory.java │ │ ├── SmileysAndPeopleCategoryChunk0.java │ │ ├── SmileysAndPeopleCategoryChunk1.java │ │ ├── SymbolsCategory.java │ │ ├── SymbolsCategoryChunk0.java │ │ ├── TravelAndPlacesCategory.java │ │ └── TravelAndPlacesCategoryChunk0.java │ │ ├── core │ │ ├── CacheKey.java │ │ ├── Emoji.java │ │ ├── EmojiCategory.java │ │ └── RangeBean.kt │ │ └── read.txt │ └── res │ ├── layout │ └── activity_main.xml │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ └── values │ ├── colors.xml │ ├── strings.xml │ └── themes.xml ├── build.gradle ├── com_ab.jks ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── image ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png └── 6.gif └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | ###### https://github.com/github/gitignore ###### 2 | # Built application files 3 | *.apk 4 | *.ap_ 5 | *.aab 6 | 7 | # Files for the ART/Dalvik VM 8 | *.dex 9 | 10 | # Java class files 11 | *.class 12 | 13 | # Generated files 14 | bin/ 15 | gen/ 16 | out/ 17 | release/ 18 | 19 | # Gradle files 20 | .gradle/ 21 | build/ 22 | 23 | # Local configuration file (sdk path, etc) 24 | local.properties 25 | 26 | # Proguard folder generated by Eclipse 27 | proguard/ 28 | 29 | # Log Files 30 | *.log 31 | 32 | # Android Studio Navigation editor temp files 33 | .navigation/ 34 | 35 | # Android Studio captures folder 36 | captures/ 37 | 38 | # IntelliJ 39 | *.iml 40 | .idea/workspace.xml 41 | .idea/tasks.xml 42 | .idea/gradle.xml 43 | .idea/assetWizardSettings.xml 44 | .idea/dictionaries 45 | .idea/libraries 46 | # Android Studio 3 in .gitignore file. 47 | .idea/caches 48 | .idea/modules.xml 49 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 50 | .idea/navEditor.xml 51 | 52 | # Keystore files 53 | # Uncomment the following lines if you do not want to check your keystore files in. 54 | #*.jks 55 | #*.keystore 56 | 57 | # External native build folder generated in Android Studio 2.2 and later 58 | .externalNativeBuild 59 | 60 | # Google Services (e.g. APIs or Firebase) 61 | # google-services.json 62 | 63 | # Freeline 64 | freeline.py 65 | freeline/ 66 | freeline_project_description.json 67 | 68 | # fastlane 69 | fastlane/report.xml 70 | fastlane/Preview.html 71 | fastlane/screenshots 72 | fastlane/test_output 73 | fastlane/readme.md 74 | 75 | # Version control 76 | vcs.xml 77 | 78 | # lint 79 | lint/intermediates/ 80 | lint/generated/ 81 | lint/outputs/ 82 | lint/tmp/ 83 | # lint/reports/ 84 | ###################################################### 85 | class_files.txt -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 116 | 117 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | 29 | 30 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /APK/FitWidthTextView_1.2.0.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khaos116/FitWidthTextView/253e1603005c88660246043ad6053aa9253956dc/APK/FitWidthTextView_1.2.0.apk -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FitWidthTextView 2 | ###
1.解决TextView中英文排版自动换行参差不齐、提前换行、断行问题
3 | ###
2.解决其他自定义文本控件绘制Emoji不兼容问题
4 | ###
3.解决其他自定义文本控件绘制Span不兼容问题
5 | ###
4.支持段落间距倍数设置、支持段落缩进空格设置
6 | ###
5.自动化处理多个空白行、支持设置最大连续空格数(Span一律不处理)
7 | ###
6.支持ForegroundColorSpan、BackgroundColorSpan以及MyClickSpan(内置)
8 | 9 | ### 下载演示[Demo](https://raw.githubusercontent.com/Khaos116/FitWidthTextView/master/APK/FitWidthTextView_1.2.0.apk) 10 | 11 | 感谢[Emoji](https://github.com/vanniktech/Emoji)提供判断Emoji逻辑 12 | 感谢[LineBreakTextView](https://github.com/changer0/LineBreakTextView)提供参考 13 | 感谢[MTextView](https://github.com/yellowcath/MTextView)提供参考 14 | 15 | //================================================================// 16 | ## 中文(貌似和原TextView无区别) 17 | ![中文展示](https://github.com/Khaos116/FitWidthTextView/blob/master/image/1.png) 18 | 19 | //================================================================// 20 | ## 英文(解决换行问题) 21 | ![英文展示](https://github.com/Khaos116/FitWidthTextView/blob/master/image/2.png) 22 | 23 | //================================================================// 24 | ## Emoji(貌似和原TextView无区别) 25 | ![Emoji展示](https://github.com/Khaos116/FitWidthTextView/blob/master/image/3.png) 26 | 27 | //================================================================// 28 | ## 混合(解决换行问题) 29 | ![混合展示](https://github.com/Khaos116/FitWidthTextView/blob/master/image/4.png) 30 | 31 | //================================================================// 32 | ## Span展示(只支持前景/背景类型的Span+MyClickSpan) 33 | ![Span展示](https://github.com/Khaos116/FitWidthTextView/blob/master/image/5.png) 34 | ![MyClickSpan展示](https://github.com/Khaos116/FitWidthTextView/blob/master/image/6.gif) -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'kotlin-android' 4 | id 'kotlin-android-extensions' 5 | } 6 | 7 | android { 8 | compileSdkVersion 30 9 | 10 | defaultConfig { 11 | applicationId "com.cc.fitwidth" 12 | minSdkVersion 23 13 | targetSdkVersion 30 14 | versionCode 120 15 | versionName "1.2.0" 16 | //APK名称 17 | archivesBaseName = "FitWidthTextView_v$versionName" 18 | } 19 | 20 | //配置不同版本的keystore 21 | signingConfigs { 22 | debug { 23 | storeFile file(STORE_FILE_ABASE) 24 | storePassword STORE_PASSWORD_ABASE 25 | keyAlias KEY_ALIAS_ABASE 26 | keyPassword KEY_PASSWORD_ABASE 27 | } 28 | release { 29 | storeFile file(STORE_FILE_ABASE) 30 | storePassword STORE_PASSWORD_ABASE 31 | keyAlias KEY_ALIAS_ABASE 32 | keyPassword KEY_PASSWORD_ABASE 33 | } 34 | } 35 | 36 | //正式和测试配置 37 | buildTypes { 38 | debug { 39 | debuggable true 40 | zipAlignEnabled false 41 | shrinkResources false 42 | minifyEnabled false 43 | signingConfig signingConfigs.debug 44 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 45 | } 46 | release { 47 | debuggable false 48 | zipAlignEnabled true 49 | shrinkResources true 50 | minifyEnabled true 51 | signingConfig signingConfigs.release 52 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 53 | } 54 | } 55 | 56 | compileOptions { 57 | sourceCompatibility JavaVersion.VERSION_1_8 58 | targetCompatibility JavaVersion.VERSION_1_8 59 | } 60 | kotlinOptions { 61 | jvmTarget = '1.8' 62 | } 63 | } 64 | 65 | dependencies { 66 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 67 | implementation 'androidx.appcompat:appcompat:1.3.0' 68 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/FitWidthTextView.kt: -------------------------------------------------------------------------------- 1 | package com.cc.fitwidth.widget 2 | 3 | import android.annotation.SuppressLint 4 | import android.content.Context 5 | import android.graphics.Canvas 6 | import android.graphics.Paint 7 | import android.text.* 8 | import android.text.style.* 9 | import android.util.AttributeSet 10 | import android.view.MotionEvent 11 | import androidx.appcompat.widget.AppCompatTextView 12 | import com.cc.fitwidth.widget.emoji.EmojiManager 13 | import com.cc.fitwidth.widget.emoji.core.Range 14 | import com.cc.fitwidth.widget.emoji.core.RangeBean 15 | import java.util.regex.Matcher 16 | import java.util.regex.Pattern 17 | 18 | /** 19 | * @Description 主要解决TextView中英文符号换行参差不齐、提前断行/换行、Emoji兼容和Span兼容的问题 20 | * 21 | * 功能说明: 22 | * 1.FitWidthTextView解决了中英文符号等还可以显示就换行导致文本参差不齐的bug 23 | * 2.FitWidthTextView解决了网络上很多自定义文本绘制拆分出现Emoji异常的bug 24 | * 3.FitWidthTextView支持段落缩进和段间距倍数设置(倍数基数为绘制的文本高度) 25 | * 4.FitWidthTextView会自动删除多个空白行(多个换行符、换行符+空格的多个循环组合) 26 | * 5.FitWidthTextView支持设置最大空格处理(比如文本中有连续的8个空格,则会缩减至指定的个数) 27 | * 注意事项: 28 | * 1.如果要修改文字大小和颜色,请在设置文字之前进行设置,最好最后一步设置文字,因为涉及到绘制前的准备 29 | * 2.由于是自定义绘制的文字,所以无法使用TextView的gravity属性 30 | * 3.FitWidthTextView控件的宽度不能太小,否则可能出现异常(至少要保证最大的一个Emoji能显示全) 31 | * 4.由于控件支持了Emoji的段行处理,所以拷贝了三方的Emoji判断部分,导致文件较多(20多个文件) 32 | * 5.由于采用的for循环处理文本,所以如果文本太长可能导致ANR,需要自己修改处理文本部分 33 | * 6.为了防止多次测量文本高度,采用了临时变量的方式防止重复测量,如果遇到测量问题,可能需要修改 34 | * 7.由于Emoji一直在更新,所以可能遇到Emoji数据显示不全的问题,这需要更新Emoji库 35 | * 8.支持前景和背景色改变的Span、MyClickSpan 36 | * 37 | * @Author:Khaos 38 | * @Date:2021-07-10 39 | * @Time:14:59 40 | */ 41 | class FitWidthTextView @kotlin.jvm.JvmOverloads constructor( 42 | context: Context, 43 | attrs: AttributeSet? = null, 44 | defStyleAttr: Int = 0 45 | ) : AppCompatTextView(context, attrs, defStyleAttr) { 46 | // 47 | //分段文字(每段文字由"整行文字"+"类型:0普通1背景色2前景色3背景和前景色"+"开始+结束位置+颜色") 48 | private var mLineList = mutableListOf() 49 | 50 | //用于测量字符宽度 51 | private var mPaint = TextPaint(Paint.ANTI_ALIAS_FLAG) //抗锯齿 52 | 53 | //段间距 倍数(需要大于1且大于行间距】(文字绘制高度 * 倍数 = 绘制间距) 54 | var mParagraphMultiplier: Float = 1.0f 55 | 56 | //段行缩进空格(中文情况下的缩进,非中文会自动切换) 57 | var mParagraphSpace: String = " " 58 | 59 | //首行缩进 60 | var mFirstParagraphSpace: String = "" 61 | 62 | //允许最大的连续空格数量 63 | var mMaxConsecutiveSpace: Int = 4 64 | // 65 | 66 | //// 67 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 68 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 69 | if (text.isNotBlank()) { 70 | val widthMode = MeasureSpec.getMode(widthMeasureSpec) 71 | val heightMode = MeasureSpec.getMode(heightMeasureSpec) 72 | val widthSize = MeasureSpec.getSize(widthMeasureSpec) 73 | val heightSize = MeasureSpec.getSize(heightMeasureSpec) 74 | val width: Int = when (widthMode) { 75 | MeasureSpec.UNSPECIFIED -> context.resources.displayMetrics.widthPixels 76 | else -> widthSize 77 | } 78 | val height: Int = when (heightMode) { 79 | MeasureSpec.EXACTLY -> heightSize 80 | else -> (measureContentHeight(text, width - paddingStart - paddingEnd) + 1).toInt() 81 | } 82 | setMeasuredDimension(width, height) 83 | } 84 | } 85 | 86 | override fun setText(text: CharSequence?, type: BufferType?) { 87 | super.setText(text, type) 88 | requestLayout() 89 | } 90 | 91 | @SuppressLint("DrawAllocation") 92 | override fun onDraw(canvas: Canvas) { 93 | mLineList.let { l -> 94 | //文字位置参考https://github.com/changer0/LineBreakTextView 貌似绘制位置是以baseline为准的 95 | val fontMetrics = mPaint.fontMetrics 96 | //文字偏移量 97 | val offSet = mPaint.baselineShift - fontMetrics.top 98 | //文字实际绘制高度 99 | val lineHeight = fontMetrics.bottom - fontMetrics.top 100 | //每行累计高度 101 | var drawHeight = paddingTop * 1f 102 | //遍历绘制文本 103 | l.forEach { b -> 104 | val s = b.sb 105 | if (s.toString() != "\n") { 106 | //绘制背景 107 | for (rangeBg in b.ranges) { 108 | if (rangeBg.type == 1 || rangeBg.type == 3) { 109 | mPaint.color = rangeBg.bgColor 110 | val start = paddingStart * 1f + mPaint.measureText(s, 0, rangeBg.start) 111 | val end = paddingStart * 1f + mPaint.measureText(s, 0, rangeBg.end) 112 | canvas.drawRect(start, drawHeight, end, drawHeight + lineHeight, mPaint) 113 | } 114 | } 115 | //分段绘制文本 116 | for (rFore in b.ranges) { 117 | if (rFore.type == 2 || rFore.type == 3) { //绘制有前景色的文本 118 | mPaint.color = rFore.foreColor 119 | val start = paddingStart * 1f + mPaint.measureText(s, 0, rFore.start) 120 | canvas.drawText(s, rFore.start, rFore.end, start, drawHeight + offSet, mPaint) 121 | } else { //绘制普通文本 122 | val first = mPressRanges.firstOrNull { r -> r == rFore } //判断是否是按压状态 123 | mPaint.color = when { 124 | first != null -> (first.clickSpan as? MyClickSpan)?.mPressSpanColor ?: currentTextColor 125 | rFore.clickSpan != null -> (rFore.clickSpan as? MyClickSpan)?.mNormalSpanColor ?: currentTextColor 126 | else -> currentTextColor 127 | } 128 | val start = paddingStart * 1f + mPaint.measureText(s, 0, rFore.start) 129 | val w = mPaint.measureText(s, rFore.start, rFore.end) 130 | if ((rFore.clickSpan as? MyClickSpan)?.showUnderLine == true) { 131 | //绘制下划线 132 | canvas.drawRect(start, drawHeight + lineHeight - 1.3f, start + w, drawHeight + lineHeight, mPaint) 133 | } 134 | canvas.drawText(s, rFore.start, rFore.end, start, drawHeight + offSet, mPaint) 135 | } 136 | } 137 | drawHeight += lineHeight + lineHeight * (lineSpacingMultiplier - 1f) 138 | } else { 139 | //如果段间距不大于行间距,则不添加行间距;否则添加间距为"段间距-行间距"(因为默认底部有一个行间距) 140 | drawHeight += if (mParagraphMultiplier > lineSpacingMultiplier) { 141 | lineHeight * (mParagraphMultiplier - lineSpacingMultiplier) 142 | } else 0f 143 | } 144 | } 145 | } 146 | } 147 | // 148 | 149 | // 150 | private var mLastCs: CharSequence = "" 151 | private var mLastAvailableWidth: Int = 0 152 | private var mLastHeight: Float = 0f 153 | private var mLastTextSize: Float = 0f 154 | 155 | //测量高度(Span不能被破坏,否则会找不到起始位置,所以先进行span的保留) 156 | private fun measureContentHeight(text: CharSequence, availableWidth: Int): Float { 157 | //----------------------------------防止重复走----------------------------------// 158 | if (text.isBlank()) return 0f 159 | if (mLastCs == text && mLastAvailableWidth == availableWidth && mLastTextSize == textSize) return mLastHeight 160 | mLastCs = text 161 | mLastTextSize = textSize 162 | mLastAvailableWidth = availableWidth 163 | //文字绘制大小 164 | mPaint.textSize = textSize 165 | //文字绘制的实际高度 166 | val lineHeight = mPaint.fontMetrics.bottom - mPaint.fontMetrics.top 167 | //----------------------------------没有中文缩进自动减半----------------------------------// 168 | var tempSpaceFirst = mFirstParagraphSpace 169 | if (mFirstParagraphSpace.length > 2 && !isContainChinese(text.toString())) { 170 | tempSpaceFirst = mFirstParagraphSpace.substring(mFirstParagraphSpace.length / 2) 171 | } 172 | var tempSpace = mParagraphSpace 173 | if (mParagraphSpace.length > 2 && !isContainChinese(text.toString())) { 174 | tempSpace = mParagraphSpace.substring(mParagraphSpace.length / 2) 175 | } 176 | //----------------------------------Span分隔(文字+颜色)----------------------------------// 177 | val splits = mutableListOf() 178 | //添加首行缩进 179 | if (mFirstParagraphSpace.isNotEmpty()) splits.add(RangeBean(tempSpaceFirst)) 180 | if (text is SpannedString) { 181 | val spans = text.getSpans(0, text.length, CharacterStyle::class.java) 182 | if (spans.isNullOrEmpty()) { //没有找到span 183 | splits.add(RangeBean(dealSpaceBreak(text, tempSpace))) 184 | } else { 185 | var index = 0 186 | for (span in spans) { //将普通文本和Span分隔 187 | val start = text.getSpanStart(span) 188 | val end = text.getSpanEnd(span) 189 | if (start > index) { //添加非span 190 | splits.add(RangeBean(dealSpaceBreak(text.subSequence(index, start), tempSpace))) 191 | } 192 | //获取当前span文本 193 | val txt = text.subSequence(start, end) 194 | //判断span 195 | if (span is BackgroundColorSpan && span is ForegroundColorSpan) { 196 | splits.add(RangeBean(txt, mutableListOf(Range(type = 3, bgColor = span.backgroundColor, foreColor = span.foregroundColor)))) 197 | } else if (span is BackgroundColorSpan) { 198 | splits.add(RangeBean(txt, mutableListOf(Range(type = 1, bgColor = span.backgroundColor)))) 199 | } else if (span is ForegroundColorSpan) { 200 | splits.add(RangeBean(txt, mutableListOf(Range(type = 2, foreColor = span.foregroundColor)))) 201 | } else if (span is ClickableSpan) { 202 | splits.add(RangeBean(txt, mutableListOf(Range(type = 4, clickSpan = span)))) 203 | } else { 204 | splits.add(RangeBean(dealSpaceBreak(txt, tempSpace))) 205 | } 206 | index = end 207 | } 208 | if (index < text.length) splits.add(RangeBean(dealSpaceBreak(text.subSequence(index, text.length), tempSpace))) 209 | } 210 | } else { 211 | splits.add(RangeBean(dealSpaceBreak(text, tempSpace))) 212 | } 213 | //----------------------------------换行分隔----------------------------------// 214 | //处理后的分行文本(一个为一行) 215 | val resultList = mutableListOf() 216 | //拼接裁切后剩余不足一行的部分 217 | val remainSb = SpannableStringBuilder() 218 | //非普通文本的范围 219 | var remainRange = mutableListOf() 220 | //循环拼接 221 | for (index in 0 until splits.size) { 222 | val split = splits[index] 223 | //如果不是普通文本,则拼接后重新计算位置 224 | split.ranges.firstOrNull { f -> f.type != 0 }?.let { r -> 225 | r.start = remainSb.length 226 | r.end = r.start + split.sb.length 227 | remainRange.add(r) 228 | } 229 | //剩余的加上现在的再测量 230 | remainSb.append(split.sb) 231 | //测量拼接后的长度 232 | val w = mPaint.measureText(remainSb, 0, remainSb.length) 233 | if (w < availableWidth && !remainSb.toString().contains("\n")) { //填不满宽度并且没有换行符,累计临时值 234 | if (index == splits.size - 1) { //如果是最后一个了 235 | resultList.add(RangeBean(remainSb.subSequence(0, remainSb.length), remainRange)) 236 | remainSb.delete(0, remainSb.length) 237 | remainRange = mutableListOf() 238 | break 239 | } else continue 240 | } else { //大于宽度,需要裁切 241 | //只要有换行符或者能填满宽度,就继续处理 242 | while (remainSb.toString().contains("\n") || mPaint.measureText(remainSb, 0, remainSb.length) >= availableWidth) { 243 | //找出所有emoji表情 244 | val emojis = EmojiManager.getInstance().findAllEmojis(remainSb) 245 | for (i in remainSb.indices) { //遍历判断长度 246 | //遇到换行符的处理 247 | if (remainSb.subSequence(i, i + 1).toString() == "\n") { 248 | //裁切 249 | val txt = remainSb.subSequence(0, i) 250 | remainSb.delete(0, i + 1) 251 | //被裁切的span 252 | val splitRange = remainRange.filter { r -> r.end < (txt.length + 1) }.toMutableList() 253 | //span被分隔的处理 254 | val cutSpan = remainRange.firstOrNull { f -> (txt.length + 1) in f.start..f.end } 255 | //新余下的span 256 | remainRange = remainRange.filter { r -> r.start > (txt.length + 1) }.map { r -> 257 | r.start -= (txt.length + 1) 258 | r.end -= (txt.length + 1) 259 | r 260 | }.toMutableList() 261 | //分隔成2个span 262 | if (cutSpan != null) { 263 | val span1 = cutSpan.copy(end = txt.length, split = true) 264 | val span2 = cutSpan.copy(start = 0, end = cutSpan.end - (txt.length + 1), split = true) 265 | splitRange.add(span1) //添加到最后 266 | remainRange.add(0, span2) //添加到最前面 267 | } 268 | resultList.add(RangeBean(txt, splitRange)) 269 | //确保最后一个不是换行符 270 | if (!(index == splits.size - 1 && i == remainSb.length - 1)) { 271 | resultList.add(RangeBean("\n")) 272 | } 273 | break 274 | } 275 | val w2 = mPaint.measureText(remainSb, 0, i + 1) 276 | if (w2 == 0f) continue //可能测量到空制符 277 | if (w2 >= availableWidth * 1f) { //需要换行了 278 | //优先判断是否会分隔Emoji 279 | val emojiRange = emojis.firstOrNull { e -> i in e.start until e.end } 280 | //文本裁切结束位置 281 | var end = i + (if (w2 == availableWidth * 1f) 1 else 0) //多一个字符刚好,则添加最后一个字符到本行 282 | if (emojiRange != null) { //如果Emoji被拆分了 283 | //测试是否可用完整显示,如果不行就拆到下一行(有可能不完整的Emoji放不下,完整的反而可用放下) 284 | val w3 = mPaint.measureText(remainSb, 0, emojiRange.end) 285 | end = if (w3 > maxWidth) { //换到下一行 286 | emojiRange.start 287 | } else { //本行结束 288 | emojiRange.end 289 | } 290 | } 291 | //裁切 292 | val txt = remainSb.subSequence(0, end) 293 | remainSb.delete(0, end) 294 | //被裁切的span 295 | val splitRange = remainRange.filter { r -> r.end < txt.length }.toMutableList() 296 | //span被分隔的处理 297 | val cutSpan = remainRange.firstOrNull { f -> txt.length in f.start..f.end } 298 | //新余下的span 299 | remainRange = remainRange.filter { r -> r.start > txt.length }.map { r -> 300 | r.start -= txt.length 301 | r.end -= txt.length 302 | r 303 | }.toMutableList() 304 | //分隔成2个span 305 | if (cutSpan != null) { 306 | val span1 = cutSpan.copy(end = txt.length, split = true) 307 | val span2 = cutSpan.copy(start = 0, end = cutSpan.end - txt.length, split = true) 308 | splitRange.add(span1) //添加到最后 309 | remainRange.add(0, span2) //添加到最前面 310 | } 311 | resultList.add(RangeBean(txt, splitRange)) 312 | break 313 | } 314 | } 315 | } 316 | //如果是最后一个了 317 | if (index == splits.size - 1 && remainSb.isNotEmpty()) { 318 | resultList.add(RangeBean(remainSb.subSequence(0, remainSb.length), remainRange)) 319 | remainSb.delete(0, remainSb.length) 320 | remainRange = mutableListOf() 321 | break 322 | } 323 | } 324 | } 325 | val countBreak = resultList.count { r -> r.sb.toString() == "\n" } 326 | var totalHeight = countBreak * (lineHeight * (mParagraphMultiplier - 1f)) + (resultList.size - countBreak) * (lineHeight * lineSpacingMultiplier) 327 | if (resultList.isNotEmpty()) totalHeight -= lineHeight * (lineSpacingMultiplier - 1f) //最后一行不要行间距 328 | mLastHeight = totalHeight + paddingTop + paddingBottom 329 | //处理普通文字的范围 330 | resultList.forEach { bean -> 331 | if (bean.ranges.isEmpty()) { //没有span的情况 332 | bean.ranges.add(Range(0, bean.sb.length)) 333 | } else { //有span的情况 334 | val newList = mutableListOf() 335 | var index = 0 336 | for (range in bean.ranges) { 337 | if (range.start > index) newList.add(Range(index, range.start)) //普通文字 338 | newList.add(range) 339 | index = range.end 340 | } 341 | if (index < bean.sb.length) newList.add(Range(index, bean.sb.length)) //普通文字 342 | bean.ranges.clear() 343 | bean.ranges.addAll(newList) 344 | } 345 | } 346 | mLineList.clear() 347 | mLineList.addAll(resultList) 348 | return mLastHeight 349 | } 350 | 351 | //普通文本处理多个空白行和空格保留问题 352 | private fun dealSpaceBreak(cs: CharSequence, paragraphSpace: String): CharSequence { 353 | val sb = StringBuilder() //处理后的文本 354 | val sbSpace = StringBuilder() //临时存放空格,可以设置最大连续数量 355 | for (c in cs) { //遍历每个字符 356 | if (c.toString() == "\r") continue //不处理 357 | if (c.toString() == " " || c.toString() == "\t") { //空格处理 358 | val endSpaceBreak = sb.toString().endsWith("\n") || sb.toString().endsWith(" ") || sb.toString().endsWith("\t") 359 | if (sb.isNotEmpty() && !endSpaceBreak && sbSpace.length < mMaxConsecutiveSpace) sbSpace.append(" ") //文本最开始不加空格,超过最大数量不加空格 360 | } else if (c.toString() == "\n") { 361 | if (sbSpace.isNotEmpty()) sbSpace.delete(0, sbSpace.length) //遇到换行则把想要添加的空格移除,直接添加换行符 362 | val endBreak = sb.toString().replace(" ", "").replace("\t", "").endsWith("\n") 363 | if (sb.isNotEmpty() && !endBreak) { //文本不为空,且不以换行结尾才添加换行 364 | sb.append("\n") 365 | if (paragraphSpace.isNotEmpty()) { 366 | sb.append(paragraphSpace) //添加段落缩进 367 | sbSpace.delete(0, sbSpace.length) //删除需要添加的空格 368 | } 369 | } 370 | } else { 371 | if (sbSpace.isNotEmpty()) { //文本中间需要的空格添加 372 | sb.append(sbSpace.toString()) 373 | sbSpace.delete(0, sbSpace.length) //添加完成后删除临时空格 374 | } 375 | sb.append(c) //正常添加字符 376 | } 377 | } 378 | return sb 379 | } 380 | 381 | //判断是否包含中文 382 | private fun isContainChinese(str: String): Boolean { 383 | val p: Pattern = Pattern.compile("[\\u4e00-\\u9fa5]") 384 | val m: Matcher = p.matcher(str) 385 | return m.find() 386 | } 387 | // 388 | 389 | // 390 | //按压的ClickSpan范围 391 | private var mPressRanges: MutableList = mutableListOf() 392 | 393 | @SuppressLint("ClickableViewAccessibility") 394 | override fun onTouchEvent(event: MotionEvent?): Boolean { 395 | if (mLineList.isNotEmpty()) event?.let { ev -> 396 | when (ev.action and MotionEvent.ACTION_MASK) { 397 | MotionEvent.ACTION_DOWN -> { 398 | //清除上次的数据 399 | mPressRanges.clear() 400 | //按压位置 401 | val x = ev.x 402 | val y = ev.y 403 | //计算正常绘制行高 404 | val fontMetrics = mPaint.fontMetrics 405 | val lineHeight = fontMetrics.bottom - fontMetrics.top 406 | //第一行开始位置的顶部 407 | var drawHeight = paddingTop * 1f 408 | //点击的该行文字 409 | var clickRangeBean: RangeBean? = null 410 | for (b in mLineList) { //遍历通过高度找到该行文字 411 | val s = b.sb 412 | drawHeight += if (s.toString() != "\n") { 413 | lineHeight + lineHeight * (lineSpacingMultiplier - 1f) 414 | } else { 415 | if (mParagraphMultiplier > lineSpacingMultiplier) lineHeight * (mParagraphMultiplier - lineSpacingMultiplier) else 0f 416 | } 417 | clickRangeBean = b 418 | if (drawHeight >= y) break 419 | } 420 | clickRangeBean?.let { range -> //找到对应的span 421 | //找到所有clickSpan的范围 422 | val clickRanges = mutableListOf() 423 | (range.sb as? SpannableStringBuilder)?.let { ssb -> 424 | ssb.getSpans(0, ssb.length, MyClickSpan::class.java)?.forEach { clickSpan -> 425 | clickRanges.add(Range(ssb.getSpanStart(clickSpan), ssb.getSpanEnd(clickSpan))) 426 | } 427 | } 428 | if (clickRanges.isNotEmpty()) for (i in 0 until range.ranges.size) { 429 | val r = range.ranges[i] 430 | if (r.type == 4) { //clickSpan才进行处理 431 | val start = paddingStart * 1f + mPaint.measureText(range.sb, 0, r.start) 432 | val end = paddingStart * 1f + mPaint.measureText(range.sb, 0, r.end) 433 | if (x in start..end) { //找到range 434 | val clickRange = clickRanges.firstOrNull { t -> r.start >= t.start && r.end <= t.end } 435 | if (clickRange != null) { //如果处于clickSpan的范围 436 | mPressRanges.add(r) 437 | if (r.split) { //被拆分的,需要找到多行 438 | val index = mLineList.indexOf(range) 439 | if (r.start == 0 && index > 0) { //上面是被拆分的 440 | for (j in index - 1 downTo 0) { 441 | val line = mLineList[j] 442 | val rt = line.ranges.last() 443 | if (rt.split) mPressRanges.add(0, rt) 444 | if (line.ranges.size > 1) break //如果有多段,则不可能还是同一个拆分 445 | } 446 | } 447 | if (r.end == range.sb.length && index < mLineList.size - 1) { //下面可能是被拆分的 448 | for (j in index + 1 until mLineList.size) { 449 | val line = mLineList[j] 450 | val rt = line.ranges.first() 451 | if (rt.split) mPressRanges.add(rt) 452 | if (line.ranges.size > 1) break //如果有多段,则不可能还是同一个拆分 453 | } 454 | } 455 | } 456 | invalidate() 457 | return true 458 | } else { 459 | break 460 | } 461 | } 462 | } 463 | } 464 | } 465 | } 466 | MotionEvent.ACTION_MOVE -> { 467 | val x = ev.x 468 | val y = ev.y 469 | val outRange = x < paddingStart || x > width - paddingEnd || y < paddingTop || y > height - paddingBottom 470 | return if (outRange) { //如果移动超出文字绘制范围则取消点击判断 471 | mPressRanges.clear() 472 | invalidate() 473 | false 474 | } else { 475 | super.onTouchEvent(event) 476 | } 477 | } 478 | MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { //响应对应的pan事件 479 | return if (mPressRanges.isNotEmpty()) { 480 | mPressRanges.firstOrNull { r -> r.clickSpan != null }?.clickSpan?.onClick(this) 481 | mPressRanges.clear() 482 | invalidate() 483 | true 484 | } else { 485 | super.onTouchEvent(event) 486 | } 487 | } 488 | else -> { 489 | } 490 | } 491 | } 492 | return super.onTouchEvent(event) 493 | } 494 | // 495 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.cc.fitwidth.widget 2 | 3 | import android.graphics.Color 4 | import android.os.Bundle 5 | import android.text.* 6 | import android.text.style.BackgroundColorSpan 7 | import android.text.style.ForegroundColorSpan 8 | import android.widget.Toast 9 | import androidx.appcompat.app.AppCompatActivity 10 | import com.cc.fitwidth.R 11 | import kotlinx.android.synthetic.main.activity_main.mainTv1 12 | import kotlinx.android.synthetic.main.activity_main.mainTv2 13 | 14 | /** 15 | * 功能说明: 16 | * 1.FitWidthTextView解决了中英文符号等还可以显示就换行导致文本参差不齐的bug 17 | * 2.FitWidthTextView解决了网络上很多自定义文本绘制拆分出现Emoji异常的bug 18 | * 3.FitWidthTextView支持段落缩进和段间距倍数设置(倍数基数为绘制的文本高度) 19 | * 4.FitWidthTextView会自动删除多个空白行(多个换行符、换行符+空格的多个循环组合) 20 | * 5.FitWidthTextView支持设置最大空格处理(比如文本中有连续的8个空格,则会缩减至指定的个数) 21 | * 注意事项: 22 | * 1.如果要修改文字大小和颜色,请在设置文字之前进行设置,最好最后一步设置文字,因为涉及到绘制前的准备 23 | * 2.由于是自定义绘制的文字,所以无法使用TextView的gravity属性 24 | * 3.FitWidthTextView控件的宽度不能太小,否则可能出现异常(至少要保证最大的一个Emoji能显示全) 25 | * 4.由于控件支持了Emoji的段行处理,所以拷贝了三方的Emoji判断部分,导致文件较多(20多个文件) 26 | * 5.由于采用的for循环处理文本,所以如果文本太长可能导致ANR,需要自己修改处理文本部分 27 | * 6.为了防止多次测量文本高度,采用了临时变量的方式防止重复测量,如果遇到测量问题,可能需要修改 28 | * 7.由于Emoji一直在更新,所以可能遇到Emoji数据显示不全的问题,这需要更新Emoji库 29 | */ 30 | class MainActivity : AppCompatActivity() { 31 | //英文 32 | private val text1 = 33 | "This is a TextView that solves the uneven line breaks of mixed text such as Chinese, English, and characters.\nAt the same time, it solves the problem that other custom line breaks on the Internet cause Emoji expressions to be separated and displayed abnormally.\nThere may be some compatibility issues, so let's improve it together." 34 | 35 | //中文 36 | private val text2 = "这是一个解决中文、英文、字符等混合文字换行参差不齐的文字控件。\n同时解决网上其他自定义换行导致Emoji表情被分隔显示异常的问题。\n可能会存在一些兼容性问题,大家一起完善吧。" 37 | 38 | //Emoj 39 | private val text3 = 40 | "\uD83D\uDC36\uD83D\uDC30\uD83E\uDD8A\uD83D\uDC3C\uD83D\uDC2F\uD83D\uDC35\uD83D\uDC37\uD83D\uDC2E\uD83E\uDD81\uD83D\uDC28\uD83D\uDC14\uD83C\uDF3F\uD83C\uDF40\uD83C\uDF38\uD83C\uDF39\uD83C\uDF34\uD83C\uDF32\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDF53\uD83C\uDF4E\uD83C\uDF49\uD83C\uDF4F\uD83C\uDF51\uD83C\uDF89\uD83D\uDEB2\uD83C\uDFC5\uD83D\uDDFD\uD83D\uDC6B\uD83C\uDF1D\uD83D\uDCAF\uD83D\uDC58\uD83D\uDC57" 41 | 42 | //组合 43 | private val text4 = 44 | "\uD83D\uDC36\uD83D\uDC30\uD83E\uDD8A\uD83D\uDC3C\uD83D\uDC2F\uD83D\uDC35\uD83D\uDC37\uD83D\uDC2E\uD83E\uDD81\uD83D\uDC28\uD83D\uDC14\uD83C\uDF3F\uD83C\uDF40\uD83C\uDDE8\uD83C\uDDF3 This is english split\uD83C\uDF38\uD83C\uDF39\uD83C\uDF34\uD83C\uDF32\uD83C\uDF53\uD83C\uDF4E\uD83C\uDF49\uD83C\uDF4F\uD83C\uDF51\uD83C\uDF89\uD83D\uDEB2 中文也会被拆分 \uD83C\uDFC5\uD83D\uDDFD\uD83D\uDC6B\uD83C\uDF1D\uD83D\uDCAF\uD83D\uDC58\uD83D\uDC57 轻浮的女子 Flibbertigibbet \uD83E\uDD22\uD83E\uDD9A\uD83D\uDC71\uD83C\uDFFB\u200D♀️\uD83D\uDD1E\uD83D\uDE45\uD83C\uDFFB\u200D♀️\uD83D\uDC69\uD83C\uDFFB\u200D\uD83D\uDCBB\uD83C\uDFE9\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC67㍿⚅㎇㍰▓\uD83D\uDCBB\uD83C\uDE32\uD83D\uDEB4\uD83C\uDFFB\u200D♂️\uD83C\uDDEC\uD83C\uDDE7✈️" 45 | 46 | //Span测试 47 | private val text5 = SpannableStringBuilder() 48 | 49 | override fun onCreate(savedInstanceState: Bundle?) { 50 | super.onCreate(savedInstanceState) 51 | setContentView(R.layout.activity_main) 52 | val index = System.currentTimeMillis() % 6 53 | val span = SpannableString("中文") 54 | span.setSpan(ForegroundColorSpan(Color.RED), 0, span.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) 55 | val span1 = SpannableString("换行参差不齐") 56 | span1.setSpan(BackgroundColorSpan(Color.LTGRAY), 0, span1.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) 57 | val span2 = SpannableString("Emoji表情被分隔显示异常") 58 | span2.setSpan(ForegroundColorSpan(Color.RED), 0, span2.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) 59 | val span3 = SpannableString("最后以Span结尾。") 60 | span3.setSpan(ForegroundColorSpan(Color.BLUE), 0, span3.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) 61 | val span4 = SpannableString("这是一个很长很长很长的ClickSpan,其长度必须要实现换行拆分到三行显示,如果还不够长,就继续添加显示文字,直到显示三行+。") 62 | span4.setSpan( 63 | MyClickSpan( 64 | mNormalSpanColor = Color.parseColor("#FF018786"), 65 | mPressSpanColor = Color.parseColor("#009ACD"), 66 | showUnderLine = true, 67 | ) { v -> 68 | Toast.makeText(v.context, span4, Toast.LENGTH_SHORT).show() 69 | }, 0, span4.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE 70 | ) 71 | //Span添加 72 | text5.append("这是一个解决") 73 | .append(span) 74 | .append("、英文、字符等混合文字") 75 | .append(span1) 76 | .append("的文字控件。 \n \n \n \n \n \n 同时解决网上其他 自定义换行导致") 77 | .append(span2) 78 | .append("的问题。\n可能会存在一些兼容性问题,大家\n一起完善吧。") 79 | .append(span3) 80 | .append(span4) 81 | //默认带有段落缩进,这里为了对比,去掉缩进 82 | if (index == 0L) { 83 | mainTv1.mFirstParagraphSpace = mainTv1.mParagraphSpace 84 | } else { 85 | mainTv1.mParagraphSpace = "" 86 | } 87 | //设置段间距倍数(倍数为文字绘制高度的倍数) 88 | mainTv1.mParagraphMultiplier = 1.5f 89 | //随机设置文字 90 | val text = when (index) { 91 | 1L -> text1 92 | 2L -> text2 93 | 3L -> text3 94 | 4L -> text4 95 | else -> text5 96 | } 97 | //两种显示对比 98 | mainTv1.text = text 99 | mainTv2.text = text 100 | mainTv1.setOnClickListener { v -> 101 | Toast.makeText(v.context, "点击自定义文本控件", Toast.LENGTH_SHORT).show() 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/MyClickSpan.kt: -------------------------------------------------------------------------------- 1 | package com.cc.fitwidth.widget 2 | 3 | import android.graphics.Color 4 | import android.text.TextPaint 5 | import android.text.style.ClickableSpan 6 | import android.view.View 7 | 8 | /** 9 | * @Description 10 | * @Author:Khaos 11 | * @Date:2021-08-09 12 | * @Time:18:17 13 | */ 14 | class MyClickSpan( 15 | //正常颜色Span颜色 16 | val mNormalSpanColor: Int = Color.BLACK, 17 | //按压Span颜色 18 | val mPressSpanColor: Int = Color.BLACK, 19 | //是否显示下划线 20 | val showUnderLine: Boolean = false, 21 | //点击事件回调 22 | private val mCallClick: ((view: View) -> Unit)? = null 23 | ) : ClickableSpan() { 24 | 25 | override fun onClick(widget: View) { 26 | mCallClick?.invoke(widget) 27 | } 28 | 29 | override fun updateDrawState(ds: TextPaint) { 30 | super.updateDrawState(ds) 31 | ds.isUnderlineText = showUnderLine 32 | } 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/EmojiManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji; 18 | 19 | import androidx.annotation.NonNull; 20 | import androidx.annotation.Nullable; 21 | import com.cc.fitwidth.widget.emoji.core.Emoji; 22 | import com.cc.fitwidth.widget.emoji.core.EmojiCategory; 23 | import java.util.*; 24 | import java.util.regex.Matcher; 25 | import java.util.regex.Pattern; 26 | 27 | /** 28 | * EmojiManager where an EmojiProvider can be installed for further usage. 29 | */ 30 | @SuppressWarnings("PMD.ForLoopCanBeForeach") public final class EmojiManager { 31 | private static final EmojiManager INSTANCE = new EmojiManager(); 32 | private static final int GUESSED_UNICODE_AMOUNT = 3000; 33 | private static final int GUESSED_TOTAL_PATTERN_LENGTH = GUESSED_UNICODE_AMOUNT * 4; 34 | 35 | private static final Comparator STRING_LENGTH_COMPARATOR = (first, second) -> { 36 | final int firstLength = first.length(); 37 | final int secondLength = second.length(); 38 | 39 | return Integer.compare(secondLength, firstLength); 40 | }; 41 | 42 | private final Map emojiMap = new LinkedHashMap<>(GUESSED_UNICODE_AMOUNT); 43 | private EmojiCategory[] categories; 44 | private Pattern emojiPattern; 45 | 46 | private EmojiManager() { 47 | // No instances apart from singleton. 48 | } 49 | 50 | public static EmojiManager getInstance() { 51 | synchronized (EmojiManager.class) { 52 | return INSTANCE; 53 | } 54 | } 55 | 56 | static { 57 | install(new GoogleEmojiProvider()); 58 | } 59 | 60 | /** 61 | * Installs the given EmojiProvider. 62 | * 63 | * NOTE: That only one can be present at any time. 64 | * 65 | * @param provider the provider that should be installed. 66 | */ 67 | public static void install(@NonNull final GoogleEmojiProvider provider) { 68 | synchronized (EmojiManager.class) { 69 | INSTANCE.categories = checkNotNull(provider.getCategories(), "categories == null"); 70 | INSTANCE.emojiMap.clear(); 71 | 72 | final List unicodesForPattern = new ArrayList<>(GUESSED_UNICODE_AMOUNT); 73 | 74 | final int categoriesSize = INSTANCE.categories.length; 75 | //noinspection 76 | for (int i = 0; i < categoriesSize; i++) { 77 | final Emoji[] emojis = checkNotNull(INSTANCE.categories[i].getEmojis(), "emojies == null"); 78 | 79 | final int emojisSize = emojis.length; 80 | //noinspection ForLoopReplaceableByForEach 81 | for (int j = 0; j < emojisSize; j++) { 82 | final Emoji emoji = emojis[j]; 83 | final String unicode = emoji.getUnicode(); 84 | final List variants = emoji.getVariants(); 85 | 86 | INSTANCE.emojiMap.put(unicode, emoji); 87 | unicodesForPattern.add(unicode); 88 | 89 | //noinspection 90 | for (int k = 0; k < variants.size(); k++) { 91 | final Emoji variant = variants.get(k); 92 | final String variantUnicode = variant.getUnicode(); 93 | 94 | INSTANCE.emojiMap.put(variantUnicode, variant); 95 | unicodesForPattern.add(variantUnicode); 96 | } 97 | } 98 | } 99 | 100 | if (unicodesForPattern.isEmpty()) { 101 | throw new IllegalArgumentException("Your EmojiProvider must at least have one category with at least one emoji."); 102 | } 103 | 104 | // We need to sort the unicodes by length so the longest one gets matched first. 105 | Collections.sort(unicodesForPattern, STRING_LENGTH_COMPARATOR); 106 | 107 | final StringBuilder patternBuilder = new StringBuilder(GUESSED_TOTAL_PATTERN_LENGTH); 108 | 109 | final int unicodesForPatternSize = unicodesForPattern.size(); 110 | for (int i = 0; i < unicodesForPatternSize; i++) { 111 | patternBuilder.append(Pattern.quote(unicodesForPattern.get(i))).append('|'); 112 | } 113 | 114 | final String regex = patternBuilder.deleteCharAt(patternBuilder.length() - 1).toString(); 115 | INSTANCE.emojiPattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); 116 | } 117 | } 118 | 119 | /** 120 | * Destroys the EmojiManager. This means that all internal data structures are released as well as 121 | * all data associated with installed {@link Emoji}s. For the existing {@link GoogleEmojiProvider}s this 122 | * means the memory-heavy emoji sheet. 123 | * 124 | * @see #destroy() 125 | */ 126 | public static void destroy() { 127 | synchronized (EmojiManager.class) { 128 | release(); 129 | INSTANCE.emojiMap.clear(); 130 | INSTANCE.categories = null; 131 | INSTANCE.emojiPattern = null; 132 | } 133 | } 134 | 135 | /** 136 | * Releases all data associated with installed {@link Emoji}s. For the existing {@link GoogleEmojiProvider}s this 137 | * means the memory-heavy emoji sheet. 138 | * 139 | * In contrast to {@link #destroy()}, this does not destroy the internal 140 | * data structures and thus, you do not need to {@link #install(GoogleEmojiProvider)} again before using the EmojiManager. 141 | * 142 | * @see #destroy() 143 | */ 144 | public static void release() { 145 | synchronized (EmojiManager.class) { 146 | for (final Emoji emoji : INSTANCE.emojiMap.values()) { 147 | emoji.destroy(); 148 | } 149 | } 150 | } 151 | 152 | @NonNull 153 | public List findAllEmojis(@Nullable final CharSequence text) { 154 | verifyInstalled(); 155 | 156 | final List result = new ArrayList<>(); 157 | 158 | if (text != null && text.length() > 0) { 159 | final Matcher matcher = emojiPattern.matcher(text); 160 | 161 | while (matcher.find()) { 162 | final Emoji found = findEmoji(text.subSequence(matcher.start(), matcher.end())); 163 | 164 | if (found != null) { 165 | result.add(new EmojiRange(matcher.start(), matcher.end(), found)); 166 | } 167 | } 168 | } 169 | 170 | return result; 171 | } 172 | 173 | private @Nullable Emoji findEmoji(@NonNull final CharSequence candidate) { 174 | verifyInstalled(); 175 | 176 | // We need to call toString on the candidate, since the emojiMap may not find the requested entry otherwise, because the type is different. 177 | return emojiMap.get(candidate.toString()); 178 | } 179 | 180 | private void verifyInstalled() { 181 | if (categories == null) { 182 | throw new IllegalStateException("Please install an EmojiProvider through the EmojiManager.install() method first."); 183 | } 184 | } 185 | 186 | private static @NonNull T checkNotNull(@Nullable final T reference, final String message) { 187 | if (reference == null) { 188 | throw new IllegalArgumentException(message); 189 | } 190 | return reference; 191 | } 192 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/EmojiRange.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji; 18 | 19 | import androidx.annotation.NonNull; 20 | import com.cc.fitwidth.widget.emoji.core.Emoji; 21 | 22 | public final class EmojiRange { 23 | public final int start; 24 | public final int end; 25 | public final Emoji emoji; 26 | 27 | EmojiRange(final int start, final int end, @NonNull final Emoji emoji) { 28 | this.start = start; 29 | this.end = end; 30 | this.emoji = emoji; 31 | } 32 | 33 | @Override public boolean equals(final Object o) { 34 | if (this == o) { 35 | return true; 36 | } 37 | 38 | if (o == null || getClass() != o.getClass()) { 39 | return false; 40 | } 41 | 42 | final EmojiRange that = (EmojiRange) o; 43 | 44 | return start == that.start && end == that.end && emoji.equals(that.emoji); 45 | } 46 | 47 | @Override public int hashCode() { 48 | int result = start; 49 | result = 31 * result + end; 50 | result = 31 * result + emoji.hashCode(); 51 | return result; 52 | } 53 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/GoogleEmoji.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji; 18 | 19 | import android.content.Context; 20 | import android.content.res.Resources; 21 | import android.graphics.Bitmap; 22 | import android.graphics.BitmapFactory; 23 | import android.graphics.drawable.BitmapDrawable; 24 | import android.graphics.drawable.Drawable; 25 | import android.util.LruCache; 26 | import androidx.annotation.NonNull; 27 | import com.cc.fitwidth.widget.emoji.core.CacheKey; 28 | import com.cc.fitwidth.widget.emoji.core.Emoji; 29 | import java.lang.ref.SoftReference; 30 | 31 | public class GoogleEmoji extends Emoji { 32 | private static final int CACHE_SIZE = 100; 33 | private static final int SPRITE_SIZE = 64; 34 | private static final int SPRITE_SIZE_INC_BORDER = 66; 35 | private static final int NUM_STRIPS = 56; 36 | 37 | private static final Object LOCK = new Object(); 38 | 39 | private static final SoftReference[] STRIP_REFS = new SoftReference[NUM_STRIPS]; 40 | private static final LruCache BITMAP_CACHE = new LruCache<>(CACHE_SIZE); 41 | 42 | static { 43 | for (int i = 0; i < NUM_STRIPS; i++) { 44 | STRIP_REFS[i] = new SoftReference(null); 45 | } 46 | } 47 | 48 | private final int x; 49 | private final int y; 50 | 51 | public GoogleEmoji(@NonNull final int[] codePoints, @NonNull final String[] shortcodes, final int x, final int y, 52 | final boolean isDuplicate) { 53 | super(codePoints, shortcodes, -1, isDuplicate); 54 | 55 | this.x = x; 56 | this.y = y; 57 | } 58 | 59 | public GoogleEmoji(final int codePoint, @NonNull final String[] shortcodes, final int x, final int y, 60 | final boolean isDuplicate) { 61 | super(codePoint, shortcodes, -1, isDuplicate); 62 | 63 | this.x = x; 64 | this.y = y; 65 | } 66 | 67 | public GoogleEmoji(final int codePoint, @NonNull final String[] shortcodes, final int x, final int y, 68 | final boolean isDuplicate, final Emoji... variants) { 69 | super(codePoint, shortcodes, -1, isDuplicate, variants); 70 | 71 | this.x = x; 72 | this.y = y; 73 | } 74 | 75 | public GoogleEmoji(@NonNull final int[] codePoints, @NonNull final String[] shortcodes, final int x, final int y, 76 | final boolean isDuplicate, final Emoji... variants) { 77 | super(codePoints, shortcodes, -1, isDuplicate, variants); 78 | 79 | this.x = x; 80 | this.y = y; 81 | } 82 | 83 | @Override @NonNull public Drawable getDrawable(final Context context) { 84 | final CacheKey key = new CacheKey(x, y); 85 | final Bitmap bitmap = BITMAP_CACHE.get(key); 86 | if (bitmap != null) { 87 | return new BitmapDrawable(context.getResources(), bitmap); 88 | } 89 | final Bitmap strip = loadStrip(context); 90 | final Bitmap cut = Bitmap.createBitmap(strip, 1, y * SPRITE_SIZE_INC_BORDER + 1, SPRITE_SIZE, SPRITE_SIZE); 91 | BITMAP_CACHE.put(key, cut); 92 | return new BitmapDrawable(context.getResources(), cut); 93 | } 94 | 95 | private Bitmap loadStrip(final Context context) { 96 | Bitmap strip = (Bitmap) STRIP_REFS[x].get(); 97 | if (strip == null) { 98 | synchronized (LOCK) { 99 | strip = (Bitmap) STRIP_REFS[x].get(); 100 | if (strip == null) { 101 | final Resources resources = context.getResources(); 102 | final int resId = resources.getIdentifier("emoji_google_sheet_" + x, 103 | "drawable", context.getPackageName()); 104 | strip = BitmapFactory.decodeResource(resources, resId); 105 | STRIP_REFS[x] = new SoftReference<>(strip); 106 | } 107 | } 108 | } 109 | return strip; 110 | } 111 | 112 | @Override public void destroy() { 113 | synchronized (LOCK) { 114 | BITMAP_CACHE.evictAll(); 115 | for (int i = 0; i < NUM_STRIPS; i++) { 116 | final Bitmap strip = (Bitmap) STRIP_REFS[i].get(); 117 | if (strip != null) { 118 | strip.recycle(); 119 | STRIP_REFS[i].clear(); 120 | } 121 | } 122 | } 123 | } 124 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/GoogleEmojiProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji; 18 | 19 | import androidx.annotation.NonNull; 20 | import com.cc.fitwidth.widget.emoji.category.*; 21 | import com.cc.fitwidth.widget.emoji.core.EmojiCategory; 22 | 23 | public final class GoogleEmojiProvider { 24 | @NonNull public EmojiCategory[] getCategories() { 25 | return new EmojiCategory[] { 26 | new SmileysAndPeopleCategory(), 27 | new AnimalsAndNatureCategory(), 28 | new FoodAndDrinkCategory(), 29 | new ActivitiesCategory(), 30 | new TravelAndPlacesCategory(), 31 | new ObjectsCategory(), 32 | new SymbolsCategory(), 33 | new FlagsCategory() 34 | }; 35 | } 36 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/category/ActivitiesCategory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.category; 18 | 19 | import androidx.annotation.NonNull; 20 | import com.cc.fitwidth.widget.emoji.GoogleEmoji; 21 | import com.cc.fitwidth.widget.emoji.core.EmojiCategory; 22 | 23 | @SuppressWarnings("PMD.MethodReturnsInternalArray") public final class ActivitiesCategory implements EmojiCategory { 24 | private static final GoogleEmoji[] EMOJIS = CategoryUtils.concatAll(ActivitiesCategoryChunk0.get()); 25 | 26 | @Override @NonNull public GoogleEmoji[] getEmojis() { 27 | return EMOJIS; 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/category/ActivitiesCategoryChunk0.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package com.cc.fitwidth.widget.emoji.category; 19 | 20 | import com.cc.fitwidth.widget.emoji.GoogleEmoji; 21 | 22 | final class ActivitiesCategoryChunk0 { 23 | @SuppressWarnings("PMD.ExcessiveMethodLength") static GoogleEmoji[] get() { 24 | return new GoogleEmoji[] { 25 | new GoogleEmoji(0x1F383, new String[]{"jack_o_lantern"}, 7, 34, false), 26 | new GoogleEmoji(0x1F384, new String[]{"christmas_tree"}, 7, 35, false), 27 | new GoogleEmoji(0x1F386, new String[]{"fireworks"}, 7, 42, false), 28 | new GoogleEmoji(0x1F387, new String[]{"sparkler"}, 7, 43, false), 29 | new GoogleEmoji(0x1F9E8, new String[]{"firecracker"}, 51, 27, false), 30 | new GoogleEmoji(0x2728, new String[]{"sparkles"}, 55, 16, false), 31 | new GoogleEmoji(0x1F388, new String[]{"balloon"}, 7, 44, false), 32 | new GoogleEmoji(0x1F389, new String[]{"tada"}, 7, 45, false), 33 | new GoogleEmoji(0x1F38A, new String[]{"confetti_ball"}, 7, 46, false), 34 | new GoogleEmoji(0x1F38B, new String[]{"tanabata_tree"}, 7, 47, false), 35 | new GoogleEmoji(0x1F38D, new String[]{"bamboo"}, 7, 49, false), 36 | new GoogleEmoji(0x1F38E, new String[]{"dolls"}, 7, 50, false), 37 | new GoogleEmoji(0x1F38F, new String[]{"flags"}, 7, 51, false), 38 | new GoogleEmoji(0x1F390, new String[]{"wind_chime"}, 7, 52, false), 39 | new GoogleEmoji(0x1F391, new String[]{"rice_scene"}, 7, 53, false), 40 | new GoogleEmoji(0x1F9E7, new String[]{"red_envelope"}, 51, 26, false), 41 | new GoogleEmoji(0x1F380, new String[]{"ribbon"}, 7, 31, false), 42 | new GoogleEmoji(0x1F381, new String[]{"gift"}, 7, 32, false), 43 | new GoogleEmoji(new int[] { 0x1F397, 0xFE0F }, new String[]{"reminder_ribbon"}, 8, 0, false), 44 | new GoogleEmoji(new int[] { 0x1F39F, 0xFE0F }, new String[]{"admission_tickets"}, 8, 5, false), 45 | new GoogleEmoji(0x1F3AB, new String[]{"ticket"}, 8, 17, false), 46 | new GoogleEmoji(new int[] { 0x1F396, 0xFE0F }, new String[]{"medal"}, 7, 56, false), 47 | new GoogleEmoji(0x1F3C6, new String[]{"trophy"}, 9, 26, false), 48 | new GoogleEmoji(0x1F3C5, new String[]{"sports_medal"}, 9, 25, false), 49 | new GoogleEmoji(0x1F947, new String[]{"first_place_medal"}, 41, 22, false), 50 | new GoogleEmoji(0x1F948, new String[]{"second_place_medal"}, 41, 23, false), 51 | new GoogleEmoji(0x1F949, new String[]{"third_place_medal"}, 41, 24, false), 52 | new GoogleEmoji(0x26BD, new String[]{"soccer"}, 53, 56, false), 53 | new GoogleEmoji(0x26BE, new String[]{"baseball"}, 54, 0, false), 54 | new GoogleEmoji(0x1F94E, new String[]{"softball"}, 41, 29, false), 55 | new GoogleEmoji(0x1F3C0, new String[]{"basketball"}, 8, 38, false), 56 | new GoogleEmoji(0x1F3D0, new String[]{"volleyball"}, 10, 35, false), 57 | new GoogleEmoji(0x1F3C8, new String[]{"football"}, 9, 33, false), 58 | new GoogleEmoji(0x1F3C9, new String[]{"rugby_football"}, 9, 34, false), 59 | new GoogleEmoji(0x1F3BE, new String[]{"tennis"}, 8, 36, false), 60 | new GoogleEmoji(0x1F94F, new String[]{"flying_disc"}, 41, 30, false), 61 | new GoogleEmoji(0x1F3B3, new String[]{"bowling"}, 8, 25, false), 62 | new GoogleEmoji(0x1F3CF, new String[]{"cricket_bat_and_ball"}, 10, 34, false), 63 | new GoogleEmoji(0x1F3D1, new String[]{"field_hockey_stick_and_ball"}, 10, 36, false), 64 | new GoogleEmoji(0x1F3D2, new String[]{"ice_hockey_stick_and_puck"}, 10, 37, false), 65 | new GoogleEmoji(0x1F94D, new String[]{"lacrosse"}, 41, 28, false), 66 | new GoogleEmoji(0x1F3D3, new String[]{"table_tennis_paddle_and_ball"}, 10, 38, false), 67 | new GoogleEmoji(0x1F3F8, new String[]{"badminton_racquet_and_shuttlecock"}, 11, 20, false), 68 | new GoogleEmoji(0x1F94A, new String[]{"boxing_glove"}, 41, 25, false), 69 | new GoogleEmoji(0x1F94B, new String[]{"martial_arts_uniform"}, 41, 26, false), 70 | new GoogleEmoji(0x1F945, new String[]{"goal_net"}, 41, 21, false), 71 | new GoogleEmoji(0x26F3, new String[]{"golf"}, 54, 14, false), 72 | new GoogleEmoji(new int[] { 0x26F8, 0xFE0F }, new String[]{"ice_skate"}, 54, 18, false), 73 | new GoogleEmoji(0x1F3A3, new String[]{"fishing_pole_and_fish"}, 8, 9, false), 74 | new GoogleEmoji(0x1F93F, new String[]{"diving_mask"}, 41, 15, false), 75 | new GoogleEmoji(0x1F3BD, new String[]{"running_shirt_with_sash"}, 8, 35, false), 76 | new GoogleEmoji(0x1F3BF, new String[]{"ski"}, 8, 37, false), 77 | new GoogleEmoji(0x1F6F7, new String[]{"sled"}, 36, 56, false), 78 | new GoogleEmoji(0x1F94C, new String[]{"curling_stone"}, 41, 27, false), 79 | new GoogleEmoji(0x1F3AF, new String[]{"dart"}, 8, 21, false), 80 | new GoogleEmoji(0x1FA80, new String[]{"yo-yo"}, 52, 1, false), 81 | new GoogleEmoji(0x1FA81, new String[]{"kite"}, 52, 2, false), 82 | new GoogleEmoji(0x1F3B1, new String[]{"8ball"}, 8, 23, false), 83 | new GoogleEmoji(0x1F52E, new String[]{"crystal_ball"}, 28, 17, false), 84 | new GoogleEmoji(0x1F9FF, new String[]{"nazar_amulet"}, 51, 50, false), 85 | new GoogleEmoji(0x1F3AE, new String[]{"video_game"}, 8, 20, false), 86 | new GoogleEmoji(new int[] { 0x1F579, 0xFE0F }, new String[]{"joystick"}, 29, 36, false), 87 | new GoogleEmoji(0x1F3B0, new String[]{"slot_machine"}, 8, 22, false), 88 | new GoogleEmoji(0x1F3B2, new String[]{"game_die"}, 8, 24, false), 89 | new GoogleEmoji(0x1F9E9, new String[]{"jigsaw"}, 51, 28, false), 90 | new GoogleEmoji(0x1F9F8, new String[]{"teddy_bear"}, 51, 43, false), 91 | new GoogleEmoji(new int[] { 0x2660, 0xFE0F }, new String[]{"spades"}, 53, 33, false), 92 | new GoogleEmoji(new int[] { 0x2665, 0xFE0F }, new String[]{"hearts"}, 53, 35, false), 93 | new GoogleEmoji(new int[] { 0x2666, 0xFE0F }, new String[]{"diamonds"}, 53, 36, false), 94 | new GoogleEmoji(new int[] { 0x2663, 0xFE0F }, new String[]{"clubs"}, 53, 34, false), 95 | new GoogleEmoji(new int[] { 0x265F, 0xFE0F }, new String[]{"chess_pawn"}, 53, 32, false), 96 | new GoogleEmoji(0x1F0CF, new String[]{"black_joker"}, 0, 15, false), 97 | new GoogleEmoji(0x1F004, new String[]{"mahjong"}, 0, 14, false), 98 | new GoogleEmoji(0x1F3B4, new String[]{"flower_playing_cards"}, 8, 26, false), 99 | new GoogleEmoji(0x1F3AD, new String[]{"performing_arts"}, 8, 19, false), 100 | new GoogleEmoji(new int[] { 0x1F5BC, 0xFE0F }, new String[]{"frame_with_picture"}, 30, 14, false), 101 | new GoogleEmoji(0x1F3A8, new String[]{"art"}, 8, 14, false), 102 | new GoogleEmoji(0x1F9F5, new String[]{"thread"}, 51, 40, false), 103 | new GoogleEmoji(0x1F9F6, new String[]{"yarn"}, 51, 41, false) 104 | }; 105 | } 106 | 107 | private ActivitiesCategoryChunk0() { 108 | // No instances. 109 | } 110 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/category/AnimalsAndNatureCategory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.category; 18 | 19 | import androidx.annotation.NonNull; 20 | import com.cc.fitwidth.widget.emoji.GoogleEmoji; 21 | import com.cc.fitwidth.widget.emoji.core.EmojiCategory; 22 | 23 | @SuppressWarnings("PMD.MethodReturnsInternalArray") 24 | public final class AnimalsAndNatureCategory implements EmojiCategory { 25 | private static final GoogleEmoji[] EMOJIS = CategoryUtils.concatAll(AnimalsAndNatureCategoryChunk0.get()); 26 | 27 | @Override @NonNull public GoogleEmoji[] getEmojis() { 28 | return EMOJIS; 29 | } 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/category/AnimalsAndNatureCategoryChunk0.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.category; 18 | 19 | import com.cc.fitwidth.widget.emoji.GoogleEmoji; 20 | 21 | final class AnimalsAndNatureCategoryChunk0 { 22 | @SuppressWarnings("PMD.ExcessiveMethodLength") static GoogleEmoji[] get() { 23 | return new GoogleEmoji[] { 24 | new GoogleEmoji(0x1F435, new String[]{"monkey_face"}, 12, 25, false), 25 | new GoogleEmoji(0x1F412, new String[]{"monkey"}, 11, 46, false), 26 | new GoogleEmoji(0x1F98D, new String[]{"gorilla"}, 42, 31, false), 27 | new GoogleEmoji(0x1F9A7, new String[]{"orangutan"}, 42, 55, false), 28 | new GoogleEmoji(0x1F436, new String[]{"dog"}, 12, 26, false), 29 | new GoogleEmoji(0x1F415, new String[]{"dog2"}, 11, 50, false), 30 | new GoogleEmoji(0x1F9AE, new String[]{"guide_dog"}, 43, 2, false), 31 | new GoogleEmoji(new int[] { 0x1F415, 0x200D, 0x1F9BA }, new String[]{"service_dog"}, 11, 49, false), 32 | new GoogleEmoji(0x1F429, new String[]{"poodle"}, 12, 13, false), 33 | new GoogleEmoji(0x1F43A, new String[]{"wolf"}, 12, 30, false), 34 | new GoogleEmoji(0x1F98A, new String[]{"fox_face"}, 42, 28, false), 35 | new GoogleEmoji(0x1F99D, new String[]{"raccoon"}, 42, 47, false), 36 | new GoogleEmoji(0x1F431, new String[]{"cat"}, 12, 21, false), 37 | new GoogleEmoji(0x1F408, new String[]{"cat2"}, 11, 36, false), 38 | new GoogleEmoji(0x1F981, new String[]{"lion_face"}, 42, 19, false), 39 | new GoogleEmoji(0x1F42F, new String[]{"tiger"}, 12, 19, false), 40 | new GoogleEmoji(0x1F405, new String[]{"tiger2"}, 11, 33, false), 41 | new GoogleEmoji(0x1F406, new String[]{"leopard"}, 11, 34, false), 42 | new GoogleEmoji(0x1F434, new String[]{"horse"}, 12, 24, false), 43 | new GoogleEmoji(0x1F40E, new String[]{"racehorse"}, 11, 42, false), 44 | new GoogleEmoji(0x1F984, new String[]{"unicorn_face"}, 42, 22, false), 45 | new GoogleEmoji(0x1F993, new String[]{"zebra_face"}, 42, 37, false), 46 | new GoogleEmoji(0x1F98C, new String[]{"deer"}, 42, 30, false), 47 | new GoogleEmoji(0x1F42E, new String[]{"cow"}, 12, 18, false), 48 | new GoogleEmoji(0x1F402, new String[]{"ox"}, 11, 30, false), 49 | new GoogleEmoji(0x1F403, new String[]{"water_buffalo"}, 11, 31, false), 50 | new GoogleEmoji(0x1F404, new String[]{"cow2"}, 11, 32, false), 51 | new GoogleEmoji(0x1F437, new String[]{"pig"}, 12, 27, false), 52 | new GoogleEmoji(0x1F416, new String[]{"pig2"}, 11, 51, false), 53 | new GoogleEmoji(0x1F417, new String[]{"boar"}, 11, 52, false), 54 | new GoogleEmoji(0x1F43D, new String[]{"pig_nose"}, 12, 33, false), 55 | new GoogleEmoji(0x1F40F, new String[]{"ram"}, 11, 43, false), 56 | new GoogleEmoji(0x1F411, new String[]{"sheep"}, 11, 45, false), 57 | new GoogleEmoji(0x1F410, new String[]{"goat"}, 11, 44, false), 58 | new GoogleEmoji(0x1F42A, new String[]{"dromedary_camel"}, 12, 14, false), 59 | new GoogleEmoji(0x1F42B, new String[]{"camel"}, 12, 15, false), 60 | new GoogleEmoji(0x1F999, new String[]{"llama"}, 42, 43, false), 61 | new GoogleEmoji(0x1F992, new String[]{"giraffe_face"}, 42, 36, false), 62 | new GoogleEmoji(0x1F418, new String[]{"elephant"}, 11, 53, false), 63 | new GoogleEmoji(0x1F98F, new String[]{"rhinoceros"}, 42, 33, false), 64 | new GoogleEmoji(0x1F99B, new String[]{"hippopotamus"}, 42, 45, false), 65 | new GoogleEmoji(0x1F42D, new String[]{"mouse"}, 12, 17, false), 66 | new GoogleEmoji(0x1F401, new String[]{"mouse2"}, 11, 29, false), 67 | new GoogleEmoji(0x1F400, new String[]{"rat"}, 11, 28, false), 68 | new GoogleEmoji(0x1F439, new String[]{"hamster"}, 12, 29, false), 69 | new GoogleEmoji(0x1F430, new String[]{"rabbit"}, 12, 20, false), 70 | new GoogleEmoji(0x1F407, new String[]{"rabbit2"}, 11, 35, false), 71 | new GoogleEmoji(new int[] { 0x1F43F, 0xFE0F }, new String[]{"chipmunk"}, 12, 35, false), 72 | new GoogleEmoji(0x1F994, new String[]{"hedgehog"}, 42, 38, false), 73 | new GoogleEmoji(0x1F987, new String[]{"bat"}, 42, 25, false), 74 | new GoogleEmoji(0x1F43B, new String[]{"bear"}, 12, 31, false), 75 | new GoogleEmoji(0x1F428, new String[]{"koala"}, 12, 12, false), 76 | new GoogleEmoji(0x1F43C, new String[]{"panda_face"}, 12, 32, false), 77 | new GoogleEmoji(0x1F9A5, new String[]{"sloth"}, 42, 53, false), 78 | new GoogleEmoji(0x1F9A6, new String[]{"otter"}, 42, 54, false), 79 | new GoogleEmoji(0x1F9A8, new String[]{"skunk"}, 42, 56, false), 80 | new GoogleEmoji(0x1F998, new String[]{"kangaroo"}, 42, 42, false), 81 | new GoogleEmoji(0x1F9A1, new String[]{"badger"}, 42, 51, false), 82 | new GoogleEmoji(0x1F43E, new String[]{"feet", "paw_prints"}, 12, 34, false), 83 | new GoogleEmoji(0x1F983, new String[]{"turkey"}, 42, 21, false), 84 | new GoogleEmoji(0x1F414, new String[]{"chicken"}, 11, 48, false), 85 | new GoogleEmoji(0x1F413, new String[]{"rooster"}, 11, 47, false), 86 | new GoogleEmoji(0x1F423, new String[]{"hatching_chick"}, 12, 7, false), 87 | new GoogleEmoji(0x1F424, new String[]{"baby_chick"}, 12, 8, false), 88 | new GoogleEmoji(0x1F425, new String[]{"hatched_chick"}, 12, 9, false), 89 | new GoogleEmoji(0x1F426, new String[]{"bird"}, 12, 10, false), 90 | new GoogleEmoji(0x1F427, new String[]{"penguin"}, 12, 11, false), 91 | new GoogleEmoji(new int[] { 0x1F54A, 0xFE0F }, new String[]{"dove_of_peace"}, 28, 34, false), 92 | new GoogleEmoji(0x1F985, new String[]{"eagle"}, 42, 23, false), 93 | new GoogleEmoji(0x1F986, new String[]{"duck"}, 42, 24, false), 94 | new GoogleEmoji(0x1F9A2, new String[]{"swan"}, 42, 52, false), 95 | new GoogleEmoji(0x1F989, new String[]{"owl"}, 42, 27, false), 96 | new GoogleEmoji(0x1F9A9, new String[]{"flamingo"}, 43, 0, false), 97 | new GoogleEmoji(0x1F99A, new String[]{"peacock"}, 42, 44, false), 98 | new GoogleEmoji(0x1F99C, new String[]{"parrot"}, 42, 46, false), 99 | new GoogleEmoji(0x1F438, new String[]{"frog"}, 12, 28, false), 100 | new GoogleEmoji(0x1F40A, new String[]{"crocodile"}, 11, 38, false), 101 | new GoogleEmoji(0x1F422, new String[]{"turtle"}, 12, 6, false), 102 | new GoogleEmoji(0x1F98E, new String[]{"lizard"}, 42, 32, false), 103 | new GoogleEmoji(0x1F40D, new String[]{"snake"}, 11, 41, false), 104 | new GoogleEmoji(0x1F432, new String[]{"dragon_face"}, 12, 22, false), 105 | new GoogleEmoji(0x1F409, new String[]{"dragon"}, 11, 37, false), 106 | new GoogleEmoji(0x1F995, new String[]{"sauropod"}, 42, 39, false), 107 | new GoogleEmoji(0x1F996, new String[]{"t-rex"}, 42, 40, false), 108 | new GoogleEmoji(0x1F433, new String[]{"whale"}, 12, 23, false), 109 | new GoogleEmoji(0x1F40B, new String[]{"whale2"}, 11, 39, false), 110 | new GoogleEmoji(0x1F42C, new String[]{"dolphin", "flipper"}, 12, 16, false), 111 | new GoogleEmoji(0x1F41F, new String[]{"fish"}, 12, 3, false), 112 | new GoogleEmoji(0x1F420, new String[]{"tropical_fish"}, 12, 4, false), 113 | new GoogleEmoji(0x1F421, new String[]{"blowfish"}, 12, 5, false), 114 | new GoogleEmoji(0x1F988, new String[]{"shark"}, 42, 26, false), 115 | new GoogleEmoji(0x1F419, new String[]{"octopus"}, 11, 54, false), 116 | new GoogleEmoji(0x1F41A, new String[]{"shell"}, 11, 55, false), 117 | new GoogleEmoji(0x1F40C, new String[]{"snail"}, 11, 40, false), 118 | new GoogleEmoji(0x1F98B, new String[]{"butterfly"}, 42, 29, false), 119 | new GoogleEmoji(0x1F41B, new String[]{"bug"}, 11, 56, false), 120 | new GoogleEmoji(0x1F41C, new String[]{"ant"}, 12, 0, false), 121 | new GoogleEmoji(0x1F41D, new String[]{"bee", "honeybee"}, 12, 1, false), 122 | new GoogleEmoji(0x1F41E, new String[]{"beetle"}, 12, 2, false), 123 | new GoogleEmoji(0x1F997, new String[]{"cricket"}, 42, 41, false), 124 | new GoogleEmoji(new int[] { 0x1F577, 0xFE0F }, new String[]{"spider"}, 29, 34, false), 125 | new GoogleEmoji(new int[] { 0x1F578, 0xFE0F }, new String[]{"spider_web"}, 29, 35, false), 126 | new GoogleEmoji(0x1F982, new String[]{"scorpion"}, 42, 20, false), 127 | new GoogleEmoji(0x1F99F, new String[]{"mosquito"}, 42, 49, false), 128 | new GoogleEmoji(0x1F9A0, new String[]{"microbe"}, 42, 50, false), 129 | new GoogleEmoji(0x1F490, new String[]{"bouquet"}, 25, 26, false), 130 | new GoogleEmoji(0x1F338, new String[]{"cherry_blossom"}, 6, 16, false), 131 | new GoogleEmoji(0x1F4AE, new String[]{"white_flower"}, 26, 4, false), 132 | new GoogleEmoji(new int[] { 0x1F3F5, 0xFE0F }, new String[]{"rosette"}, 11, 18, false), 133 | new GoogleEmoji(0x1F339, new String[]{"rose"}, 6, 17, false), 134 | new GoogleEmoji(0x1F940, new String[]{"wilted_flower"}, 41, 16, false), 135 | new GoogleEmoji(0x1F33A, new String[]{"hibiscus"}, 6, 18, false), 136 | new GoogleEmoji(0x1F33B, new String[]{"sunflower"}, 6, 19, false), 137 | new GoogleEmoji(0x1F33C, new String[]{"blossom"}, 6, 20, false), 138 | new GoogleEmoji(0x1F337, new String[]{"tulip"}, 6, 15, false), 139 | new GoogleEmoji(0x1F331, new String[]{"seedling"}, 6, 9, false), 140 | new GoogleEmoji(0x1F332, new String[]{"evergreen_tree"}, 6, 10, false), 141 | new GoogleEmoji(0x1F333, new String[]{"deciduous_tree"}, 6, 11, false), 142 | new GoogleEmoji(0x1F334, new String[]{"palm_tree"}, 6, 12, false), 143 | new GoogleEmoji(0x1F335, new String[]{"cactus"}, 6, 13, false), 144 | new GoogleEmoji(0x1F33E, new String[]{"ear_of_rice"}, 6, 22, false), 145 | new GoogleEmoji(0x1F33F, new String[]{"herb"}, 6, 23, false), 146 | new GoogleEmoji(new int[] { 0x2618, 0xFE0F }, new String[]{"shamrock"}, 53, 1, false), 147 | new GoogleEmoji(0x1F340, new String[]{"four_leaf_clover"}, 6, 24, false), 148 | new GoogleEmoji(0x1F341, new String[]{"maple_leaf"}, 6, 25, false), 149 | new GoogleEmoji(0x1F342, new String[]{"fallen_leaf"}, 6, 26, false), 150 | new GoogleEmoji(0x1F343, new String[]{"leaves"}, 6, 27, false) 151 | }; 152 | } 153 | 154 | private AnimalsAndNatureCategoryChunk0() { 155 | // No instances. 156 | } 157 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/category/CategoryUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.category; 18 | 19 | import com.cc.fitwidth.widget.emoji.GoogleEmoji; 20 | import java.util.Arrays; 21 | 22 | final class CategoryUtils { 23 | static GoogleEmoji[] concatAll(final GoogleEmoji[] first, final GoogleEmoji[]... rest) { 24 | int totalLength = first.length; 25 | for (final GoogleEmoji[] array : rest) { 26 | totalLength += array.length; 27 | } 28 | 29 | final GoogleEmoji[] result = Arrays.copyOf(first, totalLength); 30 | 31 | int offset = first.length; 32 | for (final GoogleEmoji[] array : rest) { 33 | System.arraycopy(array, 0, result, offset, array.length); 34 | offset += array.length; 35 | } 36 | 37 | return result; 38 | } 39 | 40 | private CategoryUtils() { 41 | // No instances. 42 | } 43 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/category/FlagsCategory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.category; 18 | 19 | import androidx.annotation.NonNull; 20 | import com.cc.fitwidth.widget.emoji.GoogleEmoji; 21 | import com.cc.fitwidth.widget.emoji.core.EmojiCategory; 22 | 23 | @SuppressWarnings("PMD.MethodReturnsInternalArray") public final class FlagsCategory implements EmojiCategory { 24 | private static final GoogleEmoji[] EMOJIS = CategoryUtils.concatAll(FlagsCategoryChunk0.get(), FlagsCategoryChunk1.get()); 25 | 26 | @Override @NonNull public GoogleEmoji[] getEmojis() { 27 | return EMOJIS; 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/category/FlagsCategoryChunk0.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.category; 18 | 19 | import com.cc.fitwidth.widget.emoji.GoogleEmoji; 20 | 21 | final class FlagsCategoryChunk0 { 22 | @SuppressWarnings("PMD.ExcessiveMethodLength") static GoogleEmoji[] get() { 23 | return new GoogleEmoji[] { 24 | new GoogleEmoji(0x1F3C1, new String[]{"checkered_flag"}, 8, 39, false), 25 | new GoogleEmoji(0x1F6A9, new String[]{"triangular_flag_on_post"}, 35, 0, false), 26 | new GoogleEmoji(0x1F38C, new String[]{"crossed_flags"}, 7, 48, false), 27 | new GoogleEmoji(0x1F3F4, new String[]{"waving_black_flag"}, 11, 17, false), 28 | new GoogleEmoji(new int[] { 0x1F3F3, 0xFE0F }, new String[]{"waving_white_flag"}, 11, 12, false), 29 | new GoogleEmoji(new int[] { 0x1F3F3, 0xFE0F, 0x200D, 0x1F308 }, new String[]{"rainbow-flag"}, 11, 11, false), 30 | new GoogleEmoji(new int[] { 0x1F3F4, 0x200D, 0x2620, 0xFE0F }, new String[]{"pirate_flag"}, 11, 13, false), 31 | new GoogleEmoji(new int[] { 0x1F1E6, 0x1F1E8 }, new String[]{"flag-ac"}, 0, 31, false), 32 | new GoogleEmoji(new int[] { 0x1F1E6, 0x1F1E9 }, new String[]{"flag-ad"}, 0, 32, false), 33 | new GoogleEmoji(new int[] { 0x1F1E6, 0x1F1EA }, new String[]{"flag-ae"}, 0, 33, false), 34 | new GoogleEmoji(new int[] { 0x1F1E6, 0x1F1EB }, new String[]{"flag-af"}, 0, 34, false), 35 | new GoogleEmoji(new int[] { 0x1F1E6, 0x1F1EC }, new String[]{"flag-ag"}, 0, 35, false), 36 | new GoogleEmoji(new int[] { 0x1F1E6, 0x1F1EE }, new String[]{"flag-ai"}, 0, 36, false), 37 | new GoogleEmoji(new int[] { 0x1F1E6, 0x1F1F1 }, new String[]{"flag-al"}, 0, 37, false), 38 | new GoogleEmoji(new int[] { 0x1F1E6, 0x1F1F2 }, new String[]{"flag-am"}, 0, 38, false), 39 | new GoogleEmoji(new int[] { 0x1F1E6, 0x1F1F4 }, new String[]{"flag-ao"}, 0, 39, false), 40 | new GoogleEmoji(new int[] { 0x1F1E6, 0x1F1F6 }, new String[]{"flag-aq"}, 0, 40, false), 41 | new GoogleEmoji(new int[] { 0x1F1E6, 0x1F1F7 }, new String[]{"flag-ar"}, 0, 41, false), 42 | new GoogleEmoji(new int[] { 0x1F1E6, 0x1F1F8 }, new String[]{"flag-as"}, 0, 42, false), 43 | new GoogleEmoji(new int[] { 0x1F1E6, 0x1F1F9 }, new String[]{"flag-at"}, 0, 43, false), 44 | new GoogleEmoji(new int[] { 0x1F1E6, 0x1F1FA }, new String[]{"flag-au"}, 0, 44, false), 45 | new GoogleEmoji(new int[] { 0x1F1E6, 0x1F1FC }, new String[]{"flag-aw"}, 0, 45, false), 46 | new GoogleEmoji(new int[] { 0x1F1E6, 0x1F1FD }, new String[]{"flag-ax"}, 0, 46, false), 47 | new GoogleEmoji(new int[] { 0x1F1E6, 0x1F1FF }, new String[]{"flag-az"}, 0, 47, false), 48 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1E6 }, new String[]{"flag-ba"}, 0, 48, false), 49 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1E7 }, new String[]{"flag-bb"}, 0, 49, false), 50 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1E9 }, new String[]{"flag-bd"}, 0, 50, false), 51 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1EA }, new String[]{"flag-be"}, 0, 51, false), 52 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1EB }, new String[]{"flag-bf"}, 0, 52, false), 53 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1EC }, new String[]{"flag-bg"}, 0, 53, false), 54 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1ED }, new String[]{"flag-bh"}, 0, 54, false), 55 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1EE }, new String[]{"flag-bi"}, 0, 55, false), 56 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1EF }, new String[]{"flag-bj"}, 0, 56, false), 57 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1F1 }, new String[]{"flag-bl"}, 1, 0, false), 58 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1F2 }, new String[]{"flag-bm"}, 1, 1, false), 59 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1F3 }, new String[]{"flag-bn"}, 1, 2, false), 60 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1F4 }, new String[]{"flag-bo"}, 1, 3, false), 61 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1F6 }, new String[]{"flag-bq"}, 1, 4, false), 62 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1F7 }, new String[]{"flag-br"}, 1, 5, false), 63 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1F8 }, new String[]{"flag-bs"}, 1, 6, false), 64 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1F9 }, new String[]{"flag-bt"}, 1, 7, false), 65 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1FB }, new String[]{"flag-bv"}, 1, 8, false), 66 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1FC }, new String[]{"flag-bw"}, 1, 9, false), 67 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1FE }, new String[]{"flag-by"}, 1, 10, false), 68 | new GoogleEmoji(new int[] { 0x1F1E7, 0x1F1FF }, new String[]{"flag-bz"}, 1, 11, false), 69 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1E6 }, new String[]{"flag-ca"}, 1, 12, false), 70 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1E8 }, new String[]{"flag-cc"}, 1, 13, false), 71 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1E9 }, new String[]{"flag-cd"}, 1, 14, false), 72 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1EB }, new String[]{"flag-cf"}, 1, 15, false), 73 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1EC }, new String[]{"flag-cg"}, 1, 16, false), 74 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1ED }, new String[]{"flag-ch"}, 1, 17, false), 75 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1EE }, new String[]{"flag-ci"}, 1, 18, false), 76 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1F0 }, new String[]{"flag-ck"}, 1, 19, false), 77 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1F1 }, new String[]{"flag-cl"}, 1, 20, false), 78 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1F2 }, new String[]{"flag-cm"}, 1, 21, false), 79 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1F3 }, new String[]{"cn", "flag-cn"}, 1, 22, false), 80 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1F4 }, new String[]{"flag-co"}, 1, 23, false), 81 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1F5 }, new String[]{"flag-cp"}, 1, 24, false), 82 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1F7 }, new String[]{"flag-cr"}, 1, 25, false), 83 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1FA }, new String[]{"flag-cu"}, 1, 26, false), 84 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1FB }, new String[]{"flag-cv"}, 1, 27, false), 85 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1FC }, new String[]{"flag-cw"}, 1, 28, false), 86 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1FD }, new String[]{"flag-cx"}, 1, 29, false), 87 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1FE }, new String[]{"flag-cy"}, 1, 30, false), 88 | new GoogleEmoji(new int[] { 0x1F1E8, 0x1F1FF }, new String[]{"flag-cz"}, 1, 31, false), 89 | new GoogleEmoji(new int[] { 0x1F1E9, 0x1F1EA }, new String[]{"de", "flag-de"}, 1, 32, false), 90 | new GoogleEmoji(new int[] { 0x1F1E9, 0x1F1EC }, new String[]{"flag-dg"}, 1, 33, false), 91 | new GoogleEmoji(new int[] { 0x1F1E9, 0x1F1EF }, new String[]{"flag-dj"}, 1, 34, false), 92 | new GoogleEmoji(new int[] { 0x1F1E9, 0x1F1F0 }, new String[]{"flag-dk"}, 1, 35, false), 93 | new GoogleEmoji(new int[] { 0x1F1E9, 0x1F1F2 }, new String[]{"flag-dm"}, 1, 36, false), 94 | new GoogleEmoji(new int[] { 0x1F1E9, 0x1F1F4 }, new String[]{"flag-do"}, 1, 37, false), 95 | new GoogleEmoji(new int[] { 0x1F1E9, 0x1F1FF }, new String[]{"flag-dz"}, 1, 38, false), 96 | new GoogleEmoji(new int[] { 0x1F1EA, 0x1F1E6 }, new String[]{"flag-ea"}, 1, 39, false), 97 | new GoogleEmoji(new int[] { 0x1F1EA, 0x1F1E8 }, new String[]{"flag-ec"}, 1, 40, false), 98 | new GoogleEmoji(new int[] { 0x1F1EA, 0x1F1EA }, new String[]{"flag-ee"}, 1, 41, false), 99 | new GoogleEmoji(new int[] { 0x1F1EA, 0x1F1EC }, new String[]{"flag-eg"}, 1, 42, false), 100 | new GoogleEmoji(new int[] { 0x1F1EA, 0x1F1ED }, new String[]{"flag-eh"}, 1, 43, false), 101 | new GoogleEmoji(new int[] { 0x1F1EA, 0x1F1F7 }, new String[]{"flag-er"}, 1, 44, false), 102 | new GoogleEmoji(new int[] { 0x1F1EA, 0x1F1F8 }, new String[]{"es", "flag-es"}, 1, 45, false), 103 | new GoogleEmoji(new int[] { 0x1F1EA, 0x1F1F9 }, new String[]{"flag-et"}, 1, 46, false), 104 | new GoogleEmoji(new int[] { 0x1F1EA, 0x1F1FA }, new String[]{"flag-eu"}, 1, 47, false), 105 | new GoogleEmoji(new int[] { 0x1F1EB, 0x1F1EE }, new String[]{"flag-fi"}, 1, 48, false), 106 | new GoogleEmoji(new int[] { 0x1F1EB, 0x1F1EF }, new String[]{"flag-fj"}, 1, 49, false), 107 | new GoogleEmoji(new int[] { 0x1F1EB, 0x1F1F0 }, new String[]{"flag-fk"}, 1, 50, false), 108 | new GoogleEmoji(new int[] { 0x1F1EB, 0x1F1F2 }, new String[]{"flag-fm"}, 1, 51, false), 109 | new GoogleEmoji(new int[] { 0x1F1EB, 0x1F1F4 }, new String[]{"flag-fo"}, 1, 52, false), 110 | new GoogleEmoji(new int[] { 0x1F1EB, 0x1F1F7 }, new String[]{"fr", "flag-fr"}, 1, 53, false), 111 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1E6 }, new String[]{"flag-ga"}, 1, 54, false), 112 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1E7 }, new String[]{"gb", "uk", "flag-gb"}, 1, 55, false), 113 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1E9 }, new String[]{"flag-gd"}, 1, 56, false), 114 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1EA }, new String[]{"flag-ge"}, 2, 0, false), 115 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1EB }, new String[]{"flag-gf"}, 2, 1, false), 116 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1EC }, new String[]{"flag-gg"}, 2, 2, false), 117 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1ED }, new String[]{"flag-gh"}, 2, 3, false), 118 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1EE }, new String[]{"flag-gi"}, 2, 4, false), 119 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1F1 }, new String[]{"flag-gl"}, 2, 5, false), 120 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1F2 }, new String[]{"flag-gm"}, 2, 6, false), 121 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1F3 }, new String[]{"flag-gn"}, 2, 7, false), 122 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1F5 }, new String[]{"flag-gp"}, 2, 8, false), 123 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1F6 }, new String[]{"flag-gq"}, 2, 9, false), 124 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1F7 }, new String[]{"flag-gr"}, 2, 10, false), 125 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1F8 }, new String[]{"flag-gs"}, 2, 11, false), 126 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1F9 }, new String[]{"flag-gt"}, 2, 12, false), 127 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1FA }, new String[]{"flag-gu"}, 2, 13, false), 128 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1FC }, new String[]{"flag-gw"}, 2, 14, false), 129 | new GoogleEmoji(new int[] { 0x1F1EC, 0x1F1FE }, new String[]{"flag-gy"}, 2, 15, false), 130 | new GoogleEmoji(new int[] { 0x1F1ED, 0x1F1F0 }, new String[]{"flag-hk"}, 2, 16, false), 131 | new GoogleEmoji(new int[] { 0x1F1ED, 0x1F1F2 }, new String[]{"flag-hm"}, 2, 17, false), 132 | new GoogleEmoji(new int[] { 0x1F1ED, 0x1F1F3 }, new String[]{"flag-hn"}, 2, 18, false), 133 | new GoogleEmoji(new int[] { 0x1F1ED, 0x1F1F7 }, new String[]{"flag-hr"}, 2, 19, false), 134 | new GoogleEmoji(new int[] { 0x1F1ED, 0x1F1F9 }, new String[]{"flag-ht"}, 2, 20, false), 135 | new GoogleEmoji(new int[] { 0x1F1ED, 0x1F1FA }, new String[]{"flag-hu"}, 2, 21, false), 136 | new GoogleEmoji(new int[] { 0x1F1EE, 0x1F1E8 }, new String[]{"flag-ic"}, 2, 22, false), 137 | new GoogleEmoji(new int[] { 0x1F1EE, 0x1F1E9 }, new String[]{"flag-id"}, 2, 23, false), 138 | new GoogleEmoji(new int[] { 0x1F1EE, 0x1F1EA }, new String[]{"flag-ie"}, 2, 24, false), 139 | new GoogleEmoji(new int[] { 0x1F1EE, 0x1F1F1 }, new String[]{"flag-il"}, 2, 25, false), 140 | new GoogleEmoji(new int[] { 0x1F1EE, 0x1F1F2 }, new String[]{"flag-im"}, 2, 26, false), 141 | new GoogleEmoji(new int[] { 0x1F1EE, 0x1F1F3 }, new String[]{"flag-in"}, 2, 27, false), 142 | new GoogleEmoji(new int[] { 0x1F1EE, 0x1F1F4 }, new String[]{"flag-io"}, 2, 28, false), 143 | new GoogleEmoji(new int[] { 0x1F1EE, 0x1F1F6 }, new String[]{"flag-iq"}, 2, 29, false), 144 | new GoogleEmoji(new int[] { 0x1F1EE, 0x1F1F7 }, new String[]{"flag-ir"}, 2, 30, false), 145 | new GoogleEmoji(new int[] { 0x1F1EE, 0x1F1F8 }, new String[]{"flag-is"}, 2, 31, false), 146 | new GoogleEmoji(new int[] { 0x1F1EE, 0x1F1F9 }, new String[]{"it", "flag-it"}, 2, 32, false), 147 | new GoogleEmoji(new int[] { 0x1F1EF, 0x1F1EA }, new String[]{"flag-je"}, 2, 33, false), 148 | new GoogleEmoji(new int[] { 0x1F1EF, 0x1F1F2 }, new String[]{"flag-jm"}, 2, 34, false), 149 | new GoogleEmoji(new int[] { 0x1F1EF, 0x1F1F4 }, new String[]{"flag-jo"}, 2, 35, false), 150 | new GoogleEmoji(new int[] { 0x1F1EF, 0x1F1F5 }, new String[]{"jp", "flag-jp"}, 2, 36, false), 151 | new GoogleEmoji(new int[] { 0x1F1F0, 0x1F1EA }, new String[]{"flag-ke"}, 2, 37, false), 152 | new GoogleEmoji(new int[] { 0x1F1F0, 0x1F1EC }, new String[]{"flag-kg"}, 2, 38, false), 153 | new GoogleEmoji(new int[] { 0x1F1F0, 0x1F1ED }, new String[]{"flag-kh"}, 2, 39, false), 154 | new GoogleEmoji(new int[] { 0x1F1F0, 0x1F1EE }, new String[]{"flag-ki"}, 2, 40, false), 155 | new GoogleEmoji(new int[] { 0x1F1F0, 0x1F1F2 }, new String[]{"flag-km"}, 2, 41, false), 156 | new GoogleEmoji(new int[] { 0x1F1F0, 0x1F1F3 }, new String[]{"flag-kn"}, 2, 42, false), 157 | new GoogleEmoji(new int[] { 0x1F1F0, 0x1F1F5 }, new String[]{"flag-kp"}, 2, 43, false), 158 | new GoogleEmoji(new int[] { 0x1F1F0, 0x1F1F7 }, new String[]{"kr", "flag-kr"}, 2, 44, false), 159 | new GoogleEmoji(new int[] { 0x1F1F0, 0x1F1FC }, new String[]{"flag-kw"}, 2, 45, false), 160 | new GoogleEmoji(new int[] { 0x1F1F0, 0x1F1FE }, new String[]{"flag-ky"}, 2, 46, false), 161 | new GoogleEmoji(new int[] { 0x1F1F0, 0x1F1FF }, new String[]{"flag-kz"}, 2, 47, false), 162 | new GoogleEmoji(new int[] { 0x1F1F1, 0x1F1E6 }, new String[]{"flag-la"}, 2, 48, false), 163 | new GoogleEmoji(new int[] { 0x1F1F1, 0x1F1E7 }, new String[]{"flag-lb"}, 2, 49, false), 164 | new GoogleEmoji(new int[] { 0x1F1F1, 0x1F1E8 }, new String[]{"flag-lc"}, 2, 50, false), 165 | new GoogleEmoji(new int[] { 0x1F1F1, 0x1F1EE }, new String[]{"flag-li"}, 2, 51, false), 166 | new GoogleEmoji(new int[] { 0x1F1F1, 0x1F1F0 }, new String[]{"flag-lk"}, 2, 52, false), 167 | new GoogleEmoji(new int[] { 0x1F1F1, 0x1F1F7 }, new String[]{"flag-lr"}, 2, 53, false), 168 | new GoogleEmoji(new int[] { 0x1F1F1, 0x1F1F8 }, new String[]{"flag-ls"}, 2, 54, false), 169 | new GoogleEmoji(new int[] { 0x1F1F1, 0x1F1F9 }, new String[]{"flag-lt"}, 2, 55, false), 170 | new GoogleEmoji(new int[] { 0x1F1F1, 0x1F1FA }, new String[]{"flag-lu"}, 2, 56, false), 171 | new GoogleEmoji(new int[] { 0x1F1F1, 0x1F1FB }, new String[]{"flag-lv"}, 3, 0, false), 172 | new GoogleEmoji(new int[] { 0x1F1F1, 0x1F1FE }, new String[]{"flag-ly"}, 3, 1, false), 173 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1E6 }, new String[]{"flag-ma"}, 3, 2, false), 174 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1E8 }, new String[]{"flag-mc"}, 3, 3, false), 175 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1E9 }, new String[]{"flag-md"}, 3, 4, false), 176 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1EA }, new String[]{"flag-me"}, 3, 5, false), 177 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1EB }, new String[]{"flag-mf"}, 3, 6, false), 178 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1EC }, new String[]{"flag-mg"}, 3, 7, false), 179 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1ED }, new String[]{"flag-mh"}, 3, 8, false), 180 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1F0 }, new String[]{"flag-mk"}, 3, 9, false), 181 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1F1 }, new String[]{"flag-ml"}, 3, 10, false), 182 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1F2 }, new String[]{"flag-mm"}, 3, 11, false), 183 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1F3 }, new String[]{"flag-mn"}, 3, 12, false), 184 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1F4 }, new String[]{"flag-mo"}, 3, 13, false), 185 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1F5 }, new String[]{"flag-mp"}, 3, 14, false), 186 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1F6 }, new String[]{"flag-mq"}, 3, 15, false), 187 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1F7 }, new String[]{"flag-mr"}, 3, 16, false), 188 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1F8 }, new String[]{"flag-ms"}, 3, 17, false), 189 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1F9 }, new String[]{"flag-mt"}, 3, 18, false), 190 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1FA }, new String[]{"flag-mu"}, 3, 19, false), 191 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1FB }, new String[]{"flag-mv"}, 3, 20, false), 192 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1FC }, new String[]{"flag-mw"}, 3, 21, false), 193 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1FD }, new String[]{"flag-mx"}, 3, 22, false), 194 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1FE }, new String[]{"flag-my"}, 3, 23, false), 195 | new GoogleEmoji(new int[] { 0x1F1F2, 0x1F1FF }, new String[]{"flag-mz"}, 3, 24, false), 196 | new GoogleEmoji(new int[] { 0x1F1F3, 0x1F1E6 }, new String[]{"flag-na"}, 3, 25, false), 197 | new GoogleEmoji(new int[] { 0x1F1F3, 0x1F1E8 }, new String[]{"flag-nc"}, 3, 26, false), 198 | new GoogleEmoji(new int[] { 0x1F1F3, 0x1F1EA }, new String[]{"flag-ne"}, 3, 27, false), 199 | new GoogleEmoji(new int[] { 0x1F1F3, 0x1F1EB }, new String[]{"flag-nf"}, 3, 28, false), 200 | new GoogleEmoji(new int[] { 0x1F1F3, 0x1F1EC }, new String[]{"flag-ng"}, 3, 29, false), 201 | new GoogleEmoji(new int[] { 0x1F1F3, 0x1F1EE }, new String[]{"flag-ni"}, 3, 30, false), 202 | new GoogleEmoji(new int[] { 0x1F1F3, 0x1F1F1 }, new String[]{"flag-nl"}, 3, 31, false), 203 | new GoogleEmoji(new int[] { 0x1F1F3, 0x1F1F4 }, new String[]{"flag-no"}, 3, 32, false), 204 | new GoogleEmoji(new int[] { 0x1F1F3, 0x1F1F5 }, new String[]{"flag-np"}, 3, 33, false), 205 | new GoogleEmoji(new int[] { 0x1F1F3, 0x1F1F7 }, new String[]{"flag-nr"}, 3, 34, false), 206 | new GoogleEmoji(new int[] { 0x1F1F3, 0x1F1FA }, new String[]{"flag-nu"}, 3, 35, false), 207 | new GoogleEmoji(new int[] { 0x1F1F3, 0x1F1FF }, new String[]{"flag-nz"}, 3, 36, false), 208 | new GoogleEmoji(new int[] { 0x1F1F4, 0x1F1F2 }, new String[]{"flag-om"}, 3, 37, false), 209 | new GoogleEmoji(new int[] { 0x1F1F5, 0x1F1E6 }, new String[]{"flag-pa"}, 3, 38, false), 210 | new GoogleEmoji(new int[] { 0x1F1F5, 0x1F1EA }, new String[]{"flag-pe"}, 3, 39, false), 211 | new GoogleEmoji(new int[] { 0x1F1F5, 0x1F1EB }, new String[]{"flag-pf"}, 3, 40, false), 212 | new GoogleEmoji(new int[] { 0x1F1F5, 0x1F1EC }, new String[]{"flag-pg"}, 3, 41, false), 213 | new GoogleEmoji(new int[] { 0x1F1F5, 0x1F1ED }, new String[]{"flag-ph"}, 3, 42, false), 214 | new GoogleEmoji(new int[] { 0x1F1F5, 0x1F1F0 }, new String[]{"flag-pk"}, 3, 43, false), 215 | new GoogleEmoji(new int[] { 0x1F1F5, 0x1F1F1 }, new String[]{"flag-pl"}, 3, 44, false), 216 | new GoogleEmoji(new int[] { 0x1F1F5, 0x1F1F2 }, new String[]{"flag-pm"}, 3, 45, false), 217 | new GoogleEmoji(new int[] { 0x1F1F5, 0x1F1F3 }, new String[]{"flag-pn"}, 3, 46, false), 218 | new GoogleEmoji(new int[] { 0x1F1F5, 0x1F1F7 }, new String[]{"flag-pr"}, 3, 47, false), 219 | new GoogleEmoji(new int[] { 0x1F1F5, 0x1F1F8 }, new String[]{"flag-ps"}, 3, 48, false), 220 | new GoogleEmoji(new int[] { 0x1F1F5, 0x1F1F9 }, new String[]{"flag-pt"}, 3, 49, false), 221 | new GoogleEmoji(new int[] { 0x1F1F5, 0x1F1FC }, new String[]{"flag-pw"}, 3, 50, false), 222 | new GoogleEmoji(new int[] { 0x1F1F5, 0x1F1FE }, new String[]{"flag-py"}, 3, 51, false), 223 | new GoogleEmoji(new int[] { 0x1F1F6, 0x1F1E6 }, new String[]{"flag-qa"}, 3, 52, false), 224 | new GoogleEmoji(new int[] { 0x1F1F7, 0x1F1EA }, new String[]{"flag-re"}, 3, 53, false), 225 | new GoogleEmoji(new int[] { 0x1F1F7, 0x1F1F4 }, new String[]{"flag-ro"}, 3, 54, false), 226 | new GoogleEmoji(new int[] { 0x1F1F7, 0x1F1F8 }, new String[]{"flag-rs"}, 3, 55, false), 227 | new GoogleEmoji(new int[] { 0x1F1F7, 0x1F1FA }, new String[]{"ru", "flag-ru"}, 3, 56, false), 228 | new GoogleEmoji(new int[] { 0x1F1F7, 0x1F1FC }, new String[]{"flag-rw"}, 4, 0, false), 229 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1E6 }, new String[]{"flag-sa"}, 4, 1, false), 230 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1E7 }, new String[]{"flag-sb"}, 4, 2, false), 231 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1E8 }, new String[]{"flag-sc"}, 4, 3, false), 232 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1E9 }, new String[]{"flag-sd"}, 4, 4, false), 233 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1EA }, new String[]{"flag-se"}, 4, 5, false), 234 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1EC }, new String[]{"flag-sg"}, 4, 6, false), 235 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1ED }, new String[]{"flag-sh"}, 4, 7, false), 236 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1EE }, new String[]{"flag-si"}, 4, 8, false), 237 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1EF }, new String[]{"flag-sj"}, 4, 9, false), 238 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1F0 }, new String[]{"flag-sk"}, 4, 10, false), 239 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1F1 }, new String[]{"flag-sl"}, 4, 11, false), 240 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1F2 }, new String[]{"flag-sm"}, 4, 12, false), 241 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1F3 }, new String[]{"flag-sn"}, 4, 13, false), 242 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1F4 }, new String[]{"flag-so"}, 4, 14, false), 243 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1F7 }, new String[]{"flag-sr"}, 4, 15, false), 244 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1F8 }, new String[]{"flag-ss"}, 4, 16, false), 245 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1F9 }, new String[]{"flag-st"}, 4, 17, false), 246 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1FB }, new String[]{"flag-sv"}, 4, 18, false), 247 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1FD }, new String[]{"flag-sx"}, 4, 19, false), 248 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1FE }, new String[]{"flag-sy"}, 4, 20, false), 249 | new GoogleEmoji(new int[] { 0x1F1F8, 0x1F1FF }, new String[]{"flag-sz"}, 4, 21, false), 250 | new GoogleEmoji(new int[] { 0x1F1F9, 0x1F1E6 }, new String[]{"flag-ta"}, 4, 22, false), 251 | new GoogleEmoji(new int[] { 0x1F1F9, 0x1F1E8 }, new String[]{"flag-tc"}, 4, 23, false), 252 | new GoogleEmoji(new int[] { 0x1F1F9, 0x1F1E9 }, new String[]{"flag-td"}, 4, 24, false), 253 | new GoogleEmoji(new int[] { 0x1F1F9, 0x1F1EB }, new String[]{"flag-tf"}, 4, 25, false), 254 | new GoogleEmoji(new int[] { 0x1F1F9, 0x1F1EC }, new String[]{"flag-tg"}, 4, 26, false), 255 | new GoogleEmoji(new int[] { 0x1F1F9, 0x1F1ED }, new String[]{"flag-th"}, 4, 27, false), 256 | new GoogleEmoji(new int[] { 0x1F1F9, 0x1F1EF }, new String[]{"flag-tj"}, 4, 28, false), 257 | new GoogleEmoji(new int[] { 0x1F1F9, 0x1F1F0 }, new String[]{"flag-tk"}, 4, 29, false), 258 | new GoogleEmoji(new int[] { 0x1F1F9, 0x1F1F1 }, new String[]{"flag-tl"}, 4, 30, false), 259 | new GoogleEmoji(new int[] { 0x1F1F9, 0x1F1F2 }, new String[]{"flag-tm"}, 4, 31, false), 260 | new GoogleEmoji(new int[] { 0x1F1F9, 0x1F1F3 }, new String[]{"flag-tn"}, 4, 32, false), 261 | new GoogleEmoji(new int[] { 0x1F1F9, 0x1F1F4 }, new String[]{"flag-to"}, 4, 33, false), 262 | new GoogleEmoji(new int[] { 0x1F1F9, 0x1F1F7 }, new String[]{"flag-tr"}, 4, 34, false), 263 | new GoogleEmoji(new int[] { 0x1F1F9, 0x1F1F9 }, new String[]{"flag-tt"}, 4, 35, false), 264 | new GoogleEmoji(new int[] { 0x1F1F9, 0x1F1FB }, new String[]{"flag-tv"}, 4, 36, false), 265 | new GoogleEmoji(new int[] { 0x1F1F9, 0x1F1FC }, new String[]{"flag-tw"}, 4, 37, false), 266 | new GoogleEmoji(new int[] { 0x1F1F9, 0x1F1FF }, new String[]{"flag-tz"}, 4, 38, false), 267 | new GoogleEmoji(new int[] { 0x1F1FA, 0x1F1E6 }, new String[]{"flag-ua"}, 4, 39, false), 268 | new GoogleEmoji(new int[] { 0x1F1FA, 0x1F1EC }, new String[]{"flag-ug"}, 4, 40, false), 269 | new GoogleEmoji(new int[] { 0x1F1FA, 0x1F1F2 }, new String[]{"flag-um"}, 4, 41, false), 270 | new GoogleEmoji(new int[] { 0x1F1FA, 0x1F1F3 }, new String[]{"flag-un"}, 4, 42, false), 271 | new GoogleEmoji(new int[] { 0x1F1FA, 0x1F1F8 }, new String[]{"us", "flag-us"}, 4, 43, false), 272 | new GoogleEmoji(new int[] { 0x1F1FA, 0x1F1FE }, new String[]{"flag-uy"}, 4, 44, false), 273 | new GoogleEmoji(new int[] { 0x1F1FA, 0x1F1FF }, new String[]{"flag-uz"}, 4, 45, false) 274 | }; 275 | } 276 | 277 | private FlagsCategoryChunk0() { 278 | // No instances. 279 | } 280 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/category/FlagsCategoryChunk1.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.category; 18 | 19 | import com.cc.fitwidth.widget.emoji.GoogleEmoji; 20 | 21 | final class FlagsCategoryChunk1 { 22 | @SuppressWarnings("PMD.ExcessiveMethodLength") static GoogleEmoji[] get() { 23 | return new GoogleEmoji[] { 24 | new GoogleEmoji(new int[] { 0x1F1FB, 0x1F1E6 }, new String[]{"flag-va"}, 4, 46, false), 25 | new GoogleEmoji(new int[] { 0x1F1FB, 0x1F1E8 }, new String[]{"flag-vc"}, 4, 47, false), 26 | new GoogleEmoji(new int[] { 0x1F1FB, 0x1F1EA }, new String[]{"flag-ve"}, 4, 48, false), 27 | new GoogleEmoji(new int[] { 0x1F1FB, 0x1F1EC }, new String[]{"flag-vg"}, 4, 49, false), 28 | new GoogleEmoji(new int[] { 0x1F1FB, 0x1F1EE }, new String[]{"flag-vi"}, 4, 50, false), 29 | new GoogleEmoji(new int[] { 0x1F1FB, 0x1F1F3 }, new String[]{"flag-vn"}, 4, 51, false), 30 | new GoogleEmoji(new int[] { 0x1F1FB, 0x1F1FA }, new String[]{"flag-vu"}, 4, 52, false), 31 | new GoogleEmoji(new int[] { 0x1F1FC, 0x1F1EB }, new String[]{"flag-wf"}, 4, 53, false), 32 | new GoogleEmoji(new int[] { 0x1F1FC, 0x1F1F8 }, new String[]{"flag-ws"}, 4, 54, false), 33 | new GoogleEmoji(new int[] { 0x1F1FD, 0x1F1F0 }, new String[]{"flag-xk"}, 4, 55, false), 34 | new GoogleEmoji(new int[] { 0x1F1FE, 0x1F1EA }, new String[]{"flag-ye"}, 4, 56, false), 35 | new GoogleEmoji(new int[] { 0x1F1FE, 0x1F1F9 }, new String[]{"flag-yt"}, 5, 0, false), 36 | new GoogleEmoji(new int[] { 0x1F1FF, 0x1F1E6 }, new String[]{"flag-za"}, 5, 1, false), 37 | new GoogleEmoji(new int[] { 0x1F1FF, 0x1F1F2 }, new String[]{"flag-zm"}, 5, 2, false), 38 | new GoogleEmoji(new int[] { 0x1F1FF, 0x1F1FC }, new String[]{"flag-zw"}, 5, 3, false), 39 | new GoogleEmoji(new int[] { 0x1F3F4, 0xE0067, 0xE0062, 0xE0065, 0xE006E, 0xE0067, 0xE007F }, new String[]{"flag-england"}, 11, 14, false), 40 | new GoogleEmoji(new int[] { 0x1F3F4, 0xE0067, 0xE0062, 0xE0073, 0xE0063, 0xE0074, 0xE007F }, new String[]{"flag-scotland"}, 11, 15, false), 41 | new GoogleEmoji(new int[] { 0x1F3F4, 0xE0067, 0xE0062, 0xE0077, 0xE006C, 0xE0073, 0xE007F }, new String[]{"flag-wales"}, 11, 16, false) 42 | }; 43 | } 44 | 45 | private FlagsCategoryChunk1() { 46 | // No instances. 47 | } 48 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/category/FoodAndDrinkCategory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.category; 18 | 19 | import androidx.annotation.NonNull; 20 | import com.cc.fitwidth.widget.emoji.GoogleEmoji; 21 | import com.cc.fitwidth.widget.emoji.core.EmojiCategory; 22 | 23 | @SuppressWarnings("PMD.MethodReturnsInternalArray") public final class FoodAndDrinkCategory implements EmojiCategory { 24 | private static final GoogleEmoji[] EMOJIS = CategoryUtils.concatAll(FoodAndDrinkCategoryChunk0.get()); 25 | 26 | @Override @NonNull public GoogleEmoji[] getEmojis() { 27 | return EMOJIS; 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/category/FoodAndDrinkCategoryChunk0.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.category; 18 | 19 | import com.cc.fitwidth.widget.emoji.GoogleEmoji; 20 | 21 | final class FoodAndDrinkCategoryChunk0 { 22 | @SuppressWarnings("PMD.ExcessiveMethodLength") static GoogleEmoji[] get() { 23 | return new GoogleEmoji[] { 24 | new GoogleEmoji(0x1F347, new String[]{"grapes"}, 6, 31, false), 25 | new GoogleEmoji(0x1F348, new String[]{"melon"}, 6, 32, false), 26 | new GoogleEmoji(0x1F349, new String[]{"watermelon"}, 6, 33, false), 27 | new GoogleEmoji(0x1F34A, new String[]{"tangerine"}, 6, 34, false), 28 | new GoogleEmoji(0x1F34B, new String[]{"lemon"}, 6, 35, false), 29 | new GoogleEmoji(0x1F34C, new String[]{"banana"}, 6, 36, false), 30 | new GoogleEmoji(0x1F34D, new String[]{"pineapple"}, 6, 37, false), 31 | new GoogleEmoji(0x1F96D, new String[]{"mango"}, 42, 3, false), 32 | new GoogleEmoji(0x1F34E, new String[]{"apple"}, 6, 38, false), 33 | new GoogleEmoji(0x1F34F, new String[]{"green_apple"}, 6, 39, false), 34 | new GoogleEmoji(0x1F350, new String[]{"pear"}, 6, 40, false), 35 | new GoogleEmoji(0x1F351, new String[]{"peach"}, 6, 41, false), 36 | new GoogleEmoji(0x1F352, new String[]{"cherries"}, 6, 42, false), 37 | new GoogleEmoji(0x1F353, new String[]{"strawberry"}, 6, 43, false), 38 | new GoogleEmoji(0x1F95D, new String[]{"kiwifruit"}, 41, 44, false), 39 | new GoogleEmoji(0x1F345, new String[]{"tomato"}, 6, 29, false), 40 | new GoogleEmoji(0x1F965, new String[]{"coconut"}, 41, 52, false), 41 | new GoogleEmoji(0x1F951, new String[]{"avocado"}, 41, 32, false), 42 | new GoogleEmoji(0x1F346, new String[]{"eggplant"}, 6, 30, false), 43 | new GoogleEmoji(0x1F954, new String[]{"potato"}, 41, 35, false), 44 | new GoogleEmoji(0x1F955, new String[]{"carrot"}, 41, 36, false), 45 | new GoogleEmoji(0x1F33D, new String[]{"corn"}, 6, 21, false), 46 | new GoogleEmoji(new int[] { 0x1F336, 0xFE0F }, new String[]{"hot_pepper"}, 6, 14, false), 47 | new GoogleEmoji(0x1F952, new String[]{"cucumber"}, 41, 33, false), 48 | new GoogleEmoji(0x1F96C, new String[]{"leafy_green"}, 42, 2, false), 49 | new GoogleEmoji(0x1F966, new String[]{"broccoli"}, 41, 53, false), 50 | new GoogleEmoji(0x1F9C4, new String[]{"garlic"}, 44, 12, false), 51 | new GoogleEmoji(0x1F9C5, new String[]{"onion"}, 44, 13, false), 52 | new GoogleEmoji(0x1F344, new String[]{"mushroom"}, 6, 28, false), 53 | new GoogleEmoji(0x1F95C, new String[]{"peanuts"}, 41, 43, false), 54 | new GoogleEmoji(0x1F330, new String[]{"chestnut"}, 6, 8, false), 55 | new GoogleEmoji(0x1F35E, new String[]{"bread"}, 6, 54, false), 56 | new GoogleEmoji(0x1F950, new String[]{"croissant"}, 41, 31, false), 57 | new GoogleEmoji(0x1F956, new String[]{"baguette_bread"}, 41, 37, false), 58 | new GoogleEmoji(0x1F968, new String[]{"pretzel"}, 41, 55, false), 59 | new GoogleEmoji(0x1F96F, new String[]{"bagel"}, 42, 5, false), 60 | new GoogleEmoji(0x1F95E, new String[]{"pancakes"}, 41, 45, false), 61 | new GoogleEmoji(0x1F9C7, new String[]{"waffle"}, 44, 15, false), 62 | new GoogleEmoji(0x1F9C0, new String[]{"cheese_wedge"}, 44, 8, false), 63 | new GoogleEmoji(0x1F356, new String[]{"meat_on_bone"}, 6, 46, false), 64 | new GoogleEmoji(0x1F357, new String[]{"poultry_leg"}, 6, 47, false), 65 | new GoogleEmoji(0x1F969, new String[]{"cut_of_meat"}, 41, 56, false), 66 | new GoogleEmoji(0x1F953, new String[]{"bacon"}, 41, 34, false), 67 | new GoogleEmoji(0x1F354, new String[]{"hamburger"}, 6, 44, false), 68 | new GoogleEmoji(0x1F35F, new String[]{"fries"}, 6, 55, false), 69 | new GoogleEmoji(0x1F355, new String[]{"pizza"}, 6, 45, false), 70 | new GoogleEmoji(0x1F32D, new String[]{"hotdog"}, 6, 5, false), 71 | new GoogleEmoji(0x1F96A, new String[]{"sandwich"}, 42, 0, false), 72 | new GoogleEmoji(0x1F32E, new String[]{"taco"}, 6, 6, false), 73 | new GoogleEmoji(0x1F32F, new String[]{"burrito"}, 6, 7, false), 74 | new GoogleEmoji(0x1F959, new String[]{"stuffed_flatbread"}, 41, 40, false), 75 | new GoogleEmoji(0x1F9C6, new String[]{"falafel"}, 44, 14, false), 76 | new GoogleEmoji(0x1F95A, new String[]{"egg"}, 41, 41, false), 77 | new GoogleEmoji(0x1F373, new String[]{"fried_egg", "cooking"}, 7, 18, false), 78 | new GoogleEmoji(0x1F958, new String[]{"shallow_pan_of_food"}, 41, 39, false), 79 | new GoogleEmoji(0x1F372, new String[]{"stew"}, 7, 17, false), 80 | new GoogleEmoji(0x1F963, new String[]{"bowl_with_spoon"}, 41, 50, false), 81 | new GoogleEmoji(0x1F957, new String[]{"green_salad"}, 41, 38, false), 82 | new GoogleEmoji(0x1F37F, new String[]{"popcorn"}, 7, 30, false), 83 | new GoogleEmoji(0x1F9C8, new String[]{"butter"}, 44, 16, false), 84 | new GoogleEmoji(0x1F9C2, new String[]{"salt"}, 44, 10, false), 85 | new GoogleEmoji(0x1F96B, new String[]{"canned_food"}, 42, 1, false), 86 | new GoogleEmoji(0x1F371, new String[]{"bento"}, 7, 16, false), 87 | new GoogleEmoji(0x1F358, new String[]{"rice_cracker"}, 6, 48, false), 88 | new GoogleEmoji(0x1F359, new String[]{"rice_ball"}, 6, 49, false), 89 | new GoogleEmoji(0x1F35A, new String[]{"rice"}, 6, 50, false), 90 | new GoogleEmoji(0x1F35B, new String[]{"curry"}, 6, 51, false), 91 | new GoogleEmoji(0x1F35C, new String[]{"ramen"}, 6, 52, false), 92 | new GoogleEmoji(0x1F35D, new String[]{"spaghetti"}, 6, 53, false), 93 | new GoogleEmoji(0x1F360, new String[]{"sweet_potato"}, 6, 56, false), 94 | new GoogleEmoji(0x1F362, new String[]{"oden"}, 7, 1, false), 95 | new GoogleEmoji(0x1F363, new String[]{"sushi"}, 7, 2, false), 96 | new GoogleEmoji(0x1F364, new String[]{"fried_shrimp"}, 7, 3, false), 97 | new GoogleEmoji(0x1F365, new String[]{"fish_cake"}, 7, 4, false), 98 | new GoogleEmoji(0x1F96E, new String[]{"moon_cake"}, 42, 4, false), 99 | new GoogleEmoji(0x1F361, new String[]{"dango"}, 7, 0, false), 100 | new GoogleEmoji(0x1F95F, new String[]{"dumpling"}, 41, 46, false), 101 | new GoogleEmoji(0x1F960, new String[]{"fortune_cookie"}, 41, 47, false), 102 | new GoogleEmoji(0x1F961, new String[]{"takeout_box"}, 41, 48, false), 103 | new GoogleEmoji(0x1F980, new String[]{"crab"}, 42, 18, false), 104 | new GoogleEmoji(0x1F99E, new String[]{"lobster"}, 42, 48, false), 105 | new GoogleEmoji(0x1F990, new String[]{"shrimp"}, 42, 34, false), 106 | new GoogleEmoji(0x1F991, new String[]{"squid"}, 42, 35, false), 107 | new GoogleEmoji(0x1F9AA, new String[]{"oyster"}, 43, 1, false), 108 | new GoogleEmoji(0x1F366, new String[]{"icecream"}, 7, 5, false), 109 | new GoogleEmoji(0x1F367, new String[]{"shaved_ice"}, 7, 6, false), 110 | new GoogleEmoji(0x1F368, new String[]{"ice_cream"}, 7, 7, false), 111 | new GoogleEmoji(0x1F369, new String[]{"doughnut"}, 7, 8, false), 112 | new GoogleEmoji(0x1F36A, new String[]{"cookie"}, 7, 9, false), 113 | new GoogleEmoji(0x1F382, new String[]{"birthday"}, 7, 33, false), 114 | new GoogleEmoji(0x1F370, new String[]{"cake"}, 7, 15, false), 115 | new GoogleEmoji(0x1F9C1, new String[]{"cupcake"}, 44, 9, false), 116 | new GoogleEmoji(0x1F967, new String[]{"pie"}, 41, 54, false), 117 | new GoogleEmoji(0x1F36B, new String[]{"chocolate_bar"}, 7, 10, false), 118 | new GoogleEmoji(0x1F36C, new String[]{"candy"}, 7, 11, false), 119 | new GoogleEmoji(0x1F36D, new String[]{"lollipop"}, 7, 12, false), 120 | new GoogleEmoji(0x1F36E, new String[]{"custard"}, 7, 13, false), 121 | new GoogleEmoji(0x1F36F, new String[]{"honey_pot"}, 7, 14, false), 122 | new GoogleEmoji(0x1F37C, new String[]{"baby_bottle"}, 7, 27, false), 123 | new GoogleEmoji(0x1F95B, new String[]{"glass_of_milk"}, 41, 42, false), 124 | new GoogleEmoji(0x2615, new String[]{"coffee"}, 53, 0, false), 125 | new GoogleEmoji(0x1F375, new String[]{"tea"}, 7, 20, false), 126 | new GoogleEmoji(0x1F376, new String[]{"sake"}, 7, 21, false), 127 | new GoogleEmoji(0x1F37E, new String[]{"champagne"}, 7, 29, false), 128 | new GoogleEmoji(0x1F377, new String[]{"wine_glass"}, 7, 22, false), 129 | new GoogleEmoji(0x1F378, new String[]{"cocktail"}, 7, 23, false), 130 | new GoogleEmoji(0x1F379, new String[]{"tropical_drink"}, 7, 24, false), 131 | new GoogleEmoji(0x1F37A, new String[]{"beer"}, 7, 25, false), 132 | new GoogleEmoji(0x1F37B, new String[]{"beers"}, 7, 26, false), 133 | new GoogleEmoji(0x1F942, new String[]{"clinking_glasses"}, 41, 18, false), 134 | new GoogleEmoji(0x1F943, new String[]{"tumbler_glass"}, 41, 19, false), 135 | new GoogleEmoji(0x1F964, new String[]{"cup_with_straw"}, 41, 51, false), 136 | new GoogleEmoji(0x1F9C3, new String[]{"beverage_box"}, 44, 11, false), 137 | new GoogleEmoji(0x1F9C9, new String[]{"mate_drink"}, 44, 17, false), 138 | new GoogleEmoji(0x1F9CA, new String[]{"ice_cube"}, 44, 18, false), 139 | new GoogleEmoji(0x1F962, new String[]{"chopsticks"}, 41, 49, false), 140 | new GoogleEmoji(new int[] { 0x1F37D, 0xFE0F }, new String[]{"knife_fork_plate"}, 7, 28, false), 141 | new GoogleEmoji(0x1F374, new String[]{"fork_and_knife"}, 7, 19, false), 142 | new GoogleEmoji(0x1F944, new String[]{"spoon"}, 41, 20, false), 143 | new GoogleEmoji(0x1F52A, new String[]{"hocho", "knife"}, 28, 13, false), 144 | new GoogleEmoji(0x1F3FA, new String[]{"amphora"}, 11, 22, false) 145 | }; 146 | } 147 | 148 | private FoodAndDrinkCategoryChunk0() { 149 | // No instances. 150 | } 151 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/category/ObjectsCategory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.category; 18 | 19 | import androidx.annotation.NonNull; 20 | import com.cc.fitwidth.widget.emoji.GoogleEmoji; 21 | import com.cc.fitwidth.widget.emoji.core.EmojiCategory; 22 | 23 | @SuppressWarnings("PMD.MethodReturnsInternalArray") public final class ObjectsCategory implements EmojiCategory { 24 | private static final GoogleEmoji[] EMOJIS = CategoryUtils.concatAll(ObjectsCategoryChunk0.get()); 25 | 26 | @Override @NonNull public GoogleEmoji[] getEmojis() { 27 | return EMOJIS; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/category/ObjectsCategoryChunk0.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.category; 18 | 19 | import com.cc.fitwidth.widget.emoji.GoogleEmoji; 20 | 21 | final class ObjectsCategoryChunk0 { 22 | @SuppressWarnings("PMD.ExcessiveMethodLength") static GoogleEmoji[] get() { 23 | return new GoogleEmoji[] { 24 | new GoogleEmoji(0x1F453, new String[]{"eyeglasses"}, 14, 7, false), 25 | new GoogleEmoji(new int[] { 0x1F576, 0xFE0F }, new String[]{"dark_sunglasses"}, 29, 33, false), 26 | new GoogleEmoji(0x1F97D, new String[]{"goggles"}, 42, 15, false), 27 | new GoogleEmoji(0x1F97C, new String[]{"lab_coat"}, 42, 14, false), 28 | new GoogleEmoji(0x1F9BA, new String[]{"safety_vest"}, 43, 54, false), 29 | new GoogleEmoji(0x1F454, new String[]{"necktie"}, 14, 8, false), 30 | new GoogleEmoji(0x1F455, new String[]{"shirt", "tshirt"}, 14, 9, false), 31 | new GoogleEmoji(0x1F456, new String[]{"jeans"}, 14, 10, false), 32 | new GoogleEmoji(0x1F9E3, new String[]{"scarf"}, 51, 22, false), 33 | new GoogleEmoji(0x1F9E4, new String[]{"gloves"}, 51, 23, false), 34 | new GoogleEmoji(0x1F9E5, new String[]{"coat"}, 51, 24, false), 35 | new GoogleEmoji(0x1F9E6, new String[]{"socks"}, 51, 25, false), 36 | new GoogleEmoji(0x1F457, new String[]{"dress"}, 14, 11, false), 37 | new GoogleEmoji(0x1F458, new String[]{"kimono"}, 14, 12, false), 38 | new GoogleEmoji(0x1F97B, new String[]{"sari"}, 42, 13, false), 39 | new GoogleEmoji(0x1FA71, new String[]{"one-piece_swimsuit"}, 51, 52, false), 40 | new GoogleEmoji(0x1FA72, new String[]{"briefs"}, 51, 53, false), 41 | new GoogleEmoji(0x1FA73, new String[]{"shorts"}, 51, 54, false), 42 | new GoogleEmoji(0x1F459, new String[]{"bikini"}, 14, 13, false), 43 | new GoogleEmoji(0x1F45A, new String[]{"womans_clothes"}, 14, 14, false), 44 | new GoogleEmoji(0x1F45B, new String[]{"purse"}, 14, 15, false), 45 | new GoogleEmoji(0x1F45C, new String[]{"handbag"}, 14, 16, false), 46 | new GoogleEmoji(0x1F45D, new String[]{"pouch"}, 14, 17, false), 47 | new GoogleEmoji(new int[] { 0x1F6CD, 0xFE0F }, new String[]{"shopping_bags"}, 36, 35, false), 48 | new GoogleEmoji(0x1F392, new String[]{"school_satchel"}, 7, 54, false), 49 | new GoogleEmoji(0x1F45E, new String[]{"mans_shoe", "shoe"}, 14, 18, false), 50 | new GoogleEmoji(0x1F45F, new String[]{"athletic_shoe"}, 14, 19, false), 51 | new GoogleEmoji(0x1F97E, new String[]{"hiking_boot"}, 42, 16, false), 52 | new GoogleEmoji(0x1F97F, new String[]{"womans_flat_shoe"}, 42, 17, false), 53 | new GoogleEmoji(0x1F460, new String[]{"high_heel"}, 14, 20, false), 54 | new GoogleEmoji(0x1F461, new String[]{"sandal"}, 14, 21, false), 55 | new GoogleEmoji(0x1FA70, new String[]{"ballet_shoes"}, 51, 51, false), 56 | new GoogleEmoji(0x1F462, new String[]{"boot"}, 14, 22, false), 57 | new GoogleEmoji(0x1F451, new String[]{"crown"}, 14, 5, false), 58 | new GoogleEmoji(0x1F452, new String[]{"womans_hat"}, 14, 6, false), 59 | new GoogleEmoji(0x1F3A9, new String[]{"tophat"}, 8, 15, false), 60 | new GoogleEmoji(0x1F393, new String[]{"mortar_board"}, 7, 55, false), 61 | new GoogleEmoji(0x1F9E2, new String[]{"billed_cap"}, 51, 21, false), 62 | new GoogleEmoji(new int[] { 0x26D1, 0xFE0F }, new String[]{"helmet_with_white_cross"}, 54, 6, false), 63 | new GoogleEmoji(0x1F4FF, new String[]{"prayer_beads"}, 27, 27, false), 64 | new GoogleEmoji(0x1F484, new String[]{"lipstick"}, 24, 32, false), 65 | new GoogleEmoji(0x1F48D, new String[]{"ring"}, 25, 23, false), 66 | new GoogleEmoji(0x1F48E, new String[]{"gem"}, 25, 24, false), 67 | new GoogleEmoji(0x1F507, new String[]{"mute"}, 27, 35, false), 68 | new GoogleEmoji(0x1F508, new String[]{"speaker"}, 27, 36, false), 69 | new GoogleEmoji(0x1F509, new String[]{"sound"}, 27, 37, false), 70 | new GoogleEmoji(0x1F50A, new String[]{"loud_sound"}, 27, 38, false), 71 | new GoogleEmoji(0x1F4E2, new String[]{"loudspeaker"}, 26, 56, false), 72 | new GoogleEmoji(0x1F4E3, new String[]{"mega"}, 27, 0, false), 73 | new GoogleEmoji(0x1F4EF, new String[]{"postal_horn"}, 27, 12, false), 74 | new GoogleEmoji(0x1F514, new String[]{"bell"}, 27, 48, false), 75 | new GoogleEmoji(0x1F515, new String[]{"no_bell"}, 27, 49, false), 76 | new GoogleEmoji(0x1F3BC, new String[]{"musical_score"}, 8, 34, false), 77 | new GoogleEmoji(0x1F3B5, new String[]{"musical_note"}, 8, 27, false), 78 | new GoogleEmoji(0x1F3B6, new String[]{"notes"}, 8, 28, false), 79 | new GoogleEmoji(new int[] { 0x1F399, 0xFE0F }, new String[]{"studio_microphone"}, 8, 1, false), 80 | new GoogleEmoji(new int[] { 0x1F39A, 0xFE0F }, new String[]{"level_slider"}, 8, 2, false), 81 | new GoogleEmoji(new int[] { 0x1F39B, 0xFE0F }, new String[]{"control_knobs"}, 8, 3, false), 82 | new GoogleEmoji(0x1F3A4, new String[]{"microphone"}, 8, 10, false), 83 | new GoogleEmoji(0x1F3A7, new String[]{"headphones"}, 8, 13, false), 84 | new GoogleEmoji(0x1F4FB, new String[]{"radio"}, 27, 24, false), 85 | new GoogleEmoji(0x1F3B7, new String[]{"saxophone"}, 8, 29, false), 86 | new GoogleEmoji(0x1F3B8, new String[]{"guitar"}, 8, 30, false), 87 | new GoogleEmoji(0x1F3B9, new String[]{"musical_keyboard"}, 8, 31, false), 88 | new GoogleEmoji(0x1F3BA, new String[]{"trumpet"}, 8, 32, false), 89 | new GoogleEmoji(0x1F3BB, new String[]{"violin"}, 8, 33, false), 90 | new GoogleEmoji(0x1FA95, new String[]{"banjo"}, 52, 9, false), 91 | new GoogleEmoji(0x1F941, new String[]{"drum_with_drumsticks"}, 41, 17, false), 92 | new GoogleEmoji(0x1F4F1, new String[]{"iphone"}, 27, 14, false), 93 | new GoogleEmoji(0x1F4F2, new String[]{"calling"}, 27, 15, false), 94 | new GoogleEmoji(new int[] { 0x260E, 0xFE0F }, new String[]{"phone", "telephone"}, 52, 54, false), 95 | new GoogleEmoji(0x1F4DE, new String[]{"telephone_receiver"}, 26, 52, false), 96 | new GoogleEmoji(0x1F4DF, new String[]{"pager"}, 26, 53, false), 97 | new GoogleEmoji(0x1F4E0, new String[]{"fax"}, 26, 54, false), 98 | new GoogleEmoji(0x1F50B, new String[]{"battery"}, 27, 39, false), 99 | new GoogleEmoji(0x1F50C, new String[]{"electric_plug"}, 27, 40, false), 100 | new GoogleEmoji(0x1F4BB, new String[]{"computer"}, 26, 17, false), 101 | new GoogleEmoji(new int[] { 0x1F5A5, 0xFE0F }, new String[]{"desktop_computer"}, 30, 10, false), 102 | new GoogleEmoji(new int[] { 0x1F5A8, 0xFE0F }, new String[]{"printer"}, 30, 11, false), 103 | new GoogleEmoji(new int[] { 0x2328, 0xFE0F }, new String[]{"keyboard"}, 52, 24, false), 104 | new GoogleEmoji(new int[] { 0x1F5B1, 0xFE0F }, new String[]{"three_button_mouse"}, 30, 12, false), 105 | new GoogleEmoji(new int[] { 0x1F5B2, 0xFE0F }, new String[]{"trackball"}, 30, 13, false), 106 | new GoogleEmoji(0x1F4BD, new String[]{"minidisc"}, 26, 19, false), 107 | new GoogleEmoji(0x1F4BE, new String[]{"floppy_disk"}, 26, 20, false), 108 | new GoogleEmoji(0x1F4BF, new String[]{"cd"}, 26, 21, false), 109 | new GoogleEmoji(0x1F4C0, new String[]{"dvd"}, 26, 22, false), 110 | new GoogleEmoji(0x1F9EE, new String[]{"abacus"}, 51, 33, false), 111 | new GoogleEmoji(0x1F3A5, new String[]{"movie_camera"}, 8, 11, false), 112 | new GoogleEmoji(new int[] { 0x1F39E, 0xFE0F }, new String[]{"film_frames"}, 8, 4, false), 113 | new GoogleEmoji(new int[] { 0x1F4FD, 0xFE0F }, new String[]{"film_projector"}, 27, 26, false), 114 | new GoogleEmoji(0x1F3AC, new String[]{"clapper"}, 8, 18, false), 115 | new GoogleEmoji(0x1F4FA, new String[]{"tv"}, 27, 23, false), 116 | new GoogleEmoji(0x1F4F7, new String[]{"camera"}, 27, 20, false), 117 | new GoogleEmoji(0x1F4F8, new String[]{"camera_with_flash"}, 27, 21, false), 118 | new GoogleEmoji(0x1F4F9, new String[]{"video_camera"}, 27, 22, false), 119 | new GoogleEmoji(0x1F4FC, new String[]{"vhs"}, 27, 25, false), 120 | new GoogleEmoji(0x1F50D, new String[]{"mag"}, 27, 41, false), 121 | new GoogleEmoji(0x1F50E, new String[]{"mag_right"}, 27, 42, false), 122 | new GoogleEmoji(new int[] { 0x1F56F, 0xFE0F }, new String[]{"candle"}, 29, 6, false), 123 | new GoogleEmoji(0x1F4A1, new String[]{"bulb"}, 25, 43, false), 124 | new GoogleEmoji(0x1F526, new String[]{"flashlight"}, 28, 9, false), 125 | new GoogleEmoji(0x1F3EE, new String[]{"izakaya_lantern", "lantern"}, 11, 8, false), 126 | new GoogleEmoji(0x1FA94, new String[]{"diya_lamp"}, 52, 8, false), 127 | new GoogleEmoji(0x1F4D4, new String[]{"notebook_with_decorative_cover"}, 26, 42, false), 128 | new GoogleEmoji(0x1F4D5, new String[]{"closed_book"}, 26, 43, false), 129 | new GoogleEmoji(0x1F4D6, new String[]{"book", "open_book"}, 26, 44, false), 130 | new GoogleEmoji(0x1F4D7, new String[]{"green_book"}, 26, 45, false), 131 | new GoogleEmoji(0x1F4D8, new String[]{"blue_book"}, 26, 46, false), 132 | new GoogleEmoji(0x1F4D9, new String[]{"orange_book"}, 26, 47, false), 133 | new GoogleEmoji(0x1F4DA, new String[]{"books"}, 26, 48, false), 134 | new GoogleEmoji(0x1F4D3, new String[]{"notebook"}, 26, 41, false), 135 | new GoogleEmoji(0x1F4D2, new String[]{"ledger"}, 26, 40, false), 136 | new GoogleEmoji(0x1F4C3, new String[]{"page_with_curl"}, 26, 25, false), 137 | new GoogleEmoji(0x1F4DC, new String[]{"scroll"}, 26, 50, false), 138 | new GoogleEmoji(0x1F4C4, new String[]{"page_facing_up"}, 26, 26, false), 139 | new GoogleEmoji(0x1F4F0, new String[]{"newspaper"}, 27, 13, false), 140 | new GoogleEmoji(new int[] { 0x1F5DE, 0xFE0F }, new String[]{"rolled_up_newspaper"}, 30, 23, false), 141 | new GoogleEmoji(0x1F4D1, new String[]{"bookmark_tabs"}, 26, 39, false), 142 | new GoogleEmoji(0x1F516, new String[]{"bookmark"}, 27, 50, false), 143 | new GoogleEmoji(new int[] { 0x1F3F7, 0xFE0F }, new String[]{"label"}, 11, 19, false), 144 | new GoogleEmoji(0x1F4B0, new String[]{"moneybag"}, 26, 6, false), 145 | new GoogleEmoji(0x1F4B4, new String[]{"yen"}, 26, 10, false), 146 | new GoogleEmoji(0x1F4B5, new String[]{"dollar"}, 26, 11, false), 147 | new GoogleEmoji(0x1F4B6, new String[]{"euro"}, 26, 12, false), 148 | new GoogleEmoji(0x1F4B7, new String[]{"pound"}, 26, 13, false), 149 | new GoogleEmoji(0x1F4B8, new String[]{"money_with_wings"}, 26, 14, false), 150 | new GoogleEmoji(0x1F4B3, new String[]{"credit_card"}, 26, 9, false), 151 | new GoogleEmoji(0x1F9FE, new String[]{"receipt"}, 51, 49, false), 152 | new GoogleEmoji(0x1F4B9, new String[]{"chart"}, 26, 15, false), 153 | new GoogleEmoji(0x1F4B1, new String[]{"currency_exchange"}, 26, 7, false), 154 | new GoogleEmoji(0x1F4B2, new String[]{"heavy_dollar_sign"}, 26, 8, false), 155 | new GoogleEmoji(new int[] { 0x2709, 0xFE0F }, new String[]{"email", "envelope"}, 54, 42, false), 156 | new GoogleEmoji(0x1F4E7, new String[]{"e-mail"}, 27, 4, false), 157 | new GoogleEmoji(0x1F4E8, new String[]{"incoming_envelope"}, 27, 5, false), 158 | new GoogleEmoji(0x1F4E9, new String[]{"envelope_with_arrow"}, 27, 6, false), 159 | new GoogleEmoji(0x1F4E4, new String[]{"outbox_tray"}, 27, 1, false), 160 | new GoogleEmoji(0x1F4E5, new String[]{"inbox_tray"}, 27, 2, false), 161 | new GoogleEmoji(0x1F4E6, new String[]{"package"}, 27, 3, false), 162 | new GoogleEmoji(0x1F4EB, new String[]{"mailbox"}, 27, 8, false), 163 | new GoogleEmoji(0x1F4EA, new String[]{"mailbox_closed"}, 27, 7, false), 164 | new GoogleEmoji(0x1F4EC, new String[]{"mailbox_with_mail"}, 27, 9, false), 165 | new GoogleEmoji(0x1F4ED, new String[]{"mailbox_with_no_mail"}, 27, 10, false), 166 | new GoogleEmoji(0x1F4EE, new String[]{"postbox"}, 27, 11, false), 167 | new GoogleEmoji(new int[] { 0x1F5F3, 0xFE0F }, new String[]{"ballot_box_with_ballot"}, 30, 28, false), 168 | new GoogleEmoji(new int[] { 0x270F, 0xFE0F }, new String[]{"pencil2"}, 55, 10, false), 169 | new GoogleEmoji(new int[] { 0x2712, 0xFE0F }, new String[]{"black_nib"}, 55, 11, false), 170 | new GoogleEmoji(new int[] { 0x1F58B, 0xFE0F }, new String[]{"lower_left_fountain_pen"}, 29, 45, false), 171 | new GoogleEmoji(new int[] { 0x1F58A, 0xFE0F }, new String[]{"lower_left_ballpoint_pen"}, 29, 44, false), 172 | new GoogleEmoji(new int[] { 0x1F58C, 0xFE0F }, new String[]{"lower_left_paintbrush"}, 29, 46, false), 173 | new GoogleEmoji(new int[] { 0x1F58D, 0xFE0F }, new String[]{"lower_left_crayon"}, 29, 47, false), 174 | new GoogleEmoji(0x1F4DD, new String[]{"memo", "pencil"}, 26, 51, false), 175 | new GoogleEmoji(0x1F4BC, new String[]{"briefcase"}, 26, 18, false), 176 | new GoogleEmoji(0x1F4C1, new String[]{"file_folder"}, 26, 23, false), 177 | new GoogleEmoji(0x1F4C2, new String[]{"open_file_folder"}, 26, 24, false), 178 | new GoogleEmoji(new int[] { 0x1F5C2, 0xFE0F }, new String[]{"card_index_dividers"}, 30, 15, false), 179 | new GoogleEmoji(0x1F4C5, new String[]{"date"}, 26, 27, false), 180 | new GoogleEmoji(0x1F4C6, new String[]{"calendar"}, 26, 28, false), 181 | new GoogleEmoji(new int[] { 0x1F5D2, 0xFE0F }, new String[]{"spiral_note_pad"}, 30, 19, false), 182 | new GoogleEmoji(new int[] { 0x1F5D3, 0xFE0F }, new String[]{"spiral_calendar_pad"}, 30, 20, false), 183 | new GoogleEmoji(0x1F4C7, new String[]{"card_index"}, 26, 29, false), 184 | new GoogleEmoji(0x1F4C8, new String[]{"chart_with_upwards_trend"}, 26, 30, false), 185 | new GoogleEmoji(0x1F4C9, new String[]{"chart_with_downwards_trend"}, 26, 31, false), 186 | new GoogleEmoji(0x1F4CA, new String[]{"bar_chart"}, 26, 32, false), 187 | new GoogleEmoji(0x1F4CB, new String[]{"clipboard"}, 26, 33, false), 188 | new GoogleEmoji(0x1F4CC, new String[]{"pushpin"}, 26, 34, false), 189 | new GoogleEmoji(0x1F4CD, new String[]{"round_pushpin"}, 26, 35, false), 190 | new GoogleEmoji(0x1F4CE, new String[]{"paperclip"}, 26, 36, false), 191 | new GoogleEmoji(new int[] { 0x1F587, 0xFE0F }, new String[]{"linked_paperclips"}, 29, 43, false), 192 | new GoogleEmoji(0x1F4CF, new String[]{"straight_ruler"}, 26, 37, false), 193 | new GoogleEmoji(0x1F4D0, new String[]{"triangular_ruler"}, 26, 38, false), 194 | new GoogleEmoji(new int[] { 0x2702, 0xFE0F }, new String[]{"scissors"}, 54, 39, false), 195 | new GoogleEmoji(new int[] { 0x1F5C3, 0xFE0F }, new String[]{"card_file_box"}, 30, 16, false), 196 | new GoogleEmoji(new int[] { 0x1F5C4, 0xFE0F }, new String[]{"file_cabinet"}, 30, 17, false), 197 | new GoogleEmoji(new int[] { 0x1F5D1, 0xFE0F }, new String[]{"wastebasket"}, 30, 18, false), 198 | new GoogleEmoji(0x1F512, new String[]{"lock"}, 27, 46, false), 199 | new GoogleEmoji(0x1F513, new String[]{"unlock"}, 27, 47, false), 200 | new GoogleEmoji(0x1F50F, new String[]{"lock_with_ink_pen"}, 27, 43, false), 201 | new GoogleEmoji(0x1F510, new String[]{"closed_lock_with_key"}, 27, 44, false), 202 | new GoogleEmoji(0x1F511, new String[]{"key"}, 27, 45, false), 203 | new GoogleEmoji(new int[] { 0x1F5DD, 0xFE0F }, new String[]{"old_key"}, 30, 22, false), 204 | new GoogleEmoji(0x1F528, new String[]{"hammer"}, 28, 11, false), 205 | new GoogleEmoji(0x1FA93, new String[]{"axe"}, 52, 7, false), 206 | new GoogleEmoji(new int[] { 0x26CF, 0xFE0F }, new String[]{"pick"}, 54, 5, false), 207 | new GoogleEmoji(new int[] { 0x2692, 0xFE0F }, new String[]{"hammer_and_pick"}, 53, 41, false), 208 | new GoogleEmoji(new int[] { 0x1F6E0, 0xFE0F }, new String[]{"hammer_and_wrench"}, 36, 42, false), 209 | new GoogleEmoji(new int[] { 0x1F5E1, 0xFE0F }, new String[]{"dagger_knife"}, 30, 24, false), 210 | new GoogleEmoji(new int[] { 0x2694, 0xFE0F }, new String[]{"crossed_swords"}, 53, 43, false), 211 | new GoogleEmoji(0x1F52B, new String[]{"gun"}, 28, 14, false), 212 | new GoogleEmoji(0x1F3F9, new String[]{"bow_and_arrow"}, 11, 21, false), 213 | new GoogleEmoji(new int[] { 0x1F6E1, 0xFE0F }, new String[]{"shield"}, 36, 43, false), 214 | new GoogleEmoji(0x1F527, new String[]{"wrench"}, 28, 10, false), 215 | new GoogleEmoji(0x1F529, new String[]{"nut_and_bolt"}, 28, 12, false), 216 | new GoogleEmoji(new int[] { 0x2699, 0xFE0F }, new String[]{"gear"}, 53, 47, false), 217 | new GoogleEmoji(new int[] { 0x1F5DC, 0xFE0F }, new String[]{"compression"}, 30, 21, false), 218 | new GoogleEmoji(new int[] { 0x2696, 0xFE0F }, new String[]{"scales"}, 53, 45, false), 219 | new GoogleEmoji(0x1F9AF, new String[]{"probing_cane"}, 43, 3, false), 220 | new GoogleEmoji(0x1F517, new String[]{"link"}, 27, 51, false), 221 | new GoogleEmoji(new int[] { 0x26D3, 0xFE0F }, new String[]{"chains"}, 54, 7, false), 222 | new GoogleEmoji(0x1F9F0, new String[]{"toolbox"}, 51, 35, false), 223 | new GoogleEmoji(0x1F9F2, new String[]{"magnet"}, 51, 37, false), 224 | new GoogleEmoji(new int[] { 0x2697, 0xFE0F }, new String[]{"alembic"}, 53, 46, false), 225 | new GoogleEmoji(0x1F9EA, new String[]{"test_tube"}, 51, 29, false), 226 | new GoogleEmoji(0x1F9EB, new String[]{"petri_dish"}, 51, 30, false), 227 | new GoogleEmoji(0x1F9EC, new String[]{"dna"}, 51, 31, false), 228 | new GoogleEmoji(0x1F52C, new String[]{"microscope"}, 28, 15, false), 229 | new GoogleEmoji(0x1F52D, new String[]{"telescope"}, 28, 16, false), 230 | new GoogleEmoji(0x1F4E1, new String[]{"satellite_antenna"}, 26, 55, false), 231 | new GoogleEmoji(0x1F489, new String[]{"syringe"}, 25, 19, false), 232 | new GoogleEmoji(0x1FA78, new String[]{"drop_of_blood"}, 51, 55, false), 233 | new GoogleEmoji(0x1F48A, new String[]{"pill"}, 25, 20, false), 234 | new GoogleEmoji(0x1FA79, new String[]{"adhesive_bandage"}, 51, 56, false), 235 | new GoogleEmoji(0x1FA7A, new String[]{"stethoscope"}, 52, 0, false), 236 | new GoogleEmoji(0x1F6AA, new String[]{"door"}, 35, 1, false), 237 | new GoogleEmoji(new int[] { 0x1F6CF, 0xFE0F }, new String[]{"bed"}, 36, 37, false), 238 | new GoogleEmoji(new int[] { 0x1F6CB, 0xFE0F }, new String[]{"couch_and_lamp"}, 36, 28, false), 239 | new GoogleEmoji(0x1FA91, new String[]{"chair"}, 52, 5, false), 240 | new GoogleEmoji(0x1F6BD, new String[]{"toilet"}, 36, 14, false), 241 | new GoogleEmoji(0x1F6BF, new String[]{"shower"}, 36, 16, false), 242 | new GoogleEmoji(0x1F6C1, new String[]{"bathtub"}, 36, 23, false), 243 | new GoogleEmoji(0x1FA92, new String[]{"razor"}, 52, 6, false), 244 | new GoogleEmoji(0x1F9F4, new String[]{"lotion_bottle"}, 51, 39, false), 245 | new GoogleEmoji(0x1F9F7, new String[]{"safety_pin"}, 51, 42, false), 246 | new GoogleEmoji(0x1F9F9, new String[]{"broom"}, 51, 44, false), 247 | new GoogleEmoji(0x1F9FA, new String[]{"basket"}, 51, 45, false), 248 | new GoogleEmoji(0x1F9FB, new String[]{"roll_of_paper"}, 51, 46, false), 249 | new GoogleEmoji(0x1F9FC, new String[]{"soap"}, 51, 47, false), 250 | new GoogleEmoji(0x1F9FD, new String[]{"sponge"}, 51, 48, false), 251 | new GoogleEmoji(0x1F9EF, new String[]{"fire_extinguisher"}, 51, 34, false), 252 | new GoogleEmoji(0x1F6D2, new String[]{"shopping_trolley"}, 36, 40, false), 253 | new GoogleEmoji(0x1F6AC, new String[]{"smoking"}, 35, 3, false), 254 | new GoogleEmoji(new int[] { 0x26B0, 0xFE0F }, new String[]{"coffin"}, 53, 54, false), 255 | new GoogleEmoji(new int[] { 0x26B1, 0xFE0F }, new String[]{"funeral_urn"}, 53, 55, false), 256 | new GoogleEmoji(0x1F5FF, new String[]{"moyai"}, 30, 34, false) 257 | }; 258 | } 259 | 260 | private ObjectsCategoryChunk0() { 261 | // No instances. 262 | } 263 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/category/SmileysAndPeopleCategory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.category; 18 | 19 | import androidx.annotation.NonNull; 20 | import com.cc.fitwidth.widget.emoji.GoogleEmoji; 21 | import com.cc.fitwidth.widget.emoji.core.EmojiCategory; 22 | 23 | @SuppressWarnings("PMD.MethodReturnsInternalArray") 24 | public final class SmileysAndPeopleCategory implements EmojiCategory { 25 | private static final GoogleEmoji[] EMOJIS = CategoryUtils.concatAll(SmileysAndPeopleCategoryChunk0.get(), SmileysAndPeopleCategoryChunk1.get()); 26 | 27 | @Override @NonNull public GoogleEmoji[] getEmojis() { 28 | return EMOJIS; 29 | } 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/category/SymbolsCategory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.category; 18 | 19 | import androidx.annotation.NonNull; 20 | import com.cc.fitwidth.widget.emoji.GoogleEmoji; 21 | import com.cc.fitwidth.widget.emoji.core.EmojiCategory; 22 | 23 | @SuppressWarnings("PMD.MethodReturnsInternalArray") public final class SymbolsCategory implements EmojiCategory { 24 | private static final GoogleEmoji[] EMOJIS = CategoryUtils.concatAll(SymbolsCategoryChunk0.get()); 25 | 26 | @Override @NonNull public GoogleEmoji[] getEmojis() { 27 | return EMOJIS; 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/category/SymbolsCategoryChunk0.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.category; 18 | 19 | import com.cc.fitwidth.widget.emoji.GoogleEmoji; 20 | 21 | final class SymbolsCategoryChunk0 { 22 | @SuppressWarnings("PMD.ExcessiveMethodLength") static GoogleEmoji[] get() { 23 | return new GoogleEmoji[] { 24 | new GoogleEmoji(0x1F3E7, new String[]{"atm"}, 11, 1, false), 25 | new GoogleEmoji(0x1F6AE, new String[]{"put_litter_in_its_place"}, 35, 5, false), 26 | new GoogleEmoji(0x1F6B0, new String[]{"potable_water"}, 35, 7, false), 27 | new GoogleEmoji(0x267F, new String[]{"wheelchair"}, 53, 40, false), 28 | new GoogleEmoji(0x1F6B9, new String[]{"mens"}, 36, 10, false), 29 | new GoogleEmoji(0x1F6BA, new String[]{"womens"}, 36, 11, false), 30 | new GoogleEmoji(0x1F6BB, new String[]{"restroom"}, 36, 12, false), 31 | new GoogleEmoji(0x1F6BC, new String[]{"baby_symbol"}, 36, 13, false), 32 | new GoogleEmoji(0x1F6BE, new String[]{"wc"}, 36, 15, false), 33 | new GoogleEmoji(0x1F6C2, new String[]{"passport_control"}, 36, 24, false), 34 | new GoogleEmoji(0x1F6C3, new String[]{"customs"}, 36, 25, false), 35 | new GoogleEmoji(0x1F6C4, new String[]{"baggage_claim"}, 36, 26, false), 36 | new GoogleEmoji(0x1F6C5, new String[]{"left_luggage"}, 36, 27, false), 37 | new GoogleEmoji(new int[] { 0x26A0, 0xFE0F }, new String[]{"warning"}, 53, 50, false), 38 | new GoogleEmoji(0x1F6B8, new String[]{"children_crossing"}, 36, 9, false), 39 | new GoogleEmoji(0x26D4, new String[]{"no_entry"}, 54, 8, false), 40 | new GoogleEmoji(0x1F6AB, new String[]{"no_entry_sign"}, 35, 2, false), 41 | new GoogleEmoji(0x1F6B3, new String[]{"no_bicycles"}, 35, 10, false), 42 | new GoogleEmoji(0x1F6AD, new String[]{"no_smoking"}, 35, 4, false), 43 | new GoogleEmoji(0x1F6AF, new String[]{"do_not_litter"}, 35, 6, false), 44 | new GoogleEmoji(0x1F6B1, new String[]{"non-potable_water"}, 35, 8, false), 45 | new GoogleEmoji(0x1F6B7, new String[]{"no_pedestrians"}, 36, 8, false), 46 | new GoogleEmoji(0x1F4F5, new String[]{"no_mobile_phones"}, 27, 18, false), 47 | new GoogleEmoji(0x1F51E, new String[]{"underage"}, 28, 1, false), 48 | new GoogleEmoji(new int[] { 0x2622, 0xFE0F }, new String[]{"radioactive_sign"}, 53, 9, false), 49 | new GoogleEmoji(new int[] { 0x2623, 0xFE0F }, new String[]{"biohazard_sign"}, 53, 10, false), 50 | new GoogleEmoji(new int[] { 0x2B06, 0xFE0F }, new String[]{"arrow_up"}, 55, 38, false), 51 | new GoogleEmoji(new int[] { 0x2197, 0xFE0F }, new String[]{"arrow_upper_right"}, 52, 17, false), 52 | new GoogleEmoji(new int[] { 0x27A1, 0xFE0F }, new String[]{"arrow_right"}, 55, 32, false), 53 | new GoogleEmoji(new int[] { 0x2198, 0xFE0F }, new String[]{"arrow_lower_right"}, 52, 18, false), 54 | new GoogleEmoji(new int[] { 0x2B07, 0xFE0F }, new String[]{"arrow_down"}, 55, 39, false), 55 | new GoogleEmoji(new int[] { 0x2199, 0xFE0F }, new String[]{"arrow_lower_left"}, 52, 19, false), 56 | new GoogleEmoji(new int[] { 0x2B05, 0xFE0F }, new String[]{"arrow_left"}, 55, 37, false), 57 | new GoogleEmoji(new int[] { 0x2196, 0xFE0F }, new String[]{"arrow_upper_left"}, 52, 16, false), 58 | new GoogleEmoji(new int[] { 0x2195, 0xFE0F }, new String[]{"arrow_up_down"}, 52, 15, false), 59 | new GoogleEmoji(new int[] { 0x2194, 0xFE0F }, new String[]{"left_right_arrow"}, 52, 14, false), 60 | new GoogleEmoji(new int[] { 0x21A9, 0xFE0F }, new String[]{"leftwards_arrow_with_hook"}, 52, 20, false), 61 | new GoogleEmoji(new int[] { 0x21AA, 0xFE0F }, new String[]{"arrow_right_hook"}, 52, 21, false), 62 | new GoogleEmoji(new int[] { 0x2934, 0xFE0F }, new String[]{"arrow_heading_up"}, 55, 35, false), 63 | new GoogleEmoji(new int[] { 0x2935, 0xFE0F }, new String[]{"arrow_heading_down"}, 55, 36, false), 64 | new GoogleEmoji(0x1F503, new String[]{"arrows_clockwise"}, 27, 31, false), 65 | new GoogleEmoji(0x1F504, new String[]{"arrows_counterclockwise"}, 27, 32, false), 66 | new GoogleEmoji(0x1F519, new String[]{"back"}, 27, 53, false), 67 | new GoogleEmoji(0x1F51A, new String[]{"end"}, 27, 54, false), 68 | new GoogleEmoji(0x1F51B, new String[]{"on"}, 27, 55, false), 69 | new GoogleEmoji(0x1F51C, new String[]{"soon"}, 27, 56, false), 70 | new GoogleEmoji(0x1F51D, new String[]{"top"}, 28, 0, false), 71 | new GoogleEmoji(0x1F6D0, new String[]{"place_of_worship"}, 36, 38, false), 72 | new GoogleEmoji(new int[] { 0x269B, 0xFE0F }, new String[]{"atom_symbol"}, 53, 48, false), 73 | new GoogleEmoji(new int[] { 0x1F549, 0xFE0F }, new String[]{"om_symbol"}, 28, 33, false), 74 | new GoogleEmoji(new int[] { 0x2721, 0xFE0F }, new String[]{"star_of_david"}, 55, 15, false), 75 | new GoogleEmoji(new int[] { 0x2638, 0xFE0F }, new String[]{"wheel_of_dharma"}, 53, 15, false), 76 | new GoogleEmoji(new int[] { 0x262F, 0xFE0F }, new String[]{"yin_yang"}, 53, 14, false), 77 | new GoogleEmoji(new int[] { 0x271D, 0xFE0F }, new String[]{"latin_cross"}, 55, 14, false), 78 | new GoogleEmoji(new int[] { 0x2626, 0xFE0F }, new String[]{"orthodox_cross"}, 53, 11, false), 79 | new GoogleEmoji(new int[] { 0x262A, 0xFE0F }, new String[]{"star_and_crescent"}, 53, 12, false), 80 | new GoogleEmoji(new int[] { 0x262E, 0xFE0F }, new String[]{"peace_symbol"}, 53, 13, false), 81 | new GoogleEmoji(0x1F54E, new String[]{"menorah_with_nine_branches"}, 28, 38, false), 82 | new GoogleEmoji(0x1F52F, new String[]{"six_pointed_star"}, 28, 18, false), 83 | new GoogleEmoji(0x2648, new String[]{"aries"}, 53, 20, false), 84 | new GoogleEmoji(0x2649, new String[]{"taurus"}, 53, 21, false), 85 | new GoogleEmoji(0x264A, new String[]{"gemini"}, 53, 22, false), 86 | new GoogleEmoji(0x264B, new String[]{"cancer"}, 53, 23, false), 87 | new GoogleEmoji(0x264C, new String[]{"leo"}, 53, 24, false), 88 | new GoogleEmoji(0x264D, new String[]{"virgo"}, 53, 25, false), 89 | new GoogleEmoji(0x264E, new String[]{"libra"}, 53, 26, false), 90 | new GoogleEmoji(0x264F, new String[]{"scorpius"}, 53, 27, false), 91 | new GoogleEmoji(0x2650, new String[]{"sagittarius"}, 53, 28, false), 92 | new GoogleEmoji(0x2651, new String[]{"capricorn"}, 53, 29, false), 93 | new GoogleEmoji(0x2652, new String[]{"aquarius"}, 53, 30, false), 94 | new GoogleEmoji(0x2653, new String[]{"pisces"}, 53, 31, false), 95 | new GoogleEmoji(0x26CE, new String[]{"ophiuchus"}, 54, 4, false), 96 | new GoogleEmoji(0x1F500, new String[]{"twisted_rightwards_arrows"}, 27, 28, false), 97 | new GoogleEmoji(0x1F501, new String[]{"repeat"}, 27, 29, false), 98 | new GoogleEmoji(0x1F502, new String[]{"repeat_one"}, 27, 30, false), 99 | new GoogleEmoji(new int[] { 0x25B6, 0xFE0F }, new String[]{"arrow_forward"}, 52, 43, false), 100 | new GoogleEmoji(0x23E9, new String[]{"fast_forward"}, 52, 26, false), 101 | new GoogleEmoji(new int[] { 0x23ED, 0xFE0F }, new String[]{"black_right_pointing_double_triangle_with_vertical_bar"}, 52, 30, false), 102 | new GoogleEmoji(new int[] { 0x23EF, 0xFE0F }, new String[]{"black_right_pointing_triangle_with_double_vertical_bar"}, 52, 32, false), 103 | new GoogleEmoji(new int[] { 0x25C0, 0xFE0F }, new String[]{"arrow_backward"}, 52, 44, false), 104 | new GoogleEmoji(0x23EA, new String[]{"rewind"}, 52, 27, false), 105 | new GoogleEmoji(new int[] { 0x23EE, 0xFE0F }, new String[]{"black_left_pointing_double_triangle_with_vertical_bar"}, 52, 31, false), 106 | new GoogleEmoji(0x1F53C, new String[]{"arrow_up_small"}, 28, 31, false), 107 | new GoogleEmoji(0x23EB, new String[]{"arrow_double_up"}, 52, 28, false), 108 | new GoogleEmoji(0x1F53D, new String[]{"arrow_down_small"}, 28, 32, false), 109 | new GoogleEmoji(0x23EC, new String[]{"arrow_double_down"}, 52, 29, false), 110 | new GoogleEmoji(new int[] { 0x23F8, 0xFE0F }, new String[]{"double_vertical_bar"}, 52, 37, false), 111 | new GoogleEmoji(new int[] { 0x23F9, 0xFE0F }, new String[]{"black_square_for_stop"}, 52, 38, false), 112 | new GoogleEmoji(new int[] { 0x23FA, 0xFE0F }, new String[]{"black_circle_for_record"}, 52, 39, false), 113 | new GoogleEmoji(new int[] { 0x23CF, 0xFE0F }, new String[]{"eject"}, 52, 25, false), 114 | new GoogleEmoji(0x1F3A6, new String[]{"cinema"}, 8, 12, false), 115 | new GoogleEmoji(0x1F505, new String[]{"low_brightness"}, 27, 33, false), 116 | new GoogleEmoji(0x1F506, new String[]{"high_brightness"}, 27, 34, false), 117 | new GoogleEmoji(0x1F4F6, new String[]{"signal_strength"}, 27, 19, false), 118 | new GoogleEmoji(0x1F4F3, new String[]{"vibration_mode"}, 27, 16, false), 119 | new GoogleEmoji(0x1F4F4, new String[]{"mobile_phone_off"}, 27, 17, false), 120 | new GoogleEmoji(new int[] { 0x2640, 0xFE0F }, new String[]{"female_sign"}, 53, 18, false), 121 | new GoogleEmoji(new int[] { 0x2642, 0xFE0F }, new String[]{"male_sign"}, 53, 19, false), 122 | new GoogleEmoji(new int[] { 0x2695, 0xFE0F }, new String[]{"medical_symbol", "staff_of_aesculapius"}, 53, 44, false), 123 | new GoogleEmoji(new int[] { 0x267E, 0xFE0F }, new String[]{"infinity"}, 53, 39, false), 124 | new GoogleEmoji(new int[] { 0x267B, 0xFE0F }, new String[]{"recycle"}, 53, 38, false), 125 | new GoogleEmoji(new int[] { 0x269C, 0xFE0F }, new String[]{"fleur_de_lis"}, 53, 49, false), 126 | new GoogleEmoji(0x1F531, new String[]{"trident"}, 28, 20, false), 127 | new GoogleEmoji(0x1F4DB, new String[]{"name_badge"}, 26, 49, false), 128 | new GoogleEmoji(0x1F530, new String[]{"beginner"}, 28, 19, false), 129 | new GoogleEmoji(0x2B55, new String[]{"o"}, 55, 43, false), 130 | new GoogleEmoji(0x2705, new String[]{"white_check_mark"}, 54, 40, false), 131 | new GoogleEmoji(new int[] { 0x2611, 0xFE0F }, new String[]{"ballot_box_with_check"}, 52, 55, false), 132 | new GoogleEmoji(new int[] { 0x2714, 0xFE0F }, new String[]{"heavy_check_mark"}, 55, 12, false), 133 | new GoogleEmoji(new int[] { 0x2716, 0xFE0F }, new String[]{"heavy_multiplication_x"}, 55, 13, false), 134 | new GoogleEmoji(0x274C, new String[]{"x"}, 55, 21, false), 135 | new GoogleEmoji(0x274E, new String[]{"negative_squared_cross_mark"}, 55, 22, false), 136 | new GoogleEmoji(0x2795, new String[]{"heavy_plus_sign"}, 55, 29, false), 137 | new GoogleEmoji(0x2796, new String[]{"heavy_minus_sign"}, 55, 30, false), 138 | new GoogleEmoji(0x2797, new String[]{"heavy_division_sign"}, 55, 31, false), 139 | new GoogleEmoji(0x27B0, new String[]{"curly_loop"}, 55, 33, false), 140 | new GoogleEmoji(0x27BF, new String[]{"loop"}, 55, 34, false), 141 | new GoogleEmoji(new int[] { 0x303D, 0xFE0F }, new String[]{"part_alternation_mark"}, 55, 45, false), 142 | new GoogleEmoji(new int[] { 0x2733, 0xFE0F }, new String[]{"eight_spoked_asterisk"}, 55, 17, false), 143 | new GoogleEmoji(new int[] { 0x2734, 0xFE0F }, new String[]{"eight_pointed_black_star"}, 55, 18, false), 144 | new GoogleEmoji(new int[] { 0x2747, 0xFE0F }, new String[]{"sparkle"}, 55, 20, false), 145 | new GoogleEmoji(new int[] { 0x203C, 0xFE0F }, new String[]{"bangbang"}, 52, 10, false), 146 | new GoogleEmoji(new int[] { 0x2049, 0xFE0F }, new String[]{"interrobang"}, 52, 11, false), 147 | new GoogleEmoji(0x2753, new String[]{"question"}, 55, 23, false), 148 | new GoogleEmoji(0x2754, new String[]{"grey_question"}, 55, 24, false), 149 | new GoogleEmoji(0x2755, new String[]{"grey_exclamation"}, 55, 25, false), 150 | new GoogleEmoji(0x2757, new String[]{"exclamation", "heavy_exclamation_mark"}, 55, 26, false), 151 | new GoogleEmoji(new int[] { 0x3030, 0xFE0F }, new String[]{"wavy_dash"}, 55, 44, false), 152 | new GoogleEmoji(new int[] { 0x00A9, 0xFE0F }, new String[]{"copyright"}, 0, 12, false), 153 | new GoogleEmoji(new int[] { 0x00AE, 0xFE0F }, new String[]{"registered"}, 0, 13, false), 154 | new GoogleEmoji(new int[] { 0x2122, 0xFE0F }, new String[]{"tm"}, 52, 12, false), 155 | new GoogleEmoji(new int[] { 0x0023, 0xFE0F, 0x20E3 }, new String[]{"hash"}, 0, 0, false), 156 | new GoogleEmoji(new int[] { 0x002A, 0xFE0F, 0x20E3 }, new String[]{"keycap_star"}, 0, 1, false), 157 | new GoogleEmoji(new int[] { 0x0030, 0xFE0F, 0x20E3 }, new String[]{"zero"}, 0, 2, false), 158 | new GoogleEmoji(new int[] { 0x0031, 0xFE0F, 0x20E3 }, new String[]{"one"}, 0, 3, false), 159 | new GoogleEmoji(new int[] { 0x0032, 0xFE0F, 0x20E3 }, new String[]{"two"}, 0, 4, false), 160 | new GoogleEmoji(new int[] { 0x0033, 0xFE0F, 0x20E3 }, new String[]{"three"}, 0, 5, false), 161 | new GoogleEmoji(new int[] { 0x0034, 0xFE0F, 0x20E3 }, new String[]{"four"}, 0, 6, false), 162 | new GoogleEmoji(new int[] { 0x0035, 0xFE0F, 0x20E3 }, new String[]{"five"}, 0, 7, false), 163 | new GoogleEmoji(new int[] { 0x0036, 0xFE0F, 0x20E3 }, new String[]{"six"}, 0, 8, false), 164 | new GoogleEmoji(new int[] { 0x0037, 0xFE0F, 0x20E3 }, new String[]{"seven"}, 0, 9, false), 165 | new GoogleEmoji(new int[] { 0x0038, 0xFE0F, 0x20E3 }, new String[]{"eight"}, 0, 10, false), 166 | new GoogleEmoji(new int[] { 0x0039, 0xFE0F, 0x20E3 }, new String[]{"nine"}, 0, 11, false), 167 | new GoogleEmoji(0x1F51F, new String[]{"keycap_ten"}, 28, 2, false), 168 | new GoogleEmoji(0x1F520, new String[]{"capital_abcd"}, 28, 3, false), 169 | new GoogleEmoji(0x1F521, new String[]{"abcd"}, 28, 4, false), 170 | new GoogleEmoji(0x1F522, new String[]{"1234"}, 28, 5, false), 171 | new GoogleEmoji(0x1F523, new String[]{"symbols"}, 28, 6, false), 172 | new GoogleEmoji(0x1F524, new String[]{"abc"}, 28, 7, false), 173 | new GoogleEmoji(new int[] { 0x1F170, 0xFE0F }, new String[]{"a"}, 0, 16, false), 174 | new GoogleEmoji(0x1F18E, new String[]{"ab"}, 0, 20, false), 175 | new GoogleEmoji(new int[] { 0x1F171, 0xFE0F }, new String[]{"b"}, 0, 17, false), 176 | new GoogleEmoji(0x1F191, new String[]{"cl"}, 0, 21, false), 177 | new GoogleEmoji(0x1F192, new String[]{"cool"}, 0, 22, false), 178 | new GoogleEmoji(0x1F193, new String[]{"free"}, 0, 23, false), 179 | new GoogleEmoji(new int[] { 0x2139, 0xFE0F }, new String[]{"information_source"}, 52, 13, false), 180 | new GoogleEmoji(0x1F194, new String[]{"id"}, 0, 24, false), 181 | new GoogleEmoji(new int[] { 0x24C2, 0xFE0F }, new String[]{"m"}, 52, 40, false), 182 | new GoogleEmoji(0x1F195, new String[]{"new"}, 0, 25, false), 183 | new GoogleEmoji(0x1F196, new String[]{"ng"}, 0, 26, false), 184 | new GoogleEmoji(new int[] { 0x1F17E, 0xFE0F }, new String[]{"o2"}, 0, 18, false), 185 | new GoogleEmoji(0x1F197, new String[]{"ok"}, 0, 27, false), 186 | new GoogleEmoji(new int[] { 0x1F17F, 0xFE0F }, new String[]{"parking"}, 0, 19, false), 187 | new GoogleEmoji(0x1F198, new String[]{"sos"}, 0, 28, false), 188 | new GoogleEmoji(0x1F199, new String[]{"up"}, 0, 29, false), 189 | new GoogleEmoji(0x1F19A, new String[]{"vs"}, 0, 30, false), 190 | new GoogleEmoji(0x1F201, new String[]{"koko"}, 5, 4, false), 191 | new GoogleEmoji(new int[] { 0x1F202, 0xFE0F }, new String[]{"sa"}, 5, 5, false), 192 | new GoogleEmoji(new int[] { 0x1F237, 0xFE0F }, new String[]{"u6708"}, 5, 13, false), 193 | new GoogleEmoji(0x1F236, new String[]{"u6709"}, 5, 12, false), 194 | new GoogleEmoji(0x1F22F, new String[]{"u6307"}, 5, 7, false), 195 | new GoogleEmoji(0x1F250, new String[]{"ideograph_advantage"}, 5, 17, false), 196 | new GoogleEmoji(0x1F239, new String[]{"u5272"}, 5, 15, false), 197 | new GoogleEmoji(0x1F21A, new String[]{"u7121"}, 5, 6, false), 198 | new GoogleEmoji(0x1F232, new String[]{"u7981"}, 5, 8, false), 199 | new GoogleEmoji(0x1F251, new String[]{"accept"}, 5, 18, false), 200 | new GoogleEmoji(0x1F238, new String[]{"u7533"}, 5, 14, false), 201 | new GoogleEmoji(0x1F234, new String[]{"u5408"}, 5, 10, false), 202 | new GoogleEmoji(0x1F233, new String[]{"u7a7a"}, 5, 9, false), 203 | new GoogleEmoji(new int[] { 0x3297, 0xFE0F }, new String[]{"congratulations"}, 55, 46, false), 204 | new GoogleEmoji(new int[] { 0x3299, 0xFE0F }, new String[]{"secret"}, 55, 47, false), 205 | new GoogleEmoji(0x1F23A, new String[]{"u55b6"}, 5, 16, false), 206 | new GoogleEmoji(0x1F235, new String[]{"u6e80"}, 5, 11, false), 207 | new GoogleEmoji(0x1F534, new String[]{"red_circle"}, 28, 23, false), 208 | new GoogleEmoji(0x1F7E0, new String[]{"large_orange_circle"}, 37, 3, false), 209 | new GoogleEmoji(0x1F7E1, new String[]{"large_yellow_circle"}, 37, 4, false), 210 | new GoogleEmoji(0x1F7E2, new String[]{"large_green_circle"}, 37, 5, false), 211 | new GoogleEmoji(0x1F535, new String[]{"large_blue_circle"}, 28, 24, false), 212 | new GoogleEmoji(0x1F7E3, new String[]{"large_purple_circle"}, 37, 6, false), 213 | new GoogleEmoji(0x1F7E4, new String[]{"large_brown_circle"}, 37, 7, false), 214 | new GoogleEmoji(0x26AB, new String[]{"black_circle"}, 53, 53, false), 215 | new GoogleEmoji(0x26AA, new String[]{"white_circle"}, 53, 52, false), 216 | new GoogleEmoji(0x1F7E5, new String[]{"large_red_square"}, 37, 8, false), 217 | new GoogleEmoji(0x1F7E7, new String[]{"large_orange_square"}, 37, 10, false), 218 | new GoogleEmoji(0x1F7E8, new String[]{"large_yellow_square"}, 37, 11, false), 219 | new GoogleEmoji(0x1F7E9, new String[]{"large_green_square"}, 37, 12, false), 220 | new GoogleEmoji(0x1F7E6, new String[]{"large_blue_square"}, 37, 9, false), 221 | new GoogleEmoji(0x1F7EA, new String[]{"large_purple_square"}, 37, 13, false), 222 | new GoogleEmoji(0x1F7EB, new String[]{"large_brown_square"}, 37, 14, false), 223 | new GoogleEmoji(0x2B1B, new String[]{"black_large_square"}, 55, 40, false), 224 | new GoogleEmoji(0x2B1C, new String[]{"white_large_square"}, 55, 41, false), 225 | new GoogleEmoji(new int[] { 0x25FC, 0xFE0F }, new String[]{"black_medium_square"}, 52, 46, false), 226 | new GoogleEmoji(new int[] { 0x25FB, 0xFE0F }, new String[]{"white_medium_square"}, 52, 45, false), 227 | new GoogleEmoji(0x25FE, new String[]{"black_medium_small_square"}, 52, 48, false), 228 | new GoogleEmoji(0x25FD, new String[]{"white_medium_small_square"}, 52, 47, false), 229 | new GoogleEmoji(new int[] { 0x25AA, 0xFE0F }, new String[]{"black_small_square"}, 52, 41, false), 230 | new GoogleEmoji(new int[] { 0x25AB, 0xFE0F }, new String[]{"white_small_square"}, 52, 42, false), 231 | new GoogleEmoji(0x1F536, new String[]{"large_orange_diamond"}, 28, 25, false), 232 | new GoogleEmoji(0x1F537, new String[]{"large_blue_diamond"}, 28, 26, false), 233 | new GoogleEmoji(0x1F538, new String[]{"small_orange_diamond"}, 28, 27, false), 234 | new GoogleEmoji(0x1F539, new String[]{"small_blue_diamond"}, 28, 28, false), 235 | new GoogleEmoji(0x1F53A, new String[]{"small_red_triangle"}, 28, 29, false), 236 | new GoogleEmoji(0x1F53B, new String[]{"small_red_triangle_down"}, 28, 30, false), 237 | new GoogleEmoji(0x1F4A0, new String[]{"diamond_shape_with_a_dot_inside"}, 25, 42, false), 238 | new GoogleEmoji(0x1F518, new String[]{"radio_button"}, 27, 52, false), 239 | new GoogleEmoji(0x1F533, new String[]{"white_square_button"}, 28, 22, false), 240 | new GoogleEmoji(0x1F532, new String[]{"black_square_button"}, 28, 21, false) 241 | }; 242 | } 243 | 244 | private SymbolsCategoryChunk0() { 245 | // No instances. 246 | } 247 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/category/TravelAndPlacesCategory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.category; 18 | 19 | import androidx.annotation.NonNull; 20 | import com.cc.fitwidth.widget.emoji.GoogleEmoji; 21 | import com.cc.fitwidth.widget.emoji.core.EmojiCategory; 22 | 23 | @SuppressWarnings("PMD.MethodReturnsInternalArray") public final class TravelAndPlacesCategory implements EmojiCategory { 24 | private static final GoogleEmoji[] EMOJIS = CategoryUtils.concatAll(TravelAndPlacesCategoryChunk0.get()); 25 | 26 | @Override @NonNull public GoogleEmoji[] getEmojis() { 27 | return EMOJIS; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/category/TravelAndPlacesCategoryChunk0.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.category; 18 | 19 | import com.cc.fitwidth.widget.emoji.GoogleEmoji; 20 | 21 | final class TravelAndPlacesCategoryChunk0 { 22 | @SuppressWarnings("PMD.ExcessiveMethodLength") static GoogleEmoji[] get() { 23 | return new GoogleEmoji[] { 24 | new GoogleEmoji(0x1F30D, new String[]{"earth_africa"}, 5, 32, false), 25 | new GoogleEmoji(0x1F30E, new String[]{"earth_americas"}, 5, 33, false), 26 | new GoogleEmoji(0x1F30F, new String[]{"earth_asia"}, 5, 34, false), 27 | new GoogleEmoji(0x1F310, new String[]{"globe_with_meridians"}, 5, 35, false), 28 | new GoogleEmoji(new int[] { 0x1F5FA, 0xFE0F }, new String[]{"world_map"}, 30, 29, false), 29 | new GoogleEmoji(0x1F5FE, new String[]{"japan"}, 30, 33, false), 30 | new GoogleEmoji(0x1F9ED, new String[]{"compass"}, 51, 32, false), 31 | new GoogleEmoji(new int[] { 0x1F3D4, 0xFE0F }, new String[]{"snow_capped_mountain"}, 10, 39, false), 32 | new GoogleEmoji(new int[] { 0x26F0, 0xFE0F }, new String[]{"mountain"}, 54, 11, false), 33 | new GoogleEmoji(0x1F30B, new String[]{"volcano"}, 5, 30, false), 34 | new GoogleEmoji(0x1F5FB, new String[]{"mount_fuji"}, 30, 30, false), 35 | new GoogleEmoji(new int[] { 0x1F3D5, 0xFE0F }, new String[]{"camping"}, 10, 40, false), 36 | new GoogleEmoji(new int[] { 0x1F3D6, 0xFE0F }, new String[]{"beach_with_umbrella"}, 10, 41, false), 37 | new GoogleEmoji(new int[] { 0x1F3DC, 0xFE0F }, new String[]{"desert"}, 10, 47, false), 38 | new GoogleEmoji(new int[] { 0x1F3DD, 0xFE0F }, new String[]{"desert_island"}, 10, 48, false), 39 | new GoogleEmoji(new int[] { 0x1F3DE, 0xFE0F }, new String[]{"national_park"}, 10, 49, false), 40 | new GoogleEmoji(new int[] { 0x1F3DF, 0xFE0F }, new String[]{"stadium"}, 10, 50, false), 41 | new GoogleEmoji(new int[] { 0x1F3DB, 0xFE0F }, new String[]{"classical_building"}, 10, 46, false), 42 | new GoogleEmoji(new int[] { 0x1F3D7, 0xFE0F }, new String[]{"building_construction"}, 10, 42, false), 43 | new GoogleEmoji(0x1F9F1, new String[]{"bricks"}, 51, 36, false), 44 | new GoogleEmoji(new int[] { 0x1F3D8, 0xFE0F }, new String[]{"house_buildings"}, 10, 43, false), 45 | new GoogleEmoji(new int[] { 0x1F3DA, 0xFE0F }, new String[]{"derelict_house_building"}, 10, 45, false), 46 | new GoogleEmoji(0x1F3E0, new String[]{"house"}, 10, 51, false), 47 | new GoogleEmoji(0x1F3E1, new String[]{"house_with_garden"}, 10, 52, false), 48 | new GoogleEmoji(0x1F3E2, new String[]{"office"}, 10, 53, false), 49 | new GoogleEmoji(0x1F3E3, new String[]{"post_office"}, 10, 54, false), 50 | new GoogleEmoji(0x1F3E4, new String[]{"european_post_office"}, 10, 55, false), 51 | new GoogleEmoji(0x1F3E5, new String[]{"hospital"}, 10, 56, false), 52 | new GoogleEmoji(0x1F3E6, new String[]{"bank"}, 11, 0, false), 53 | new GoogleEmoji(0x1F3E8, new String[]{"hotel"}, 11, 2, false), 54 | new GoogleEmoji(0x1F3E9, new String[]{"love_hotel"}, 11, 3, false), 55 | new GoogleEmoji(0x1F3EA, new String[]{"convenience_store"}, 11, 4, false), 56 | new GoogleEmoji(0x1F3EB, new String[]{"school"}, 11, 5, false), 57 | new GoogleEmoji(0x1F3EC, new String[]{"department_store"}, 11, 6, false), 58 | new GoogleEmoji(0x1F3ED, new String[]{"factory"}, 11, 7, false), 59 | new GoogleEmoji(0x1F3EF, new String[]{"japanese_castle"}, 11, 9, false), 60 | new GoogleEmoji(0x1F3F0, new String[]{"european_castle"}, 11, 10, false), 61 | new GoogleEmoji(0x1F492, new String[]{"wedding"}, 25, 28, false), 62 | new GoogleEmoji(0x1F5FC, new String[]{"tokyo_tower"}, 30, 31, false), 63 | new GoogleEmoji(0x1F5FD, new String[]{"statue_of_liberty"}, 30, 32, false), 64 | new GoogleEmoji(0x26EA, new String[]{"church"}, 54, 10, false), 65 | new GoogleEmoji(0x1F54C, new String[]{"mosque"}, 28, 36, false), 66 | new GoogleEmoji(0x1F6D5, new String[]{"hindu_temple"}, 36, 41, false), 67 | new GoogleEmoji(0x1F54D, new String[]{"synagogue"}, 28, 37, false), 68 | new GoogleEmoji(new int[] { 0x26E9, 0xFE0F }, new String[]{"shinto_shrine"}, 54, 9, false), 69 | new GoogleEmoji(0x1F54B, new String[]{"kaaba"}, 28, 35, false), 70 | new GoogleEmoji(0x26F2, new String[]{"fountain"}, 54, 13, false), 71 | new GoogleEmoji(0x26FA, new String[]{"tent"}, 54, 37, false), 72 | new GoogleEmoji(0x1F301, new String[]{"foggy"}, 5, 20, false), 73 | new GoogleEmoji(0x1F303, new String[]{"night_with_stars"}, 5, 22, false), 74 | new GoogleEmoji(new int[] { 0x1F3D9, 0xFE0F }, new String[]{"cityscape"}, 10, 44, false), 75 | new GoogleEmoji(0x1F304, new String[]{"sunrise_over_mountains"}, 5, 23, false), 76 | new GoogleEmoji(0x1F305, new String[]{"sunrise"}, 5, 24, false), 77 | new GoogleEmoji(0x1F306, new String[]{"city_sunset"}, 5, 25, false), 78 | new GoogleEmoji(0x1F307, new String[]{"city_sunrise"}, 5, 26, false), 79 | new GoogleEmoji(0x1F309, new String[]{"bridge_at_night"}, 5, 28, false), 80 | new GoogleEmoji(new int[] { 0x2668, 0xFE0F }, new String[]{"hotsprings"}, 53, 37, false), 81 | new GoogleEmoji(0x1F3A0, new String[]{"carousel_horse"}, 8, 6, false), 82 | new GoogleEmoji(0x1F3A1, new String[]{"ferris_wheel"}, 8, 7, false), 83 | new GoogleEmoji(0x1F3A2, new String[]{"roller_coaster"}, 8, 8, false), 84 | new GoogleEmoji(0x1F488, new String[]{"barber"}, 25, 18, false), 85 | new GoogleEmoji(0x1F3AA, new String[]{"circus_tent"}, 8, 16, false), 86 | new GoogleEmoji(0x1F682, new String[]{"steam_locomotive"}, 34, 1, false), 87 | new GoogleEmoji(0x1F683, new String[]{"railway_car"}, 34, 2, false), 88 | new GoogleEmoji(0x1F684, new String[]{"bullettrain_side"}, 34, 3, false), 89 | new GoogleEmoji(0x1F685, new String[]{"bullettrain_front"}, 34, 4, false), 90 | new GoogleEmoji(0x1F686, new String[]{"train2"}, 34, 5, false), 91 | new GoogleEmoji(0x1F687, new String[]{"metro"}, 34, 6, false), 92 | new GoogleEmoji(0x1F688, new String[]{"light_rail"}, 34, 7, false), 93 | new GoogleEmoji(0x1F689, new String[]{"station"}, 34, 8, false), 94 | new GoogleEmoji(0x1F68A, new String[]{"tram"}, 34, 9, false), 95 | new GoogleEmoji(0x1F69D, new String[]{"monorail"}, 34, 28, false), 96 | new GoogleEmoji(0x1F69E, new String[]{"mountain_railway"}, 34, 29, false), 97 | new GoogleEmoji(0x1F68B, new String[]{"train"}, 34, 10, false), 98 | new GoogleEmoji(0x1F68C, new String[]{"bus"}, 34, 11, false), 99 | new GoogleEmoji(0x1F68D, new String[]{"oncoming_bus"}, 34, 12, false), 100 | new GoogleEmoji(0x1F68E, new String[]{"trolleybus"}, 34, 13, false), 101 | new GoogleEmoji(0x1F690, new String[]{"minibus"}, 34, 15, false), 102 | new GoogleEmoji(0x1F691, new String[]{"ambulance"}, 34, 16, false), 103 | new GoogleEmoji(0x1F692, new String[]{"fire_engine"}, 34, 17, false), 104 | new GoogleEmoji(0x1F693, new String[]{"police_car"}, 34, 18, false), 105 | new GoogleEmoji(0x1F694, new String[]{"oncoming_police_car"}, 34, 19, false), 106 | new GoogleEmoji(0x1F695, new String[]{"taxi"}, 34, 20, false), 107 | new GoogleEmoji(0x1F696, new String[]{"oncoming_taxi"}, 34, 21, false), 108 | new GoogleEmoji(0x1F697, new String[]{"car", "red_car"}, 34, 22, false), 109 | new GoogleEmoji(0x1F698, new String[]{"oncoming_automobile"}, 34, 23, false), 110 | new GoogleEmoji(0x1F699, new String[]{"blue_car"}, 34, 24, false), 111 | new GoogleEmoji(0x1F69A, new String[]{"truck"}, 34, 25, false), 112 | new GoogleEmoji(0x1F69B, new String[]{"articulated_lorry"}, 34, 26, false), 113 | new GoogleEmoji(0x1F69C, new String[]{"tractor"}, 34, 27, false), 114 | new GoogleEmoji(new int[] { 0x1F3CE, 0xFE0F }, new String[]{"racing_car"}, 10, 33, false), 115 | new GoogleEmoji(new int[] { 0x1F3CD, 0xFE0F }, new String[]{"racing_motorcycle"}, 10, 32, false), 116 | new GoogleEmoji(0x1F6F5, new String[]{"motor_scooter"}, 36, 54, false), 117 | new GoogleEmoji(0x1F9BD, new String[]{"manual_wheelchair"}, 44, 5, false), 118 | new GoogleEmoji(0x1F9BC, new String[]{"motorized_wheelchair"}, 44, 4, false), 119 | new GoogleEmoji(0x1F6FA, new String[]{"auto_rickshaw"}, 37, 2, false), 120 | new GoogleEmoji(0x1F6B2, new String[]{"bike"}, 35, 9, false), 121 | new GoogleEmoji(0x1F6F4, new String[]{"scooter"}, 36, 53, false), 122 | new GoogleEmoji(0x1F6F9, new String[]{"skateboard"}, 37, 1, false), 123 | new GoogleEmoji(0x1F68F, new String[]{"busstop"}, 34, 14, false), 124 | new GoogleEmoji(new int[] { 0x1F6E3, 0xFE0F }, new String[]{"motorway"}, 36, 45, false), 125 | new GoogleEmoji(new int[] { 0x1F6E4, 0xFE0F }, new String[]{"railway_track"}, 36, 46, false), 126 | new GoogleEmoji(new int[] { 0x1F6E2, 0xFE0F }, new String[]{"oil_drum"}, 36, 44, false), 127 | new GoogleEmoji(0x26FD, new String[]{"fuelpump"}, 54, 38, false), 128 | new GoogleEmoji(0x1F6A8, new String[]{"rotating_light"}, 34, 56, false), 129 | new GoogleEmoji(0x1F6A5, new String[]{"traffic_light"}, 34, 53, false), 130 | new GoogleEmoji(0x1F6A6, new String[]{"vertical_traffic_light"}, 34, 54, false), 131 | new GoogleEmoji(0x1F6D1, new String[]{"octagonal_sign"}, 36, 39, false), 132 | new GoogleEmoji(0x1F6A7, new String[]{"construction"}, 34, 55, false), 133 | new GoogleEmoji(0x2693, new String[]{"anchor"}, 53, 42, false), 134 | new GoogleEmoji(0x26F5, new String[]{"boat", "sailboat"}, 54, 16, false), 135 | new GoogleEmoji(0x1F6F6, new String[]{"canoe"}, 36, 55, false), 136 | new GoogleEmoji(0x1F6A4, new String[]{"speedboat"}, 34, 52, false), 137 | new GoogleEmoji(new int[] { 0x1F6F3, 0xFE0F }, new String[]{"passenger_ship"}, 36, 52, false), 138 | new GoogleEmoji(new int[] { 0x26F4, 0xFE0F }, new String[]{"ferry"}, 54, 15, false), 139 | new GoogleEmoji(new int[] { 0x1F6E5, 0xFE0F }, new String[]{"motor_boat"}, 36, 47, false), 140 | new GoogleEmoji(0x1F6A2, new String[]{"ship"}, 34, 33, false), 141 | new GoogleEmoji(new int[] { 0x2708, 0xFE0F }, new String[]{"airplane"}, 54, 41, false), 142 | new GoogleEmoji(new int[] { 0x1F6E9, 0xFE0F }, new String[]{"small_airplane"}, 36, 48, false), 143 | new GoogleEmoji(0x1F6EB, new String[]{"airplane_departure"}, 36, 49, false), 144 | new GoogleEmoji(0x1F6EC, new String[]{"airplane_arriving"}, 36, 50, false), 145 | new GoogleEmoji(0x1FA82, new String[]{"parachute"}, 52, 3, false), 146 | new GoogleEmoji(0x1F4BA, new String[]{"seat"}, 26, 16, false), 147 | new GoogleEmoji(0x1F681, new String[]{"helicopter"}, 34, 0, false), 148 | new GoogleEmoji(0x1F69F, new String[]{"suspension_railway"}, 34, 30, false), 149 | new GoogleEmoji(0x1F6A0, new String[]{"mountain_cableway"}, 34, 31, false), 150 | new GoogleEmoji(0x1F6A1, new String[]{"aerial_tramway"}, 34, 32, false), 151 | new GoogleEmoji(new int[] { 0x1F6F0, 0xFE0F }, new String[]{"satellite"}, 36, 51, false), 152 | new GoogleEmoji(0x1F680, new String[]{"rocket"}, 33, 56, false), 153 | new GoogleEmoji(0x1F6F8, new String[]{"flying_saucer"}, 37, 0, false), 154 | new GoogleEmoji(new int[] { 0x1F6CE, 0xFE0F }, new String[]{"bellhop_bell"}, 36, 36, false), 155 | new GoogleEmoji(0x1F9F3, new String[]{"luggage"}, 51, 38, false), 156 | new GoogleEmoji(0x231B, new String[]{"hourglass"}, 52, 23, false), 157 | new GoogleEmoji(0x23F3, new String[]{"hourglass_flowing_sand"}, 52, 36, false), 158 | new GoogleEmoji(0x231A, new String[]{"watch"}, 52, 22, false), 159 | new GoogleEmoji(0x23F0, new String[]{"alarm_clock"}, 52, 33, false), 160 | new GoogleEmoji(new int[] { 0x23F1, 0xFE0F }, new String[]{"stopwatch"}, 52, 34, false), 161 | new GoogleEmoji(new int[] { 0x23F2, 0xFE0F }, new String[]{"timer_clock"}, 52, 35, false), 162 | new GoogleEmoji(new int[] { 0x1F570, 0xFE0F }, new String[]{"mantelpiece_clock"}, 29, 7, false), 163 | new GoogleEmoji(0x1F55B, new String[]{"clock12"}, 28, 50, false), 164 | new GoogleEmoji(0x1F567, new String[]{"clock1230"}, 29, 5, false), 165 | new GoogleEmoji(0x1F550, new String[]{"clock1"}, 28, 39, false), 166 | new GoogleEmoji(0x1F55C, new String[]{"clock130"}, 28, 51, false), 167 | new GoogleEmoji(0x1F551, new String[]{"clock2"}, 28, 40, false), 168 | new GoogleEmoji(0x1F55D, new String[]{"clock230"}, 28, 52, false), 169 | new GoogleEmoji(0x1F552, new String[]{"clock3"}, 28, 41, false), 170 | new GoogleEmoji(0x1F55E, new String[]{"clock330"}, 28, 53, false), 171 | new GoogleEmoji(0x1F553, new String[]{"clock4"}, 28, 42, false), 172 | new GoogleEmoji(0x1F55F, new String[]{"clock430"}, 28, 54, false), 173 | new GoogleEmoji(0x1F554, new String[]{"clock5"}, 28, 43, false), 174 | new GoogleEmoji(0x1F560, new String[]{"clock530"}, 28, 55, false), 175 | new GoogleEmoji(0x1F555, new String[]{"clock6"}, 28, 44, false), 176 | new GoogleEmoji(0x1F561, new String[]{"clock630"}, 28, 56, false), 177 | new GoogleEmoji(0x1F556, new String[]{"clock7"}, 28, 45, false), 178 | new GoogleEmoji(0x1F562, new String[]{"clock730"}, 29, 0, false), 179 | new GoogleEmoji(0x1F557, new String[]{"clock8"}, 28, 46, false), 180 | new GoogleEmoji(0x1F563, new String[]{"clock830"}, 29, 1, false), 181 | new GoogleEmoji(0x1F558, new String[]{"clock9"}, 28, 47, false), 182 | new GoogleEmoji(0x1F564, new String[]{"clock930"}, 29, 2, false), 183 | new GoogleEmoji(0x1F559, new String[]{"clock10"}, 28, 48, false), 184 | new GoogleEmoji(0x1F565, new String[]{"clock1030"}, 29, 3, false), 185 | new GoogleEmoji(0x1F55A, new String[]{"clock11"}, 28, 49, false), 186 | new GoogleEmoji(0x1F566, new String[]{"clock1130"}, 29, 4, false), 187 | new GoogleEmoji(0x1F311, new String[]{"new_moon"}, 5, 36, false), 188 | new GoogleEmoji(0x1F312, new String[]{"waxing_crescent_moon"}, 5, 37, false), 189 | new GoogleEmoji(0x1F313, new String[]{"first_quarter_moon"}, 5, 38, false), 190 | new GoogleEmoji(0x1F314, new String[]{"moon", "waxing_gibbous_moon"}, 5, 39, false), 191 | new GoogleEmoji(0x1F315, new String[]{"full_moon"}, 5, 40, false), 192 | new GoogleEmoji(0x1F316, new String[]{"waning_gibbous_moon"}, 5, 41, false), 193 | new GoogleEmoji(0x1F317, new String[]{"last_quarter_moon"}, 5, 42, false), 194 | new GoogleEmoji(0x1F318, new String[]{"waning_crescent_moon"}, 5, 43, false), 195 | new GoogleEmoji(0x1F319, new String[]{"crescent_moon"}, 5, 44, false), 196 | new GoogleEmoji(0x1F31A, new String[]{"new_moon_with_face"}, 5, 45, false), 197 | new GoogleEmoji(0x1F31B, new String[]{"first_quarter_moon_with_face"}, 5, 46, false), 198 | new GoogleEmoji(0x1F31C, new String[]{"last_quarter_moon_with_face"}, 5, 47, false), 199 | new GoogleEmoji(new int[] { 0x1F321, 0xFE0F }, new String[]{"thermometer"}, 5, 52, false), 200 | new GoogleEmoji(new int[] { 0x2600, 0xFE0F }, new String[]{"sunny"}, 52, 49, false), 201 | new GoogleEmoji(0x1F31D, new String[]{"full_moon_with_face"}, 5, 48, false), 202 | new GoogleEmoji(0x1F31E, new String[]{"sun_with_face"}, 5, 49, false), 203 | new GoogleEmoji(0x1FA90, new String[]{"ringed_planet"}, 52, 4, false), 204 | new GoogleEmoji(0x2B50, new String[]{"star"}, 55, 42, true, 205 | new GoogleEmoji(new int[] { 0x2B50, 0xFE0F }, new String[0], 55, 42, true) 206 | ), 207 | new GoogleEmoji(0x1F31F, new String[]{"star2"}, 5, 50, false), 208 | new GoogleEmoji(0x1F320, new String[]{"stars"}, 5, 51, false), 209 | new GoogleEmoji(0x1F30C, new String[]{"milky_way"}, 5, 31, false), 210 | new GoogleEmoji(new int[] { 0x2601, 0xFE0F }, new String[]{"cloud"}, 52, 50, false), 211 | new GoogleEmoji(0x26C5, new String[]{"partly_sunny"}, 54, 2, false), 212 | new GoogleEmoji(new int[] { 0x26C8, 0xFE0F }, new String[]{"thunder_cloud_and_rain"}, 54, 3, false), 213 | new GoogleEmoji(new int[] { 0x1F324, 0xFE0F }, new String[]{"mostly_sunny", "sun_small_cloud"}, 5, 53, false), 214 | new GoogleEmoji(new int[] { 0x1F325, 0xFE0F }, new String[]{"barely_sunny", "sun_behind_cloud"}, 5, 54, false), 215 | new GoogleEmoji(new int[] { 0x1F326, 0xFE0F }, new String[]{"partly_sunny_rain", "sun_behind_rain_cloud"}, 5, 55, false), 216 | new GoogleEmoji(new int[] { 0x1F327, 0xFE0F }, new String[]{"rain_cloud"}, 5, 56, false), 217 | new GoogleEmoji(new int[] { 0x1F328, 0xFE0F }, new String[]{"snow_cloud"}, 6, 0, false), 218 | new GoogleEmoji(new int[] { 0x1F329, 0xFE0F }, new String[]{"lightning", "lightning_cloud"}, 6, 1, false), 219 | new GoogleEmoji(new int[] { 0x1F32A, 0xFE0F }, new String[]{"tornado", "tornado_cloud"}, 6, 2, false), 220 | new GoogleEmoji(new int[] { 0x1F32B, 0xFE0F }, new String[]{"fog"}, 6, 3, false), 221 | new GoogleEmoji(new int[] { 0x1F32C, 0xFE0F }, new String[]{"wind_blowing_face"}, 6, 4, false), 222 | new GoogleEmoji(0x1F300, new String[]{"cyclone"}, 5, 19, false), 223 | new GoogleEmoji(0x1F308, new String[]{"rainbow"}, 5, 27, false), 224 | new GoogleEmoji(0x1F302, new String[]{"closed_umbrella"}, 5, 21, false), 225 | new GoogleEmoji(new int[] { 0x2602, 0xFE0F }, new String[]{"umbrella"}, 52, 51, false), 226 | new GoogleEmoji(0x2614, new String[]{"umbrella_with_rain_drops"}, 52, 56, false), 227 | new GoogleEmoji(new int[] { 0x26F1, 0xFE0F }, new String[]{"umbrella_on_ground"}, 54, 12, false), 228 | new GoogleEmoji(0x26A1, new String[]{"zap"}, 53, 51, false), 229 | new GoogleEmoji(new int[] { 0x2744, 0xFE0F }, new String[]{"snowflake"}, 55, 19, false), 230 | new GoogleEmoji(new int[] { 0x2603, 0xFE0F }, new String[]{"snowman"}, 52, 52, false), 231 | new GoogleEmoji(0x26C4, new String[]{"snowman_without_snow"}, 54, 1, false), 232 | new GoogleEmoji(new int[] { 0x2604, 0xFE0F }, new String[]{"comet"}, 52, 53, false), 233 | new GoogleEmoji(0x1F525, new String[]{"fire"}, 28, 8, false), 234 | new GoogleEmoji(0x1F4A7, new String[]{"droplet"}, 25, 49, false), 235 | new GoogleEmoji(0x1F30A, new String[]{"ocean"}, 5, 29, false) 236 | }; 237 | } 238 | 239 | private TravelAndPlacesCategoryChunk0() { 240 | // No instances. 241 | } 242 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/core/CacheKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.core; 18 | 19 | public final class CacheKey { 20 | private final int x; 21 | private final int y; 22 | 23 | public CacheKey(final int x, final int y) { 24 | this.x = x; 25 | this.y = y; 26 | } 27 | 28 | @Override public boolean equals(final Object o) { 29 | return o instanceof CacheKey 30 | && x == ((CacheKey) o).x 31 | && y == ((CacheKey) o).y; 32 | } 33 | 34 | @Override public int hashCode() { 35 | return (x << 16) ^ y; 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/core/Emoji.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.core; 18 | 19 | import android.content.Context; 20 | import android.graphics.drawable.Drawable; 21 | import androidx.annotation.*; 22 | import androidx.appcompat.content.res.AppCompatResources; 23 | import java.io.Serializable; 24 | import java.util.*; 25 | 26 | import static java.util.Arrays.asList; 27 | import static java.util.Collections.emptyList; 28 | 29 | @SuppressWarnings("PMD.ArrayIsStoredDirectly") public class Emoji implements Serializable { 30 | private static final long serialVersionUID = 3L; 31 | private static final List EMPTY_EMOJI_LIST = emptyList(); 32 | 33 | @NonNull private final String unicode; 34 | @NonNull private final String[] shortcodes; 35 | @DrawableRes private final int resource; 36 | private final boolean isDuplicate; 37 | @NonNull private final List variants; 38 | @Nullable private Emoji base; 39 | 40 | public Emoji(@NonNull final int[] codePoints, @NonNull final String[] shortcodes, 41 | @DrawableRes final int resource, final boolean isDuplicate) { 42 | this(codePoints, shortcodes, resource, isDuplicate, new Emoji[0]); 43 | } 44 | 45 | public Emoji(final int codePoint, @NonNull final String[] shortcodes, 46 | @DrawableRes final int resource, final boolean isDuplicate) { 47 | this(codePoint, shortcodes, resource, isDuplicate, new Emoji[0]); 48 | } 49 | 50 | public Emoji(final int codePoint, @NonNull final String[] shortcodes, 51 | @DrawableRes final int resource, final boolean isDuplicate, 52 | final Emoji... variants) { 53 | this(new int[]{codePoint}, shortcodes, resource, isDuplicate, variants); 54 | } 55 | 56 | public Emoji(@NonNull final int[] codePoints, @NonNull final String[] shortcodes, 57 | @DrawableRes final int resource, final boolean isDuplicate, 58 | final Emoji... variants) { 59 | this.unicode = new String(codePoints, 0, codePoints.length); 60 | this.shortcodes = shortcodes; 61 | this.resource = resource; 62 | this.isDuplicate = isDuplicate; 63 | this.variants = variants.length == 0 ? EMPTY_EMOJI_LIST : asList(variants); 64 | for (final Emoji variant : variants) { 65 | variant.base = this; 66 | } 67 | } 68 | 69 | @NonNull public String getUnicode() { 70 | return unicode; 71 | } 72 | 73 | @Nullable public List getShortcodes() { 74 | return asList(shortcodes); 75 | } 76 | 77 | /** 78 | * @deprecated Please migrate to getDrawable(). May return -1 in the future for providers that don't use 79 | * resources. 80 | */ 81 | @Deprecated @DrawableRes public int getResource() { 82 | return resource; 83 | } 84 | 85 | @NonNull public Drawable getDrawable(final Context context) { 86 | return AppCompatResources.getDrawable(context, resource); 87 | } 88 | 89 | public boolean isDuplicate() { 90 | return isDuplicate; 91 | } 92 | 93 | @NonNull public List getVariants() { 94 | return new ArrayList<>(variants); 95 | } 96 | 97 | @NonNull public Emoji getBase() { 98 | Emoji result = this; 99 | 100 | while (result.base != null) { 101 | result = result.base; 102 | } 103 | 104 | return result; 105 | } 106 | 107 | public int getLength() { 108 | return unicode.length(); 109 | } 110 | 111 | public boolean hasVariants() { 112 | return !variants.isEmpty(); 113 | } 114 | 115 | public void destroy() { 116 | // For inheritors to override. 117 | } 118 | 119 | @Override public boolean equals(final Object o) { 120 | if (this == o) { 121 | return true; 122 | } 123 | 124 | if (o == null || getClass() != o.getClass()) { 125 | return false; 126 | } 127 | 128 | final Emoji emoji = (Emoji) o; 129 | 130 | return resource == emoji.resource 131 | && unicode.equals(emoji.unicode) 132 | && Arrays.equals(shortcodes, emoji.shortcodes) 133 | && variants.equals(emoji.variants); 134 | } 135 | 136 | @Override public int hashCode() { 137 | int result = unicode.hashCode(); 138 | result = 31 * result + Arrays.hashCode(shortcodes); 139 | result = 31 * result + resource; 140 | result = 31 * result + variants.hashCode(); 141 | return result; 142 | } 143 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/core/EmojiCategory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package com.cc.fitwidth.widget.emoji.core; 18 | 19 | import androidx.annotation.NonNull; 20 | 21 | /** 22 | * Interface for defining a category. 23 | * 24 | * @since 0.4.0 25 | */ 26 | public interface EmojiCategory { 27 | /** 28 | * Returns all of the emojis it can display. 29 | * 30 | * @since 0.4.0 31 | */ 32 | @NonNull Emoji[] getEmojis(); 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/core/RangeBean.kt: -------------------------------------------------------------------------------- 1 | package com.cc.fitwidth.widget.emoji.core 2 | 3 | import android.text.style.ClickableSpan 4 | 5 | /** 6 | * @Description 7 | * @Author:Khaos 8 | * @Date:2021-07-13 9 | * @Time:22:35 10 | */ 11 | data class RangeBean( 12 | var sb: CharSequence = "", //文字信息 13 | val ranges: MutableList = mutableListOf() //范围信息 14 | ) 15 | 16 | data class Range( 17 | var start: Int = 0, //整行文字的开始位置 18 | var end: Int = 0, //整行文字的结束位置 19 | val type: Int = 0, //0普通;1背景色;2前景色;3背景和前景色;4clickSpan 20 | val bgColor: Int = 0, //背景色 21 | val foreColor: Int = 0, //前景色 22 | val split: Boolean = false, //是否被分隔成了多行 23 | var clickSpan: ClickableSpan? = null, //带点击的span 24 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/cc/fitwidth/widget/emoji/read.txt: -------------------------------------------------------------------------------- 1 | 使用Emoji工具的目的:用于从字符串中查找Emoji表情位置,方便解决最后一个是Emoji导致拆分的bug 2 | 参考地址:https://github.com/vanniktech/Emoji -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 25 | 26 | 35 | 36 | 47 | 48 | 49 | 50 | 59 | 60 | 69 | 70 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khaos116/FitWidthTextView/253e1603005c88660246043ad6053aa9253956dc/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | FitW-Text 3 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | buildscript { 3 | ext.kotlin_version = "1.5.21" 4 | repositories { 5 | google() 6 | mavenCentral() 7 | } 8 | dependencies { 9 | classpath "com.android.tools.build:gradle:4.2.2" 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | task clean(type: Delete) { 22 | delete rootProject.buildDir 23 | } -------------------------------------------------------------------------------- /com_ab.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khaos116/FitWidthTextView/253e1603005c88660246043ad6053aa9253956dc/com_ab.jks -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official 22 | ############################################################################## 23 | org.gradle.daemon=true // 开启线程守护,第一次编译时开线程,之后就不会再开了 24 | org.gradle.parallel=true // 开启并行编译,相当于多条线程再走 25 | org.gradle.configureondemand=true 启用新的孵化模式 26 | android.injected.testOnly=false 27 | PROP_APP_ABI=armeabi-v7a 28 | KEY_PASSWORD_ABASE=com_cc 29 | KEY_ALIAS_ABASE=com_cc 30 | STORE_PASSWORD_ABASE=com_cc 31 | STORE_FILE_ABASE=../com_ab.jks -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khaos116/FitWidthTextView/253e1603005c88660246043ad6053aa9253956dc/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Jul 12 15:59:16 ICT 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /image/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khaos116/FitWidthTextView/253e1603005c88660246043ad6053aa9253956dc/image/1.png -------------------------------------------------------------------------------- /image/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khaos116/FitWidthTextView/253e1603005c88660246043ad6053aa9253956dc/image/2.png -------------------------------------------------------------------------------- /image/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khaos116/FitWidthTextView/253e1603005c88660246043ad6053aa9253956dc/image/3.png -------------------------------------------------------------------------------- /image/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khaos116/FitWidthTextView/253e1603005c88660246043ad6053aa9253956dc/image/4.png -------------------------------------------------------------------------------- /image/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khaos116/FitWidthTextView/253e1603005c88660246043ad6053aa9253956dc/image/5.png -------------------------------------------------------------------------------- /image/6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khaos116/FitWidthTextView/253e1603005c88660246043ad6053aa9253956dc/image/6.gif -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "FitWidthTextView" 2 | include ':app' 3 | --------------------------------------------------------------------------------