Merge pull request #6369 from keymanapp/fix/fv/dictionary-keyboard-list

fix(oem/fv/android): Consolidate dictionary and keyboard settings
This commit is contained in:
Darcy Wong 2022-03-15 21:03:32 +07:00 committed by GitHub
commit c3da55d9ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 266 additions and 156 deletions

View file

@ -1325,7 +1325,17 @@ public final class KMManager {
return true;
}
public static boolean setBannerOptions(boolean mayPredict) {
/**
* deleteLexicalModel - Remove lexical model from the installed list
* and deregister the model with KMW
* @param context
* @param position - int position in the models list
*/
public static void deleteLexicalModel(Context context, int position, boolean silenceNotification) {
KeyboardPickerActivity.deleteLexicalModel(context, position, silenceNotification);
}
public static boolean setBannerOptions(boolean mayPredict) {
String url = KMString.format("setBannerOptions(%s)", mayPredict);
if (InAppKeyboard != null) {
InAppKeyboard.loadJavascript(url);

View file

@ -275,7 +275,7 @@ public final class ModelPickerActivity extends BaseActivity {
// Uses the repo dataset's master lexical model list to create a filtered adapter for use here.
// As this one is specific to this class, we can implement Activity-specific functionality within it.
static private class FilteredLexicalModelAdapter extends NestedAdapter<LexicalModel, Dataset.LexicalModels, String> {
static public class FilteredLexicalModelAdapter extends NestedAdapter<LexicalModel, Dataset.LexicalModels, String> {
static final int RESOURCE = R.layout.models_list_row_layout;
private final Context context;

View file

@ -97,7 +97,6 @@
<!-- Context: Keyboard Updates -->
<string name="dictionary_update_message">Updates available for dictionary %1$s: %2$s </string>
<!-- Context: Keyboard Info and Keyboard Settings -->
<string name="keyboard_version" comment="Label for keyboard version">Keyboard version</string>
@ -133,6 +132,9 @@
<!-- Context: Query for associated dictionary -->
<string name="query_associated_model" comment="Check if there's an available dictionary to download">Checking for associated dictionary to download</string>
<string name="cannot_query_associated_model" comment="Cannot reach server to check if there's an available dictionary to download">
Cannot connect to Keyman server to check for associated dictionary to download</string>
<!-- Context: Model Updates -->
<string name="confirm_download_model" comment="Confirmation to download a dictionary update">Would you like to download the latest version of this dictionary?</string>
@ -210,10 +212,14 @@
<!-- Context: Language Settings menu strings -->
<string name="model_label">Dictionary</string>
<plurals name="model_count">
<item quantity="one">Dictionary</item>
<item quantity="other">Dictionaries</item>
</plurals>
<!-- Context: Language Settings menu substring - Check for available dictionary -->
<string name="check_available_model" comment="Check for available dictionary">Check for available dictionary</string>
<string name="check_model_online" comment="Check for dictionaries online">Check for dictionaries online</string>
<!-- Context: Language Settings menu strings -->
<string name="model_info_header" comment="Dictionary name">Dictionary: %1$s</string>

View file

@ -54,10 +54,6 @@ class FVKeyboardListAdapter extends ArrayAdapter<FVShared.FVKeyboard> {
holder.nextButton = convertView.findViewById(R.id.imageNext);
holder.nextButton.setOnClickListener(new FVKeyboardListAdapter.FVOnClickNextListener());
convertView.setTag(holder);
if (listFont != null) {
holder.text1.setTypeface(listFont, Typeface.BOLD);
}
} else {
holder = (ViewHolder) convertView.getTag();
}

View file

@ -1,12 +1,18 @@
package com.firstvoices.keyboards;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
@ -15,7 +21,10 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SwitchCompat;
import androidx.appcompat.widget.Toolbar;
import com.tavultesoft.kmea.KMKeyboardDownloaderActivity;
import com.tavultesoft.kmea.KMManager;
import com.tavultesoft.kmea.KeyboardPickerActivity;
import com.tavultesoft.kmea.ModelInfoActivity;
import com.tavultesoft.kmea.ModelPickerActivity;
import com.tavultesoft.kmea.cloud.CloudApiTypes;
import com.tavultesoft.kmea.cloud.CloudDownloadMgr;
@ -24,9 +33,12 @@ import com.tavultesoft.kmea.data.CloudRepository;
import com.tavultesoft.kmea.data.Dataset;
import com.tavultesoft.kmea.data.Keyboard;
import com.tavultesoft.kmea.data.KeyboardController;
import com.tavultesoft.kmea.data.LexicalModel;
import com.tavultesoft.kmea.util.BCP47;
import com.tavultesoft.kmea.util.KMLog;
import com.tavultesoft.kmea.util.MapCompat;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
@ -34,16 +46,20 @@ import java.util.HashMap;
* Displays an FV Keyboard enable and some lexical model switches.
*/
public final class FVKeyboardSettingsActivity extends AppCompatActivity {
private Context context;
private static Context context = null;
private static Toolbar toolbar = null;
private static TextView fvKeyboardTextView = null;
private static TextView fvVersionTextView = null;
private static TextView lexicalModelTextView = null;
private static TextView correctionsTextView = null;
private static SwitchCompat fvKeyboardToggle = null;
private static SwitchCompat correctionsToggle = null;
private static ModelPickerActivity.FilteredLexicalModelAdapter listAdapter = null;
private String associatedLexicalModel = "";
private String lgCode;
private static RelativeLayout checkModelLayout = null;
private static Intent intent = null;
private static Bundle bundle = null;
private static ListView listView = null;
private String lgName;
private String kbId;
private String kbName;
@ -51,6 +67,7 @@ public final class FVKeyboardSettingsActivity extends AppCompatActivity {
private String version;
private SharedPreferences prefs;
private DataSetObserver repoObserver;
private static Dataset repo;
private boolean didExecuteParser = false;
@ -104,7 +121,10 @@ public final class FVKeyboardSettingsActivity extends AppCompatActivity {
context = this;
setContentView(R.layout.fv_keyboard_settings_list_layout);
Bundle bundle = getIntent().getExtras();
if (getIntent() != null && getIntent().getExtras() != null) {
intent = getIntent();
bundle = intent.getExtras();
}
if (bundle == null) {
// Should never actually happen.
KMLog.LogError(TAG, "Language data not specified for FVKeyboardSettingsActivity!");
@ -117,11 +137,17 @@ public final class FVKeyboardSettingsActivity extends AppCompatActivity {
}
}
// Force the cloud catalog to update
// Establish the list view based on the CloudRepository's Dataset
if (!didExecuteParser) {
didExecuteParser = true;
repo = CloudRepository.shared.fetchDataset(context);
}
// add listener to dataset to get event for catalog update.
repoObserver = new DataSetObserver() {
@Override public void onChanged() {
}
};
repo.registerDataSetObserver(repoObserver);
kbId = bundle.getString(KMManager.KMKey_KeyboardID);
kbName = bundle.getString(KMManager.KMKey_KeyboardName);
@ -149,22 +175,8 @@ public final class FVKeyboardSettingsActivity extends AppCompatActivity {
public void onClick(View v) {
// If keyboard enabled, determine if associated lexical model should be downloaded
// Check if associated model is not already installed
if (fvKeyboardToggle.isChecked() && (KMManager.getAssociatedLexicalModel(lgCode) == null) && KMManager.hasConnection(context)) {
String _downloadid = CloudLexicalModelMetaDataDownloadCallback.createDownloadId(lgCode);
CloudLexicalModelMetaDataDownloadCallback _callback = new CloudLexicalModelMetaDataDownloadCallback();
Toast.makeText(context,
context.getString(R.string.query_associated_model),
Toast.LENGTH_SHORT).show();
ArrayList<CloudApiTypes.CloudApiParam> aPreparedCloudApiParams = new ArrayList<>();
String url = CloudRepository.prepareLexicalModelQuery(lgCode);
aPreparedCloudApiParams.add(new CloudApiTypes.CloudApiParam(
CloudApiTypes.ApiTarget.KeyboardLexicalModels, url).setType(CloudApiTypes.JSONType.Array));
CloudDownloadMgr.getInstance().executeAsDownload(
context, _downloadid, null, _callback,
aPreparedCloudApiParams.toArray(new CloudApiTypes.CloudApiParam[0]));
if (fvKeyboardToggle.isChecked() && (KMManager.getAssociatedLexicalModel(lgCode) == null)) {
queryModel();
}
FVShared.getInstance().setCheckState(kbId, fvKeyboardToggle.isChecked());
@ -172,10 +184,9 @@ public final class FVKeyboardSettingsActivity extends AppCompatActivity {
});
// The following two layouts/toggles will need to link with these objects.
Context appContext = this.getApplicationContext();
prefs = appContext.getSharedPreferences(appContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE);
boolean mayPredict = prefs.getBoolean(KMManager.getLanguagePredictionPreferenceKey(lgCode), true);
boolean mayCorrect = prefs.getBoolean(KMManager.getLanguageCorrectionPreferenceKey(lgCode), true);
prefs = context.getSharedPreferences(context.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE);
boolean mayPredict = prefs.getBoolean(KMManager.getLanguagePredictionPreferenceKey(lgCode), false);
boolean mayCorrect = prefs.getBoolean(KMManager.getLanguageCorrectionPreferenceKey(lgCode), false);
layout = (RelativeLayout)findViewById(R.id.corrections_toggle);
@ -197,71 +208,184 @@ public final class FVKeyboardSettingsActivity extends AppCompatActivity {
overrideCorrectionsToggle(mayPredict);
layout = (RelativeLayout)findViewById(R.id.model_picker);
textView = (TextView) layout.findViewById(R.id.text1);
textView.setText(getString(R.string.model_label));
checkModelLayout = (RelativeLayout)findViewById(R.id.check_model);
textView = checkModelLayout.findViewById(R.id.text1);
textView.setText(getString(R.string.check_model_online));
lexicalModelTextView = layout.findViewById(R.id.text2);
updateActiveLexicalModel();
ImageView imageView = (ImageView) layout.findViewById(R.id.image1);
imageView.setImageResource(R.drawable.ic_arrow_forward);
layout.setEnabled(true);
layout.setOnClickListener(new View.OnClickListener() {
checkModelLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Start ModelPickerActivity
Bundle bundle = new Bundle();
bundle.putString(KMManager.KMKey_LanguageID, lgCode);
bundle.putString(KMManager.KMKey_LanguageName, lgName);
bundle.putString(KMManager.KMKey_CustomHelpLink, customHelpLink);
Intent i = new Intent(context, ModelPickerActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
i.putExtras(bundle);
startActivity(i);
queryModel();
}
});
/**
* This is a placeholder for "Manage dictionary" settings
*
* layout = (RelativeLayout)findViewById(R.id.manage_dictionary);
* textView = (TextView) layout.findViewById(R.id.text1);
* textView.setText(getString(R.string.manage_dictionary));
* imageView = (ImageView) layout.findViewById(R.id.image1);
* imageView.setImageResource(R.drawable.ic_arrow_forward);
*/
// Display model picker list
listView = (ListView)findViewById(R.id.listView);
listView.setFastScrollEnabled(true);
// Initialize the dataset of available lexical models (installed and from the cloud catalog)
listAdapter = new ModelPickerActivity.FilteredLexicalModelAdapter(context, repo, lgCode);
listView.setAdapter(listAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
int selectedIndex = position;
LexicalModel model = ((ModelPickerActivity.FilteredLexicalModelAdapter) listView.getAdapter()).getItem(position);
String packageID = model.getPackageID();
String languageID = model.getLanguageID();
String modelID = model.getLexicalModelID();
String modelName = model.getLexicalModelName();
String langName = model.getLanguageName();
String version = model.getVersion();
boolean immediateRegister = false;
// File check to see if lexical model file already exists locally (may not be currently installed)
File modelCheck = new File(KMManager.getLexicalModelsDir() + packageID + File.separator + modelID + ".model.js");
String modelKey = model.getKey();
boolean modelInstalled = KeyboardPickerActivity.containsLexicalModel(context, modelKey);
if (modelInstalled) {
// Show Model Info
listView.setItemChecked(position, true);
listView.setSelection(position);
// Start intent for selected Predictive Text Model screen
Intent i = new Intent(context, ModelInfoActivity.class);
i.putExtra(KMManager.KMKey_LexicalModel, model);
startActivityForResult(i, 1);
} else if (modelCheck.exists()) {
// Handle scenario where previously installed kmp already exists so
// we only need to add the model to the list of installed models
HashMap<String, String> modelInfo = new HashMap<String, String>();
modelInfo.put(KMManager.KMKey_PackageID, packageID);
modelInfo.put(KMManager.KMKey_LexicalModelID, modelID);
modelInfo.put(KMManager.KMKey_LanguageID, languageID);
modelInfo.put(KMManager.KMKey_LexicalModelName, modelName);
modelInfo.put(KMManager.KMKey_LanguageName, langName);
modelInfo.put(KMManager.KMKey_LexicalModelVersion, version);
// Add help link
modelInfo.put(KMManager.KMKey_CustomHelpLink, "");
boolean result = KMManager.addLexicalModel(context, new HashMap<>(modelInfo));
if (result) {
Toast.makeText(context, getString(R.string.model_install_toast), Toast.LENGTH_SHORT).show();
}
immediateRegister = true;
} else {
// Model isn't installed so prompt to download it
Bundle args = model.buildDownloadBundle();
Intent i = new Intent(getApplicationContext(), KMKeyboardDownloaderActivity.class);
i.putExtras(args);
startActivity(i);
}
// If we had a previously-installed lexical model, we should 'deinstall' it so that only
// one model is actively linked to any given language.
if(!modelInstalled && !immediateRegister) {
// While awkward, we must obtain the preInstalledModelMap before any installations occur.
// We don't want to remove the model we just installed, after all!
HashMap<String, String> preInstalledModelMap = KMManager.getAssociatedLexicalModel(languageID);
if(preInstalledModelMap != null) {
// This might be unnecessary
LexicalModel preInstalled = new LexicalModel(
preInstalledModelMap.get(KMManager.KMKey_PackageID),
preInstalledModelMap.get(KMManager.KMKey_LexicalModelID),
preInstalledModelMap.get(KMManager.KMKey_LexicalModelName),
preInstalledModelMap.get(KMManager.KMKey_LanguageID),
preInstalledModelMap.get(KMManager.KMKey_LanguageName),
preInstalledModelMap.get(KMManager.KMKey_LexicalModelVersion),
preInstalledModelMap.get(KMManager.KMKey_CustomHelpLink),
MapCompat.getOrDefault(preInstalledModelMap, KMManager.KMKey_KMPLink, ""));
String itemKey = preInstalled.getKey();
int modelIndex = KeyboardPickerActivity.getLexicalModelIndex(context, itemKey);
KMManager.deleteLexicalModel(context, modelIndex, true);
}
}
if(immediateRegister) {
// Register associated lexical model if it matches the active keyboard's language code;
// it's safe since we're on the same thread. Needs to be called AFTER deinstalling the old one.
String kbdLgCode = KMManager.getCurrentKeyboardInfo(context).getLanguageID();
if(BCP47.languageEquals(kbdLgCode, languageID)) {
KMManager.registerAssociatedLexicalModel(languageID);
}
}
// Force a display refresh.
notifyDataSetChanged();
}
});
Intent i = getIntent();
listView.setSelectionFromTop(i.getIntExtra("listPosition", 0),
i.getIntExtra("offsetY", 0));
// Rescale listview and hide "Dictionaries" header if no dictionaries installed
updateDictionariesSection();
}
public void updateDictionariesSection() {
if (listAdapter != null && toolbar != null) {
int actionBarHeight = toolbar.getLayoutParams().height;
int numModels = listAdapter.getCount();
listView.getLayoutParams().height = actionBarHeight * (numModels);
TextView label = findViewById(R.id.model_label);
if (label != null) {
if (numModels == 0) {
label.setVisibility(View.GONE);
} else {
label.setVisibility(VISIBLE);
}
}
}
}
private void queryModel() {
if (!KMManager.hasConnection(context)) {
Toast.makeText(context,
context.getString(R.string.cannot_query_associated_model),
Toast.LENGTH_SHORT).show();
return;
}
String _downloadid = CloudLexicalModelMetaDataDownloadCallback.createDownloadId(lgCode);
CloudLexicalModelMetaDataDownloadCallback _callback = new CloudLexicalModelMetaDataDownloadCallback();
Toast.makeText(context,
context.getString(R.string.query_associated_model),
Toast.LENGTH_SHORT).show();
ArrayList<CloudApiTypes.CloudApiParam> aPreparedCloudApiParams = new ArrayList<>();
String url = CloudRepository.prepareLexicalModelQuery(lgCode);
aPreparedCloudApiParams.add(new CloudApiTypes.CloudApiParam(
CloudApiTypes.ApiTarget.KeyboardLexicalModels, url).setType(CloudApiTypes.JSONType.Array));
CloudDownloadMgr.getInstance().executeAsDownload(
context, _downloadid, null, _callback,
aPreparedCloudApiParams.toArray(new CloudApiTypes.CloudApiParam[0]));
}
@Override
public void onResume() {
super.onResume();
updateActiveLexicalModel();
notifyDataSetChanged();
}
/**
* Updates the active lexical model label with the name of the associated lexical model.
* If there's no associated lexical model, the label displays a prompt to check for an available model.
*/
public void updateActiveLexicalModel() {
HashMap<String, String> lexModelMap = KMManager.getAssociatedLexicalModel(lgCode);
if(lexModelMap != null) {
associatedLexicalModel = lexModelMap.get(KMManager.KMKey_LexicalModelName);
} else {
// Prompt to check for available dictionary
associatedLexicalModel = getString(R.string.check_available_model);
public static void notifyDataSetChanged() {
if (listAdapter != null) {
listAdapter.notifyDataSetChanged();
}
lexicalModelTextView.setText(associatedLexicalModel);
lexicalModelTextView.setEnabled(true);
}
public static void setActiveLexicalModelLabel(String lexicalModelLabel) {
if (lexicalModelTextView != null && lexicalModelLabel != null && !lexicalModelLabel.isEmpty()) {
lexicalModelTextView.setText(lexicalModelLabel);
lexicalModelTextView.setEnabled(true);
public static void restartActivity() {
if (context != null) {
// Not using Activity.recreate() because we need to recalculate the items
((Activity)context).finish();
((Activity)context).startActivity(intent);
}
}
@ -295,7 +419,7 @@ public final class FVKeyboardSettingsActivity extends AppCompatActivity {
}
if (correctionsToggle != null) {
correctionsToggle.setEnabled(override);
int visibility = override ? View.VISIBLE : View.INVISIBLE;
int visibility = override ? VISIBLE : INVISIBLE;
correctionsToggle.setVisibility(visibility);
}
}

View file

@ -37,10 +37,6 @@ final class FVRegionListAdapter extends ArrayAdapter<FVShared.FVRegion> {
holder.text1 = convertView.findViewById(R.id.text1);
holder.text2 = convertView.findViewById(R.id.text2);
if (listFont != null) {
holder.text1.setTypeface(listFont, Typeface.BOLD);
holder.text2.setTypeface(listFont, Typeface.NORMAL);
}
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();

View file

@ -2,6 +2,7 @@ package com.firstvoices.keyboards;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@ -18,6 +19,7 @@ import io.sentry.android.core.SentryAndroid;
import com.tavultesoft.kmea.*;
import com.tavultesoft.kmea.data.Keyboard;
import com.tavultesoft.kmea.util.BCP47;
import com.tavultesoft.kmea.util.DownloadFileUtils;
import com.tavultesoft.kmea.KeyboardEventHandler.OnKeyboardDownloadEventListener;
@ -27,7 +29,7 @@ import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity implements OnKeyboardDownloadEventListener {
public static Context context;
public Context context;
FVDownloadResultReceiver resultReceiver;
@ -89,10 +91,6 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardDownloa
webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
/*
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webView.setWebContentsDebuggingEnabled(true);
}*/
webView.setWebViewClient(new WebViewClient() {
@Override
@ -204,30 +202,6 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardDownloa
// ensure onKeyboardDownloadFinished() gets called
}
/*
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
*/
private static final class JSHandler {
final private Context context;
@ -277,31 +251,36 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardDownloa
@Override
public void onLexicalModelInstalled(List<Map<String, String>> lexicalModelsInstalled) {
String langId = (KMManager.getCurrentKeyboardInfo(this) != null) ?
String keyboardLangId = (KMManager.getCurrentKeyboardInfo(this) != null) ?
KMManager.getCurrentKeyboardInfo(this).getLanguageID() :
KMManager.KMDefault_LanguageID;
boolean matchingModel = false;
String lexicalModelName = "";
SharedPreferences prefs = context.getSharedPreferences(context.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
for(int i=0; i<lexicalModelsInstalled.size(); i++) {
HashMap<String, String>lexicalModelInfo = new HashMap<>(lexicalModelsInstalled.get(i));
if(lexicalModelInfo.get(KMManager.KMKey_LanguageID).equals(langId)) {
String lexicalModelLangId = lexicalModelInfo.get(KMManager.KMKey_LanguageID);
if(BCP47.languageEquals(keyboardLangId, lexicalModelLangId)) {
matchingModel = true;
lexicalModelName = lexicalModelInfo.get(KMManager.KMKey_LexicalModelName);
}
KMManager.addLexicalModel(this, lexicalModelInfo);
// Enable predictions and corrections toggles
editor.putBoolean(KMManager.getLanguagePredictionPreferenceKey(lexicalModelLangId), true);
editor.putBoolean(KMManager.getLanguageCorrectionPreferenceKey(lexicalModelLangId), true);
}
editor.commit();
// We're on the main thread, so if the active keyboard's language code matches,
// let's register the associated lexical model.
if(matchingModel) {
KMManager.registerAssociatedLexicalModel(langId);
// Update associated dictionary string if applicable
FVKeyboardSettingsActivity.setActiveLexicalModelLabel(lexicalModelName);
KMManager.registerAssociatedLexicalModel(keyboardLangId);
}
// Launch/refresh FV Keyboard Settings menu
FVKeyboardSettingsActivity.restartActivity();
}
}

View file

@ -1,12 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/list_toolbar" />
<include layout="@layout/list_toolbar" />
<include
android:id="@+id/keyboard_toggle"
@ -24,43 +22,45 @@
android:layout_marginBottom="0dp"
android:orientation="vertical">
<View
android:id="@+id/separator"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="?attr/colorAccent" />
<!-- Enable predictions toggle -->
<include
android:id="@+id/predictions_toggle"
layout="@layout/list_row_layout4"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- Enable corrections toggle -->
<include
android:id="@+id/corrections_toggle"
layout="@layout/list_row_layout4"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/model_label"
android:textColor="@color/firstvoices_red"
android:background="@android:color/transparent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:text="@string/dictionaries"
android:textSize="16sp"
android:textStyle="bold" />
<!-- Model picker -->
<include layout="@layout/list_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<!-- Check for dictionaries online -->
<include
android:id="@+id/model_picker"
layout="@layout/list_row_layout2"
android:id="@+id/check_model"
layout="@layout/list_row_layout1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<!-- Enable corrections toggle -->
<!-- Enable predictions toggle -->
<!-- Model picker -->
<!-- Model dictionary -->
<!-- Currently a placeholder
<include layout="@layout/list_row_layout1"
android:id="@+id/manage_dictionary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/model_picker"/> -->
</RelativeLayout>

View file

@ -22,8 +22,7 @@
android:layout_marginTop="5dp"
android:ellipsize="end"
android:singleLine="true"
android:textSize="16sp"
android:textStyle="bold" />
android:textSize="16sp" />
<TextView
android:id="@+id/text2"

View file

@ -34,9 +34,8 @@
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:textSize="14sp"
android:textStyle="bold" />
android:textSize="14sp" />
</LinearLayout>
<LinearLayout

View file

@ -19,8 +19,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textSize="16sp"
android:textStyle="bold" />
android:textSize="16sp" />
<TextView
android:id="@+id/text2"
@ -28,6 +27,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:textColor="@color/material_grey_600"
android:textSize="14sp" />
</LinearLayout>

View file

@ -4,6 +4,7 @@
<string name="setup">Setup</string>
<string name="regions">Regions</string>
<string name="keyboards">Keyboards</string>
<string name="dictionaries">Dictionaries</string>
<string name="keyboard_settings">%1$s Settings</string>
<string name="enable_keyboard">Enable keyboard</string>
<string name="keyboard_version">Version %1$s</string>