add keyboard chooser dialog

This commit is contained in:
Yuriy Liskov
2018-03-20 15:48:41 +02:00
parent a7598c27eb
commit 1c65d017fb
13 changed files with 314 additions and 10 deletions

View File

@@ -36,6 +36,8 @@ import android.widget.RelativeLayout.LayoutParams;
import com.google.android.leanback.ime.voice.RecognizerView;
import com.google.android.leanback.ime.voice.SpeechLevelSource;
import com.google.leanback.ime.LeanbackImeService;
import com.liskovsoft.inputchooser.ChooseKeyboardDialog;
import com.liskovsoft.inputchooser.SettingsActivity;
import com.liskovsoft.keyboardaddons.KeyboardManager;
import com.liskovsoft.leankeykeyboard.R;
@@ -868,6 +870,12 @@ public class LeanbackKeyboardContainer {
switchToNextKeyboard();
setTouchState(LeanbackKeyboardContainer.TOUCH_STATE_NO_TOUCH);
return true;
} else if (keyCode == LeanbackKeyboardView.KEYCODE_LANG_TOGGLE) {
//Intent intent = new Intent(mContext, SettingsActivity.class);
//intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//mContext.startActivity(intent);
new ChooseKeyboardDialog(mContext, mMainKeyboardView).run();
return true;
} else {
if (mCurrKeyInfo.type == KeyFocus.TYPE_MAIN) {
mMainKeyboardView.onKeyLongPress();

View File

@@ -0,0 +1,131 @@
package com.liskovsoft.inputchooser;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.res.TypedArray;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.CheckedTextView;
import com.liskovsoft.keyboardaddons.KeyboardInfo;
import com.liskovsoft.keyboardaddons.reslangfactory.ResKeyboardInfo;
import com.liskovsoft.leankeykeyboard.R;
import java.util.ArrayList;
import java.util.List;
public class ChooseKeyboardDialog implements OnClickListener {
private final View mInputView;
private final Context mContext;
private final List<KeyboardInfo> mInfos;
private AlertDialog alertDialog;
private ArrayList<CheckedTextView> mLangViews;
/**
* Main constructor. Use it in most of the cases.
* @param ctx context
*/
public ChooseKeyboardDialog(Context ctx) {
this(ctx, null);
}
/**
* Special constructor. Useful when others didn't work. E.g. when running dialog within input method.
* @param ctx context
* @param inputView view to get token
*/
public ChooseKeyboardDialog(Context ctx, View inputView) {
mContext = ctx;
mInfos = ResKeyboardInfo.getAllKeyboardInfos(ctx);
mInputView = inputView;
}
public void run() {
showDialog();
}
@TargetApi(17)
private void showDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
alertDialog = builder
.setTitle(R.string.language_dialog_title)
.setView(buildView(builder.getContext()))
.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialogInterface) {
ResKeyboardInfo.updateAllKeyboardInfos(mContext, mInfos);
}
})
.create();
if (mInputView != null) {
initDialog(); // prepare to run from IME
}
alertDialog.show();
}
private void initDialog() {
Window window = alertDialog.getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
lp.token = mInputView.getWindowToken();
lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
window.setAttributes(lp);
window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
}
@SuppressLint("InflateParams")
private View buildView(Context context) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.lang_selection_dialog, null);
ViewGroup root = view.findViewById(R.id.root);
TypedArray attributeArray = context.getTheme().obtainStyledAttributes(new int[]{android.R.attr.selectableItemBackground});
int selectableItemBackgroundResourceId = attributeArray.getResourceId(0, 0);
attributeArray.recycle();
mLangViews = new ArrayList<>();
for (KeyboardInfo info : mInfos) {
CheckedTextView langView = (CheckedTextView) inflater.inflate(android.R.layout.simple_list_item_multiple_choice, root, false);
langView.setBackgroundResource(selectableItemBackgroundResourceId);
langView.setText(info.getLangName());
langView.setFocusable(true);
langView.setTag(info); // our TAG
langView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mContext.getResources().getDimension(R.dimen.text_size_dp));
langView.setOnClickListener(this);
mLangViews.add(langView);
root.addView(langView);
}
updateViews();
return view;
}
private void updateViews() {
for (CheckedTextView view : mLangViews) {
KeyboardInfo kbd = (KeyboardInfo) view.getTag();
if (kbd.isEnabled()) {
view.setChecked(true);
}
}
}
@Override
public void onClick(View view) {
KeyboardInfo kbd = (KeyboardInfo) view.getTag();
// todo
CheckedTextView checkedView = (CheckedTextView) view;
boolean checked = checkedView.isChecked();
kbd.setEnabled(!checked);
checkedView.setChecked(!checked);
}
}

