1.Add the built-in dictionary and configuration files under the assets directory. Please contact [email protected] for dictionary and configuration files.
2.Add the following code into build.gradle file:
build.gradle
aaptOptions{
noCompress 'xz'
}
Add themes by calling Agent.getInstance().addExternalThemes(context, infos).
Delete themes by calling Agent.getInstance().deleteExternalThemes(context, infos).
Get new themes by calling Agent.getInstance().getExternalThemes(context).
Apply themes by calling Agent.getInstance().loadTheme(context,externalId).
For example, add a theme like this:
ExampleApplication.java:
public class ExampleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
… … … … …
addExternalTheme();
Agent.getInstance().loadTheme(this,"my external theme id");
… … … … …
}
private void addExternalTheme() {
Drawable keyboardBackgroundDrawable = ContextCompat.getDrawable(this, R.drawable.test_theme_keyboard_bg);
StateListDrawable keyBackgroundDrawable = new StateListDrawable();
keyBackgroundDrawable.addState(new int[]{android.R.attr.state_pressed}, ContextCompat.getDrawable(this, R.drawable.test_theme_key_press));
keyBackgroundDrawable.addState(new int[]{}, ContextCompat.getDrawable(this, R.drawable.test_theme_key_normal));
StateListDrawable functionKeyBackgroundDrawable = new StateListDrawable();
functionKeyBackgroundDrawable.addState(new int[]{android.R.attr.state_pressed}, ContextCompat.getDrawable(this, R.drawable.test_theme_function_key_press));
functionKeyBackgroundDrawable.addState(new int[]{}, ContextCompat.getDrawable(this, R.drawable.test_theme_function_key_normal));
StateListDrawable spacebarBackgroundDrawable = new StateListDrawable();
spacebarBackgroundDrawable.addState(new int[]{android.R.attr.state_pressed}, ContextCompat.getDrawable(this, R.drawable.test_theme_space_key_press));
spacebarBackgroundDrawable.addState(new int[]{}, ContextCompat.getDrawable(this, R.drawable.test_theme_space_key_normal));
ExternalThemeInfo externalThemeInfo = new ExternalThemeInfo.Builder("my external theme id", "Test Theme")
.setKeyboardBackground(keyboardBackgroundDrawable)
.setKeyBackground(keyBackgroundDrawable)
.setFunctionKeyBackground(functionKeyBackgroundDrawable)
.setSpacebarBackground(spacebarBackgroundDrawable)
.setKeyLetterSizeRatio(0.4f)
.setKeyTextColor(Color.RED)
.setKeyHintLetterColor(Color.BLUE)
.setFunctionKeyTextColor(Color.YELLOW)
.setGestureTrailColor(Color.BLACK)
.build();
Agent.getInstance().addExternalThemes(this, externalThemeInfo);
}
… … … … …
If you wants to implement your own EmojiView rather than using the default EmojiView provided by SDK, you may implement custom EmojiView in onDisplayEmojiKeyboard() and return True at the same time.
NeutralStrip, SuggestionStripView, ChineseSuggestStripView and ChineseComposingTextView could be customized after LatinIME extends ZengineInputMethodService.
NeutralStrip,such as toolbar, will appear when SuggestStripView is gone.
For example:
input_view.xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="?attr/inputViewStyle">
<FrameLayout
android:id="@+id/kb_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
// Add a custom Neutral Strip
<RelativeLayout
android:id="@+id/customized_strip"
android:layout_width="match_parent"
android:layout_height="@dimen/config_suggestions_strip_height"
android:layout_alignTop="@id/kb_container"
android:layoutDirection="ltr"
android:background="@android:color/black">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textStyle="bold"
android:text="Customized Strip"
android:textColor="@android:color/white"/>
</RelativeLayout>
</RelativeLayout>
LatinIME.java:
// Control customized NeutralStip by overriding onHideCustomizedNeutralStripView() / onShowCustomizedNeutralStripView()
@Override
public void onHideCustomizedNeutralStripView() {
// Hide custom NeutralStrip
mCustomizedStrip.setVisibility(View.GONE);
}
@Override
public void onShowCustomizedNeutralStripView() {
// Show custom NeutralStrip
mCustomizedStrip.setVisibility(View.VISIBLE);
}
Zengine provides default SuggestionStripView and its operations.
And also you could customize SuggestStripView by extending com.nlptech.keyboardview.suggestions.SuggestionStripView.
Please implement functions down below if you would like to customize.
This method will ba called by ZengineInputMethodService.class. You need to update the SuggestionStripViewListener and make sure the method pickSuggestionManually() will be called when a word is chosen from the SuggestionStripView.
Update and display suggestion words.
Example :
CustomizedSuggestStripView.java:
public class CustomizedSuggestStripView extends SuggestionStripView {
… … … …
@Override
public void setSuggestionStripViewListener(final SuggestionStripViewListener listener, final View inputView) {
//TODO something
mSuggestionStripViewListener = listener
// Call this in a proper position
// mSuggestionStripViewListener.pickSuggestionManually(index);
}
… … … …
@Override
public void setSuggestions(final SuggestedWords suggestedWords, final boolean isRtlLanguage) {
//TODO something
}
… … … …
}
LatinIME.java:
//Pass customized SuggestionStripView by overriding getSuggestionView() of LatinIME.java
@Override
public SuggestionStripView getSuggestionView() {
// Return the custom keyboard suggestions bar the developer defined
return new CustomizedSuggestStripView(getContext());
}
ZengineInputMethodService provides showSuggestionView() / hideSuggestionView() methods to help the developer to control the display/hide SuggestStripView.
When using Chinese Input Method, Zengine also provides default ChineseSuggestStripView and its operations.
If you would like to customize ChineseSuggestStripView, you need to extend com.nlptech.keyboardview.keyboard.chinese.ChineseSuggestStripView and implement functions down below.
This method will ba called by ZengineInputMethodService.class. You need to update the SuggestionStripViewListener and make sure the method pickSuggestionManually() will be called when a word is chosen from the SuggestionStripView. Due to the data structure designed of the Chinese characters, the parameter of this method is "�the index of your chosen word".
Pass candidate words (if there are enough suggestion words, it will provide 10 words at first by default)
If there're enough suggested words, you can get more suggested words by passing fetch size.
Return a list of suggestion words that have been retrieved for the current input.
Example :
CustomizedChineseSuggestStripView:
public class CustomizedChineseSuggestStripView extends ChineseSuggestStripView implements View.OnClickListener {
… … … …
@Override
public void setChineseSuggestStripViewListener(ChineseSuggestStripViewListener chineseSuggestStripViewListener) {
mChineseSuggestStripViewListener = chineseSuggestStripViewListener;
// Call this in a proper position
// mChineseSuggestStripViewListener.pickSuggestionManually(index);
}
@Override
public void setChineseSuggestion(List<String> list, boolean enableActiveHighlight) {
// only get more 50 items
getMoreSuggestionsList(50);
// implement related behaviors
}
… … … …
}
LatinIME.java:
// Pass customized ChineseSuggestStripView by overriding getChineseSuggestionView() of LatinIME.java
@Override
public ChineseSuggestStripView getChineseSuggestionView() {
// Return the View of of the custom keyboard suggestion bar
return new CustomizedChineseSuggestionView(getContext());
}
When using Chinese Input Method, there's a default ChineseSuggestStripView at the upper left corner of the KeyboardView.
If you would like to customize ChineseComposingTextView, you need to extend com.nlptech.keyboardview.keyboard.chinese. ChineseComposingTextView and implement function down below.
Update the corresponding content under the current composing state
Example :
CustomizedChineseComposingTextView.java:
public class CustomizedChineseComposingTextView extends ChineseComposingTextView {
… … … …
@Override
public void setComposingText(String s) {
// implement related behaviors
mComposingTextView.setText(s);
}
… … … …
}
LatinIME.java:
// Pass customized ChineseSuggestStripView by overriding getChineseSuggestionView() of LatinIME.java
@Override
public ChineseComposingTextView getChineseComposingTextView() {
// Return View of suggestion bar customized by the developer
return new Customized ChineseComposingTextView(getContext());
}
LatinIME.java:
… … … … …
public void onCreate() {
DebugFlags.init(PreferenceManager.getDefaultSharedPreferences(this));
RichInputMethodManager.init(this);
mRichImm = RichInputMethodManager.getInstance();
Agent.getInstance().onCreate(this, mInputLogic, new LanguageCallback() {
@Override
public void onIMELanguageChanged(InputMethodSubtype subtype) {
onCurrentInputMethodSubtypeChanged(subtype);
}
});
//Callback for input events (Optional)
Agent.getInstance().setUserInputCallback(
new IUserInputCallback() {
@Override
public void onUserTyping(String wordComposing) { }
@Override
public void onUserTyped(String text) { }
@Override
public void onTextChanged(int direction) { }
});
}
You can get all the Id of Theme through:
Agent.getInstance().getThemeIds(context);
To create ThemeContext, build a view container and use Agent to put theme preview in.
Context themeContext = Agent.getInstance().getThemeContext(context, themeId);
Example:
View myView = LayoutInflater.from(themeContext).inflate(R.layout.my_view, null);
ViewGroup myContainer = myView.findViewById(R.id.my_view_preview_container);
Agent.getInstance().showThemePreview(myContainer, themeId)
Last, you can call it in the component's onPause or onDestroy:
Agent.getInstance().dismissThemePreview();
[zengine v1.3]
First, you need add FloatingKeyboard layout in your input_view.xml, for example:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="?attr/inputViewStyle"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- This is the FloatingKeyboard layout, wrapping up your keyboard layout content. -->
<com.nlptech.keyboardview.floatingkeyboard.FloatingKeyboard
android:id="@+id/floating_kb"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/kb_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
<LinearLayout
android:id="@+id/toolbar_items_container"
android:layout_width="match_parent"
android:layout_height="@dimen/config_suggestions_strip_height"
android:layout_alignTop="@id/kb_container"
android:background="@android:color/black"
android:layoutDirection="ltr" />
<FrameLayout
android:id="@+id/keyboard_widget_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.nlptech.keyboardview.floatingkeyboard.FloatingKeyboard>
</RelativeLayout>
Add this code in the InputMethodService.onCreateInputView():
Agent.getInstance().onCreateInputView(kbContainer, floatinKeyboard, mIsHardwareAcceleratedDrawingEnabled);
You can use those code to:
Control the floating keyboard switch:
KeyboardSwitcher.getInstance().switchFloatingKeyboard(context);
Get the floating keyboard switch on or off:
KeyboardSwitcher.getInstance().isFloatingKeyboard();
Enter the floating keyboard resize mode:
KeyboardSwitcher.getInstance().switchFloatingKeyboardResizeMode(shown);
[zengine v1.3.9]
The SDK can automatically get all of download theme 's downlaod info. You can use this code to get DownloadTheme as a KeyboardTheme:
KeyboardThemeManager.getInstance().getAvailableThemeArray(context)
The DownloadTheme 's themeType is KeyboardTheme.ThemeType.DOWNLOAD.
You can use this code to get the DownloadTheme 's status:
DownloadTheme downloadTheme = (DownloadTheme) keyboarTheme;
int status = downloadTheme.getDownloadStatus();
The status value will be:
Status | Description |
---|---|
DownloadTheme.DOWNLOAD_STATUS_DOWNLOADABLE | 可下載 |
DownloadTheme.DOWNLOAD_STATUS_DOWNLOADING | 下載中 |
DownloadTheme.DOWNLOAD_STATUS_DOWNLOADED | 已下載的 |
You can use this code to download the theme 's resource:
ThemeDownloadInfo themeDownloadInfo = downloadTheme.getDownloadInfo();
DownloadThemeManager.getInstance().downloadTheme(context, themeDownloadInfo);
You can use this code to delete the theme 's resource::
DownloadThemeManager.getInstance().deleteTheme(context, downloadTheme);
Make a BroadcastReceiver to listen the DownloadTheme 's status be changed:
private DownloadThemeReceiver receiver = new DownloadThemeReceiver();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
......
IntentFilter intentFilter = new IntentFilter(DownloadThemeManager.ACTION_UPDATE_DOWNLOAD_THEME);
registerReceiver(receiver, intentFilter);
}
@Override
protected void onDestroy() {
......
unregisterReceiver(receiver);
}
public static class DownloadThemeReceiver : BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
if (DownloadThemeManager.ACTION_UPDATE_DOWNLOAD_THEME != intent.action) {
return
}
String themeId = intent.getStringExtra(DownloadThemeManager.KEY_DOWNLOAD_THEME_ID);
// The themeId is by user call setThemeId() when creating ThemeDownloadInfo
if(themeId == null){
return
}
int status = intent.getIntExtra(DownloadThemeManager.KEY_DOWNLOAD_THEME_STATUS, -1);
// status:
// THEME_DOWNLOAD_STATUS_DOWNLOADABLE
// THEME_DOWNLOAD_STATUS_DOWNLOADING
// THEME_DOWNLOAD_STATUS_DOWNLOADED
// THEME_DOWNLOAD_STATUS_DELETED
if (status == -1) {
return
}
// TODO: You can refresh your theme list here.
}
}
If you want to create your DownloadTheme 's resource on your server, please follow 8.3 ~ 8.6
Every download theme must have a resource, the format is in Resource Format. You can create your resource as zip and upload to your server.
Your server need to provide API for APP witch implements DownloadThemeManager.Listener to fetch all of the download theme 's download info。
Download theme 's download info has those fields:
field | type | description |
---|---|---|
themeId | String | You can defind yourself. |
themeName | String | Theme name. |
themeUrl | String | Theme resource zip 's download url. |
themeCover | String | Theme 's placeholder. |
themeCoverWithBorder | String | Theme 's placeholder with border, can be null if none. |
mode | Integer | 0: Light、1: Dark,When the theme ids are same and mode are different , you can let yoyr user switch Light/Dark mode. |
md5 | String | resource zip 's md5. |
size | Integer | resource zip 's file size. |
version | Integer | resource version, according to version, SDK will update theme resource or not. |
APP implements DownloadThemeManager.Listener, for example:
public class DownloadThemeDataFetcher implements DownloadThemeManager.Listener {
private static final String TAG = DownloadThemeDataFetcher.class.getSimpleName();
@Override
@WorkerThread
public ArrayList<ThemeDownloadInfo> onFetchThemeDownloadInfo() {
ArrayList<ThemeDownloadInfo> result = new ArrayList<>();
// Fetch download theme 's download info from your server.
......
......
......
// Create the ThemeDownloadInfo.
for (YourDataObject item : items) {
ThemeDownloadInfo downloadInfo = new ThemeDownloadInfo();
downloadInfo.setThemeId(item.getTheme_id());
downloadInfo.setThemeName(item.getTheme_name());
downloadInfo.setThemeUrl(item.getTheme_url());
downloadInfo.setThemeCover(item.getTheme_cover()); // url
downloadInfo.setThemeCoverWithBorder(item.getTheme_cover_with_border()); // url
downloadInfo.setMode(Integer.parseInt(item.getMode()));
downloadInfo.setMd5(item.getMd5());
downloadInfo.setSize(item.getSize());
downloadInfo.setVersion(item.getVersion());
result.add(downloadInfo);
}
return result;
}
}
Call this code to set DownloadThemeDataFetcher(recommend in Application.onCreate()):
DownloadThemeManager.getInstance().setDownloadThemeDataListener(new DownloadThemeDataFetcher());
SDK will trigger to fetch theme 's download info at the Application.onCreate() and InputMethodService.onWindowHide().
But you can trigger on demand:
DownloadThemeManager.getInstance().triggerFetchData(context);
If it is first time or cache is time out, SDK will use DownloadThemeDataFetcher to fetch theme 's download info.
You can also use this code to set cache timeout duration, default is 12 hour:
DownloadThemeManager.getInstance().setFetchDownloadThemeDataDuration(duration);