fix(android): UI changes

* Move button to below title bar
* Update title strings
* Use back button for "Cancel" action
* Use index for PackageProcesor utilities
This commit is contained in:
Darcy Wong 2020-08-13 10:52:02 +07:00
parent 69e0454009
commit a368e1abc1
7 changed files with 87 additions and 118 deletions

View file

@ -12,7 +12,6 @@ import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
@ -20,7 +19,6 @@ import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.TextView;
import android.util.Log;
import android.widget.Toast;
import com.tavultesoft.kmea.KMManager;
@ -47,6 +45,9 @@ public class PackageActivity extends AppCompatActivity {
private File tempPackagePath;
private static ArrayList<KeyboardEventHandler.OnKeyboardDownloadEventListener> kbDownloadEventListeners = null;
private PackageProcessor kmpProcessor;
private TextView packageActivityTitle;
private String pkgName;
private String pkgVersion;
@SuppressLint({"SetJavaScriptEnabled", "InflateParams"})
@Override
@ -90,32 +91,33 @@ public class PackageActivity extends AppCompatActivity {
return;
}
pkgName = kmpProcessor.getPackageName(pkgInfo);
pkgVersion = kmpProcessor.getPackageVersion(pkgInfo);
final int languageCount = kmpProcessor.getLanguageCount(pkgInfo, PackageProcessor.PP_KEYBOARDS_KEY, 0);
// Silent installation (skip displaying welcome.htm and user confirmation)
if (silentInstall) {
installPackage(context, pkgTarget, pkgId, languageID, true);
return;
}
String pkgVersion = kmpProcessor.getPackageVersion(pkgInfo);
String pkgName = kmpProcessor.getPackageName(pkgInfo);
final int languageCount = kmpProcessor.getKeyboardLanguageCount(pkgInfo);
toolbar = (Toolbar) findViewById(R.id.titlebar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(null);
getSupportActionBar().setDisplayUseLogoEnabled(false);
getSupportActionBar().setDisplayShowHomeEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayShowCustomEnabled(true);
getSupportActionBar().setBackgroundDrawable(MainActivity.getActionBarDrawable(this));
TextView packageActivityTitle = new TextView(this);
packageActivityTitle = new TextView(this);
packageActivityTitle.setWidth((int) getResources().getDimension(R.dimen.package_label_width));
packageActivityTitle.setTextSize(getResources().getDimension(R.dimen.titlebar_label_textsize));
packageActivityTitle.setGravity(Gravity.CENTER);
String titleStr = pkgTarget.equals(PackageProcessor.PP_TARGET_KEYBOARDS) ?
String.format(getString(R.string.install_keyboard_package), pkgVersion) :
String.format(getString(R.string.install_keyboard_package), pkgName, pkgVersion) :
String.format(getString(R.string.install_predictive_text_package), pkgVersion);
packageActivityTitle.setText(titleStr);
getSupportActionBar().setCustomView(packageActivityTitle);
@ -190,7 +192,7 @@ public class PackageActivity extends AppCompatActivity {
}
/**
* Initialize buttons of package installer.
* Initialize button of package installer.
* If keyboard package languageCount > 1, use nextButton instead of installButton
* @param context the context
* @param pkgId the keyman package id
@ -198,10 +200,9 @@ public class PackageActivity extends AppCompatActivity {
* @param pkgTarget String: PackageProcessor.PP_TARGET_KEYBOARDS or PP_TARGET_LEXICAL_MODELS
* @param languageCount int number of languages for the first keyboard in a keyboard package
*/
private void initializeButtons(final Context context, final String pkgId, final String languageID,
final String pkgTarget, final int languageCount) {
private void initializeButtons(final Context context, final String pkgId,
final String languageID, final String pkgTarget, final int languageCount) {
final Button installButton = (Button) findViewById(R.id.installButton);
final Button cancelButton = (Button) findViewById(R.id.cancelButton);
final Button nextButton = (Button) findViewById(R.id.nextButton);
final Button finishButton = (Button) findViewById(R.id.finishButton);
@ -233,7 +234,6 @@ public class PackageActivity extends AppCompatActivity {
cleanup();
}
};
cancelButton.setOnClickListener(_cleanup_action);
finishButton.setOnClickListener(_cleanup_action);
updateButtonState(true, pkgTarget, languageCount);
@ -243,7 +243,7 @@ public class PackageActivity extends AppCompatActivity {
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Use the result of SelectLanguageActivity and install the package
if (requestCode == 2) {
if (resultCode == 2 && data != null) {
String pkgTarget = data.getStringExtra("pkgTarget");
String pkgId = data.getStringExtra("packageID");
String languageID = data.getStringExtra("languageID");
@ -259,6 +259,12 @@ public class PackageActivity extends AppCompatActivity {
}
}
@Override
public boolean onSupportNavigateUp() {
super.onBackPressed();
return true;
}
private void cleanup() {
try {
if (kmpFile != null && kmpFile.exists()) {
@ -293,10 +299,10 @@ public class PackageActivity extends AppCompatActivity {
}
/**
* switch button visibility for package installer.
* before installation show Install/Next and Cancel
* after installation show OK button
* Switch button visibility for package installer so only one button is visible.
* Before installation: show Install or Next
* If keyboard package languageCount > 1, use nextButton instead of installButton
* AFter installation: show OK button
* @param anIsStartInstaller if true - before installation, false - after installation
* @param pkgTarget String: PackageProcessor.PP_TARGET_KEYBOARDS or PP_TARGET_LEXICAL_MODELS
* @param languageCount int number of languages for a keyboard
@ -305,7 +311,6 @@ public class PackageActivity extends AppCompatActivity {
{
final Button installButton = (Button) findViewById(R.id.installButton);
final Button nextButton = (Button) findViewById(R.id.nextButton);
final Button cancelButton = (Button) findViewById(R.id.cancelButton);
final Button closeButton = (Button) findViewById(R.id.finishButton);
if(anIsStartInstaller)
{
@ -316,14 +321,12 @@ public class PackageActivity extends AppCompatActivity {
installButton.setVisibility(View.VISIBLE);
nextButton.setVisibility(View.GONE);
}
cancelButton.setVisibility(View.VISIBLE);
closeButton.setVisibility(View.GONE);
}
else
{
installButton.setVisibility(View.GONE);
nextButton.setVisibility(View.GONE);
cancelButton.setVisibility(View.GONE);
closeButton.setVisibility(View.VISIBLE);
}
findViewById(R.id.buttonBar).requestLayout();
@ -336,30 +339,39 @@ public class PackageActivity extends AppCompatActivity {
}
/**
* show welcome page from installed keyboard.
* Show welcome page from installed keyboard.
* @param theInstalledPackages the installed keyboards or lexical models
* @param pkgTarget String: PackageProcessor.PP_TARGET_KEYBOARDS or PP_TARGET_LEXICAL_MODELS
* @return true if a welcomepage is available
* @return true if a welcome page is available
*/
private boolean loadWelcomePage(List<Map<String, String>> theInstalledPackages, String pkgTarget)
{
boolean _found=false;
for(Map<String,String> _keyboard:theInstalledPackages) {
String _customlink = _keyboard.get(KMManager.KMKey_CustomHelpLink);
if (_customlink != null) {
webView.loadUrl("file:///" + _customlink);
_found=true;
break;
}
}
if(!_found)
return false;
updateButtonState(false, pkgTarget);
// Update titlebar: Don't display back button and update text
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setDisplayShowHomeEnabled(false);
String titleStr =
String.format(getString(R.string.welcome_package), pkgName, pkgVersion);
packageActivityTitle.setText(titleStr);
return true;
for(Map<String,String> _keyboard:theInstalledPackages) {
String _customlink = _keyboard.get(KMManager.KMKey_CustomHelpLink);
if (_customlink != null) {
webView.loadUrl("file:///" + _customlink);
_found=true;
break;
}
}
if(!_found) {
return false;
}
updateButtonState(false, pkgTarget);
return true;
}
/**
* Installs the keyboard or lexical model package, and then notifies the corresponding listeners
* @param context Context The activity context
@ -368,7 +380,8 @@ public class PackageActivity extends AppCompatActivity {
* @param languageID String The optional language ID
* @param anSilentInstall boolean If true, don't display readme.htm/welcome.htm content during installation
*/
private void installPackage(Context context, String pkgTarget, String pkgId, String languageID, boolean anSilentInstall) {
private void installPackage(Context context, String pkgTarget, String pkgId,
String languageID, boolean anSilentInstall) {
try {
if (pkgTarget.equals(PackageProcessor.PP_TARGET_KEYBOARDS)) {
// processKMP will remove currently installed package and install

View file

@ -4,6 +4,7 @@
package com.tavultesoft.kmapro;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
@ -77,7 +78,7 @@ public final class SelectLanguageActivity extends AppCompatActivity {
final String packageID = bundle.getString("packageID");
JSONObject pkgInfo = kmpProcessor.loadPackageInfo(packagePath);
Keyboard keyboard = bundle.containsKey("keyboard") ? (Keyboard)bundle.getSerializable("keyboard") :
kmpProcessor.getFirstKeyboard(pkgInfo, packageID);
kmpProcessor.getKeyboard(pkgInfo, packageID, 0);
final String keyboardID = keyboard.getKeyboardID();
final String keyboardName = keyboard.getKeyboardName();
String title_install = String.format(getString(R.string.title_select_language_for_package), keyboardName);
@ -149,6 +150,7 @@ public final class SelectLanguageActivity extends AppCompatActivity {
@Override
public boolean onSupportNavigateUp() {
super.onBackPressed();
setResult(Activity.RESULT_CANCELED);
return true;
}
}

View file

@ -8,27 +8,24 @@
tools:context=".PackageActivity" >
<include layout="@layout/titlebar" />
<WebView
android:id="@+id/packageWebView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/titlebar"
android:layout_above="@+id/buttonBar"/>
<LinearLayout
android:id="@+id/buttonBar"
style="?android:attr/buttonBarStyle"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/titlebar"
android:orientation="horizontal">
<!-- Spacer to pad buttons to the right -->
<!-- Spacer to pad button to the right -->
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<!-- PackageActivity will manage so only one of these button is displayed -->
<Button
android:id="@+id/finishButton"
style="@style/Widget.AppCompat.Button.Borderless.Colored"
@ -41,19 +38,6 @@
android:elevation="1dp"
android:singleLine="true"/>
<Button
android:id="@+id/cancelButton"
style="@style/Widget.AppCompat.Button.Borderless.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="15dp"
android:text="@string/label_cancel"
android:textColor="@color/keyman_blue"
android:elevation="1dp"
android:singleLine="true"/>
<!-- PackageActivity will manager installButton/nextButton so only one is displayed -->
<Button
android:id="@+id/installButton"
style="@style/Widget.AppCompat.Button.Borderless.Colored"
@ -81,4 +65,11 @@
</LinearLayout>
<WebView
android:id="@+id/packageWebView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/buttonBar"
/>
</RelativeLayout>

View file

@ -7,8 +7,8 @@
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="label_width">200dp</dimen>
<dimen name="titlebar_label_textsize">4sp</dimen>
<dimen name="package_label_width">250dp</dimen>
<dimen name="titlebar_label_textsize">6sp</dimen>
<dimen name="package_label_width">350dp</dimen>
<dimen name="keyman_bar_height">8dp</dimen>
<dimen name="checkbox_margin">8dp</dimen>
<dimen name="checkbox_margin_left">15dp</dimen>

View file

@ -154,7 +154,10 @@
<string name="failed_to_extract" comment="Notification that keyboard package failed to unzip">Failed to extract</string>
<!-- Context: KMP Package strings -->
<string name="install_keyboard_package" comment="Title to install keyboard package">Install Keyboard Package %1$s</string>
<string name="install_keyboard_package" comment="Title to install keyboard package (name and version)">Install %1$s %2$s</string>
<!-- Context: KMP Package welcome.htm title -->
<string name="welcome_package" comment="Title to welcome.htm page (name and version)">Welcome to %1$s %2$s</string>
<!-- Context: KMP Package strings -->
<string name="install_predictive_text_package" comment="Title to install dictionary package">Install Predictive Text Package %1$s</string>

View file

@ -194,19 +194,21 @@ public class PackageProcessor {
}
/**
* Get the language and keyboard information for the first keyboard in a keyboard package.
* Get the language and keyboard information for the keyboard in a keyboard package at a specified index.
* Use placeholders for other fields like help links, and font info.
* @param json kmp.json as a JSON object
* @param packageID String of the keyboard package ID
* @param index int of the keyboard entry
* @return Keyboard info. Null if no keyboard found
*/
public static Keyboard getFirstKeyboard(JSONObject json, String packageID) {
public static Keyboard getKeyboard(JSONObject json, String packageID, int index) {
try {
if (!json.has(PP_KEYBOARDS_KEY)) {
return null;
}
JSONObject keyboardObj = json.getJSONArray(PP_KEYBOARDS_KEY).getJSONObject(0);
JSONObject keyboardObj = json.getJSONArray(PP_KEYBOARDS_KEY).getJSONObject(index);
JSONArray languages = keyboardObj.getJSONArray(PP_LANGUAGES_KEY);
// Just get first language
JSONObject languageObj = languages.getJSONObject(0);
return new Keyboard(
packageID,
@ -228,53 +230,25 @@ public class PackageProcessor {
}
/**
* Parse a kmp.json JSON object and return the first keyboard ID. If no keyboard found, returns empty string
* @param json kmp.json as a JSON object
* @return String of the first keyboard ID
*/
public static String getFirstKeyboardID(JSONObject json) {
try {
if (!json.has(PP_KEYBOARDS_KEY)) {
return "";
}
return json.getJSONArray(PP_KEYBOARDS_KEY).getJSONObject(0).getString("id");
} catch (JSONException e) {
KMLog.LogException(TAG, "", e);
return "";
}
}
/**
* Pase a kmp.json JSON object and return the first keyboard name. If no keyboard found, returns empty string
* @param json kmp.json as a JSON object
* @return String of the first keyboard name
*/
public static String getFirstKeyboardName(JSONObject json) {
try {
if (!json.has(PP_KEYBOARDS_KEY)) {
return "";
}
return json.getJSONArray(PP_KEYBOARDS_KEY).getJSONObject(0).getString("name");
} catch (JSONException e) {
KMLog.LogException(TAG, "", e);
return "";
}
}
/**
* Parse a kmp.json JSON object and return the language count for the first keyboard
* Parse a kmp.json JSON object and return the language count for the specified resource and index
* @param json kmp.json as a JSON object
* @param key PP_KEYBOARDS_KEY or PP_LEXICAL_MODELS_KEY
* @param index int Item number the resource array
* @return int of number of languages. 0 if not found
*/
public static int getKeyboardLanguageCount(JSONObject json) {
public static int getLanguageCount(JSONObject json, String key, int index) {
int count = 0;
try {
if (!json.has(PP_KEYBOARDS_KEY)) {
if ( (key.equals(PP_KEYBOARDS_KEY) && !json.has(PP_KEYBOARDS_KEY)) ||
(key.equals(PP_LEXICAL_MODELS_KEY) && !json.has(PP_LEXICAL_MODELS_KEY)) ){
KMLog.LogError(TAG, "kmp.json doesn't contain " + key);
return count;
}
JSONArray keyboards = json.getJSONArray(PP_KEYBOARDS_KEY);
JSONArray languages = keyboards.getJSONObject(0).getJSONArray(PP_LANGUAGES_KEY);
JSONArray resources = json.getJSONArray(key);
JSONArray languages = resources.getJSONObject(index).getJSONArray(PP_LANGUAGES_KEY);
count = languages.length();
} catch (NullPointerException e) {
KMLog.LogException(TAG, "getLanguageCount with null JSONObject", e);
} catch (JSONException e) {
KMLog.LogException(TAG, "", e);
}
@ -571,7 +545,7 @@ public class PackageProcessor {
// temporary path for kmp.json so don't use KeyboardController to get the base keyboard.
if (i==0) {
// Create a "baseKeyboard" for the language picker menu. Don't need full keyboard info...
Keyboard baseKeyboard = getFirstKeyboard(infoJSON, packageID);
Keyboard baseKeyboard = getKeyboard(infoJSON, packageID, 0);
return getKeyboards(keyboard, baseKeyboard, excludeInstalledLanguages);
}
}

View file

@ -227,20 +227,6 @@ public class PackageProcessorTest {
Assert.assertEquals("1.4", version);
}
@Test
public void test_getFirstKeyboardID() {
JSONObject json = PP.loadPackageInfo(tempPkg);
Assert.assertEquals(TEST_GFF_KBD_ID, PackageProcessor.getFirstKeyboardID(json));
}
@Test
public void test_getFirstKeyboardName() {
JSONObject json = PP.loadPackageInfo(tempPkg);
Assert.assertEquals(TEST_GFF_KBD_NAME, PackageProcessor.getFirstKeyboardName(json));
}
@Test
public void test_keyboardVersion() {
JSONObject json = PP.loadPackageInfo(tempPkg);