View File

@@ -72,6 +72,7 @@ public class SettingsActivity extends Activity
protected void onCreate(final Bundle bundle) {
super.onCreate(bundle);
// new ChooseKeyboardDialog(this).run();
this.launchApp();
}
}

View File

@@ -6,4 +6,5 @@ import java.util.List;
public interface KeyboardFactory {
List<? extends KeyboardBuilder> getAllAvailableKeyboards(Context context);
boolean needUpdate();
}

View File

@@ -0,0 +1,10 @@
package com.liskovsoft.keyboardaddons;
public interface KeyboardInfo {
boolean isEnabled();
String getLangCode();
String getLangName();
void setLangName(String langName);
void setLangCode(String langCode);
void setEnabled(boolean enabled);
}

View File

@@ -2,7 +2,6 @@ package com.liskovsoft.keyboardaddons;
import android.content.Context;
import android.inputmethodservice.Keyboard;
import com.liskovsoft.keyboardaddons.apklangfactory.keyboards.ApkLangKeyboardFactory;
import com.liskovsoft.keyboardaddons.reslangfactory.ResKeyboardFactory;
import java.util.ArrayList;
@@ -11,9 +10,9 @@ import java.util.List;
public class KeyboardManager {
private final Keyboard mEnglishKeyboard;
private final Context mContext;
private final List<? extends KeyboardBuilder> mKeyboardBuilders;
private final List<Keyboard> mAllKeyboards;
private final KeyboardFactory mKeyboardFactory;
private List<? extends KeyboardBuilder> mKeyboardBuilders;
private List<Keyboard> mAllKeyboards;
private KeyboardFactory mKeyboardFactory;
private int mKeyboardIndex = 0;
public KeyboardManager(Context ctx, int keyboardResId) {
@@ -23,8 +22,11 @@ public class KeyboardManager {
public KeyboardManager(Context ctx, Keyboard englishKeyboard) {
mContext = ctx;
mEnglishKeyboard = englishKeyboard;
mKeyboardFactory = new ResKeyboardFactory(ctx);
init();
}
private void init() {
mKeyboardFactory = new ResKeyboardFactory(mContext);
mKeyboardBuilders = mKeyboardFactory.getAllAvailableKeyboards(mContext);
mAllKeyboards = buildAllKeyboards();
}
@@ -45,13 +47,18 @@ public class KeyboardManager {
* @return keyboard
*/
public Keyboard getNextKeyboard() {
if (mKeyboardFactory.needUpdate()) {
init();
}
mKeyboardIndex = mKeyboardIndex < mAllKeyboards.size() ? mKeyboardIndex : 0;
Keyboard kbd = mAllKeyboards.get(mKeyboardIndex);
if (kbd == null) {
throw new IllegalStateException(String.format("Keyboard %s not initialized", mKeyboardIndex));
}
++mKeyboardIndex;
mKeyboardIndex = mKeyboardIndex < mAllKeyboards.size() ? mKeyboardIndex : 0;
return kbd;
}

View File

@@ -57,6 +57,12 @@ public class ApkLangKeyboardFactory extends AddOnsFactory<ApkKeyboardAddOnAndBui
return getAllAddOns(context);
}
@Override
public boolean needUpdate() {
// TODO: implement need update
return false;
}
public List<ApkKeyboardAddOnAndBuilder> getEnabledKeyboards(Context askContext) {
final List<ApkKeyboardAddOnAndBuilder> allAddOns = getAllAddOns(askContext);
Logger.i(TAG, "Creating enabled addons list. I have a total of " + allAddOns.size() + " addons");

View File

@@ -6,6 +6,7 @@ import android.inputmethodservice.Keyboard;
import android.support.annotation.Nullable;
import com.liskovsoft.keyboardaddons.KeyboardBuilder;
import com.liskovsoft.keyboardaddons.KeyboardFactory;
import com.liskovsoft.keyboardaddons.KeyboardInfo;
import com.liskovsoft.leankeykeyboard.R;
import java.util.ArrayList;
@@ -21,18 +22,28 @@ public class ResKeyboardFactory implements KeyboardFactory {
@Override
public List<? extends KeyboardBuilder> getAllAvailableKeyboards(Context context) {
List<KeyboardBuilder> result = new ArrayList<>();
String[] langs = mContext.getResources().getStringArray(R.array.additional_languages);
List<KeyboardInfo> infos = ResKeyboardInfo.getAllKeyboardInfos(context);
final Resources resources = mContext.getResources();
for (final String langPair : langs) {
final String langCode = langPair.split("\\|")[1];
for (final KeyboardInfo info : infos) {
if (!info.isEnabled()) {
continue;
}
result.add(new KeyboardBuilder() {
@Nullable
@Override
public Keyboard createKeyboard() {
return new Keyboard(mContext, resources.getIdentifier("qwerty_" + langCode, "xml", mContext.getPackageName()));
return new Keyboard(mContext, resources.getIdentifier("qwerty_" + info.getLangCode(), "xml", mContext.getPackageName()));
}
});
}
return result;
}
@Override
public boolean needUpdate() {
return ResKeyboardInfo.needUpdate();
}
}

View File

@@ -0,0 +1,91 @@
package com.liskovsoft.keyboardaddons.reslangfactory;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import com.liskovsoft.keyboardaddons.KeyboardInfo;
import com.liskovsoft.leankeykeyboard.R;
import java.util.ArrayList;
import java.util.List;
public class ResKeyboardInfo implements KeyboardInfo {
private static boolean sNeedUpdate;
private boolean mEnabled;
private String mLangCode;
private String mLangName;
public static List<KeyboardInfo> getAllKeyboardInfos(Context ctx) {
List<KeyboardInfo> result = new ArrayList<>();
String[] langs = ctx.getResources().getStringArray(R.array.additional_languages);
for (final String langPair : langs) {
String[] pairs = langPair.split("\\|");
final String langName = pairs[0];
final String langCode = pairs[1];
KeyboardInfo info = new ResKeyboardInfo();
info.setLangName(langName);
info.setLangCode(langCode);
// sync with prefs
syncWithPrefs(ctx, info);
result.add(info);
}
sNeedUpdate = false;
return result;
}
public static void updateAllKeyboardInfos(Context ctx, List<KeyboardInfo> infos) {
for (KeyboardInfo info : infos) {
// update prefs
updatePrefs(ctx, info);
}
sNeedUpdate = true;
}
private static void syncWithPrefs(Context ctx, KeyboardInfo info) {
final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ctx);
final boolean kbdEnabled = sharedPreferences.getBoolean(info.getLangCode(), false);
info.setEnabled(kbdEnabled);
}
private static void updatePrefs(Context ctx, KeyboardInfo info) {
final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ctx);
final SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean(info.getLangCode(), info.isEnabled());
editor.apply();
}
public static boolean needUpdate() {
return sNeedUpdate;
}
@Override
public boolean isEnabled() {
return mEnabled;
}
@Override
public String getLangCode() {
return mLangCode;
}
@Override
public String getLangName() {
return mLangName;
}
@Override
public void setLangName(String langName) {
mLangName = langName;
}
@Override
public void setLangCode(String langCode) {
mLangCode = langCode;
}
@Override
public void setEnabled(boolean enabled) {
mEnabled = enabled;
}
}

View File

@@ -0,0 +1,11 @@
package com.liskovsoft.keyboardaddons.reslangfactory;
import com.liskovsoft.keyboardaddons.KeyboardInfo;
import java.util.List;
public class ResKeyboardManager {
public List<KeyboardInfo> getAllKeyboardInfos() {
return null;
}
}