【问题标题】:Apply theme dynamically for Android Keyboard为 Android 键盘动态应用主题
【发布时间】:2015-05-22 06:10:57
【问题描述】:

大家好,在 StackOverflow,

我在编写软键盘时遇到了问题:

我想要实现的是软键盘动态加载为夜间打字优化的主题/样式和在阳光下打字的主题/样式。样式已经定义好了,我已经可以通过更改 input.xml 中的样式轻松切换它们。

import ... /*Not quite relevant (yet)*/

public class LatinKeyboardView extends KeyboardView {

public LatinKeyboardView(Context context, AttributeSet attrs) {
    this(context, attrs, loadColor());
}

public LatinKeyboardView(Context context, AttributeSet attrs, int defStyle)                 {
    super(context, attrs, defStyle);

}

public static int loadColor() {

    String dbg = android.os.Debug.isDebuggerConnected() ? "Y" : "N";

    android.util.Log.d("loadColor", "Debugger connected: " +  dbg);

    android.os.Debug.waitForDebugger();

    int temp = 0;
    int id = 0;

    if (temp == 1)
    {
        id = R.style.KeyStyle_Day;
    }
    else
    {
        id =  R.style.KeyStyle_Night;
    }

    android.util.Log.d("loadColor", Integer.toString(id));
    return id;
}

当我将调用从第一个构造函数重定向到第二个构造函数时(如 Hacker's Keyboard 源代码中所示),软键盘成功加载 loadColor() 中的样式 ID,但在此之后,内部发生了一个异常,我即使有堆栈跟踪,也无法追溯:

03-19 08:32:48.313  18630-18630/com.alphanerd.eztype.keyboard E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.alphanerd.eztype.keyboard, PID: 18630
    android.view.InflateException: Binary XML file line #21: Error inflating class com.alphanerd.eztype.keyboard.LatinKeyboardView
            at android.view.LayoutInflater.createView(LayoutInflater.java:626)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:702)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:470)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:354)
            at com.alphanerd.eztype.keyboard.EZTypeKeyboard.onCreateInputView(EZTypeKeyboard.java:125)
            at android.inputmethodservice.InputMethodService.updateInputViewShown(InputMethodService.java:1594)
            at android.inputmethodservice.InputMethodService.showWindowInner(InputMethodService.java:2220)
            at android.inputmethodservice.InputMethodService.showWindow(InputMethodService.java:2179)
            at android.inputmethodservice.InputMethodService$InputMethodImpl.showSoftInput(InputMethodService.java:712)
            at android.inputmethodservice.IInputMethodWrapper.executeMessage(IInputMethodWrapper.java:214)
            at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:40)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:157)
            at android.app.ActivityThread.main(ActivityThread.java:5335)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.reflect.InvocationTargetException
            at java.lang.reflect.Constructor.constructNative(Native Method)
            at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
            at android.view.LayoutInflater.createView(LayoutInflater.java:600)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:702)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:470)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:354)
            at com.alphanerd.eztype.keyboard.EZTypeKeyboard.onCreateInputView(EZTypeKeyboard.java:125)
            at android.inputmethodservice.InputMethodService.updateInputViewShown(InputMethodService.java:1594)
            at android.inputmethodservice.InputMethodService.showWindowInner(InputMethodService.java:2220)
            at android.inputmethodservice.InputMethodService.showWindow(InputMethodService.java:2179)
            at android.inputmethodservice.InputMethodService$InputMethodImpl.showSoftInput(InputMethodService.java:712)
            at android.inputmethodservice.IInputMethodWrapper.executeMessage(IInputMethodWrapper.java:214)
            at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:40)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:157)
            at android.app.ActivityThread.main(ActivityThread.java:5335)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException
            at android.inputmethodservice.KeyboardView.<init>(KeyboardView.java:370)
            at com.alphanerd.eztype.keyboard.LatinKeyboardView.<init>(LatinKeyboardView.java:53)
            at java.lang.reflect.Constructor.constructNative(Native Method)
            at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
            at android.view.LayoutInflater.createView(LayoutInflater.java:600)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:702)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:470)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:354)
            at com.alphanerd.eztype.keyboard.EZTypeKeyboard.onCreateInputView(EZTypeKeyboard.java:125)
            at android.inputmethodservice.InputMethodService.updateInputViewShown(InputMethodService.java:1594)
            at android.inputmethodservice.InputMethodService.showWindowInner(InputMethodService.java:2220)
            at android.inputmethodservice.InputMethodService.showWindow(InputMethodService.java:2179)
            at android.inputmethodservice.InputMethodService$InputMethodImpl.showSoftInput(InputMethodService.java:712)
            at android.inputmethodservice.IInputMethodWrapper.executeMessage(IInputMethodWrapper.java:214)
            at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:40)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:157)
            at android.app.ActivityThread.main(ActivityThread.java:5335)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
            at dalvik.system.NativeStart.main(Native Method)

我希望你能帮助我。动态加载颜色的代码目前和 int temp 一样动态; ,但稍后我将实现从 sharedpreferences 加载颜色的逻辑(键盘实际上是为了(光学)与我公司正在开发的另一个应用程序集成)

提前感谢您的帮助:)

【问题讨论】:

    标签: java android keyboard styles ime


    【解决方案1】:

    我找到了一个解决方案,我认为一旦找到它就非常简单:我没有修改任何构造函数等,而是编辑了覆盖的 onCreateInputView:

    @Override
    public View onCreateInputView() {
        int schema = loadColor();
    
        //Default code
    
        //mInputView = (LatinKeyboardView) getLayoutInflater().inflate(
        //      R.layout.input, null);
    
        mInputView = (LatinKeyboardView) getLayoutInflater().inflate(
                schema, null);
    
        mInputView.setOnKeyboardActionListener(this);
        mInputView.setKeyboard(mQwertyKeyboard);
        return mInputView;
    }
    
    public static int loadColor() {
    
        String dbg = android.os.Debug.isDebuggerConnected() ? "Y" : "N";
    
        android.util.Log.d("loadColor", "Debugger attached: " +  dbg);
    
        //android.os.Debug.waitForDebugger(); //Comment this out before releasing the keyboard
    
        int temp = 1;
        int id = 0;
    
        if (temp == 1)
        {
            id = R.layout.input_day;
        }
        else
        {
            id =  R.layout.input;
        }
    
        android.util.Log.d("loadColor", Integer.toString(id));
        return id;
    }
    

    通常,LayoutInflater 会按照 google 的意图加载默认输入布局。我可以推荐定义多个输入布局,每个布局都有自己的风格。如果您自己的自定义键盘应该支持用户制作的主题,只需创建一个输入布局并在其中引用一个样式,该样式指的是主题图像。将所有加载的已加载主题图像放在可主题化输入 xml 可访问的特殊文件夹中。

    最后一个提示:您可以通过放置 android.os.Debug.waitForDebugger(); 来调试软键盘。在代码中。键盘(或任何其他应用程序)将等待调试器附加。请记住在发布您的应用程序之前删除每个 waitForDebugger() 调用,否则应用程序将在您忘记删除此行的任何地方停止运行。我希望,我可以帮助任何阅读本文的人。

    谢谢你,祝你有美好的一天:)

    【讨论】:

      猜你喜欢
      • 2021-12-17
      • 1970-01-01
      • 1970-01-01
      • 2013-08-13
      • 1970-01-01
      • 2020-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多