- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在学习一本书中的教程。我知道怎么猜对了吗?好吧,无论如何,我已经到了我们正在制作一个允许用户输入文本并按下按钮的简单应用程序的地步。按下按钮时,输入的文本将全部转换为大写。
我们在应用程序中添加了一个功能,以便在用户按下回车键时(在输入所需文本后)转换文本。 (无需按转换按钮)
我已经运行了我的应用程序并尝试对其进行调试,但没有成功。根据 logcat 所说(或更像是不说)永远不会调用 onKey。
有什么我想念的吗?下面是 Activity 的 java 类和布局。提前致谢。
TipCal.java(不要问我为什么这么命名)
package com.njh.add.tipclaculator;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class TipCal extends Activity implements OnClickListener, OnKeyListener{
private TextView tv = null;
private Button convertButton = null;
private Button quitButton = null;
private EditText et = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tip_cal);
tv = (TextView)findViewById(R.id.my_TextView);
convertButton = (Button)findViewById(R.id.my_Button);
quitButton = (Button)findViewById(R.id.quit);
et = (EditText)findViewById(R.id.my_EditText);
convertButton.setOnClickListener(this);
quitButton.setOnClickListener(this);
et.setOnKeyListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.tip_cal, 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();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onClick(View v) {
Log.d(v.toString(),"In onClick");
if(v == convertButton){
//Take the text from the EditText and make it all CAPS
//Then update the TextView with the CAPS string
String editTextContent = et.getText().toString();
editTextContent = editTextContent.toUpperCase();
tv.setText(editTextContent);
et.setText("");
}else if(v == quitButton){
this.finish();
}
}
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
//When the user press enter after typing in what they want to
//convert the conversion is done. No need to press any other button
Log.d(v.toString(),"In onKey");
if(event.getAction() == KeyEvent.ACTION_DOWN){
if(event.getKeyCode() == KeyEvent.KEYCODE_ENTER){
this.onClick(v); //Not sure this is legal but don't see why I couldn't do this.
}
}
return false;
}
}
这是这个 Activity 的布局 XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:id="@+id/base"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.njh.add.tipclaculator.TipCal" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="My First Android Application"
android:id="@+id/my_TextView" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Touch Me"
android:id="@+id/my_Button" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Quit"
android:id="@+id/quit" />
</LinearLayout>
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="Type something to get turned into CAPS"
android:id="@+id/my_EditText" />
</LinearLayout>
更新
到目前为止,我发现 TextWatcher 确实命中了我的代码。哪个好。现在,当我按下回车键时,我的应用程序崩溃了。
但是!
我会接受的。我认为新问题是您在制作 TextWatcher 时实现的三个功能,您按下的每个键都会调用两次。 (在 keydown 和 keyup 上)。这只是一个猜测。有人确定吗?
更新TextWatcher
没有在每次更改时多次调用其方法。软键盘正在更新自动添加空格或自动更正等功能。当我输入“ll”并且我的键盘将其更新为“lol”时我注意到了这一点,这将导致它更新从“ll”到“lol”再到“lol”的变化。
我将要进行更多挖掘。 如果我得出一个可行的解决方案,我将发布以分享财富。
最佳答案
OnKeyListener “这只对硬件键盘有用”。这是来自 View.OnKeyListener 的直接引用.
@Antrromet 你建议看看这个post ,我做到了。它让我开始了。
然后我遇到了索引越界异常。使用 Android Studio 的帮助很大。
我找到了使用 TextWatcher 调用其他函数的解决方案。下面是我用于修复的 Java 文件。如我所见,我的 XML 中没有任何问题。你我注意到我已经更改了名称和与之相关的东西,比如包裹。这是因为我为此使用了 Android Studio 而不是 Eclipse。由于我在工作中使用 Intellij,而 Android Studio 是由同一个人构建的,因此我发现使用 AS 进行调试等操作要容易得多。
自从我重写后,一些变量名称发生了变化。您仍然应该能够遵循此代码。它的设置与 OP 中的相同。
package com.example.developer.demo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.util.Locale;
//NOTE I now implement TextWatch not OnKeyListener
//the AppCompatActivity was changed because ActionBarActivity is deprecated
//look it up on StackOverflow I'll post the link at the bottom of this answer
public class Demo extends AppCompatActivity implements OnClickListener, TextWatcher {
private TextView textView = null;
private Button convertButton = null;
private Button quitButton = null;
private EditText editText = null;
private int before = 0;
private int on = 0;
private int after = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
textView = (TextView)findViewById(R.id.app_info_tv);
convertButton = (Button)findViewById(R.id.convert_but);
quitButton = (Button)findViewById(R.id.quit_but);
editText = (EditText)findViewById(R.id.main_et);
convertButton.setOnClickListener(this);
quitButton.setOnClickListener(this);
editText.addTextChangedListener(this); //use this instead of OnKeyListener
Log.d("Demo","in onCreate");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//the same as in OP
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
//the same as in OP
}
@Override
public void onClick(View v) {
Log.d("Demo","in onClick");
//See what View was clicked
if(v == convertButton) {
//turn the inputted sting into all Caps
String textToConvert = editText.getText().toString();
textToConvert = textToConvert.toUpperCase(Locale.getDefault());
textView.setText(textToConvert);
editText.setText("");
}else if(v == quitButton){
this.finish();
}
}
//Instead on onKey with OnKeyListener you get three functions with
//TextWatcher. Like their names suggest one is called before changes,
//one during, and one after.
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
Log.d("****","***************");
Log.d("Demo","in BTC: "+String.valueOf(before++));
Log.d("Demo","\ts: "+s.toString());
Log.d("Demo","\tstart: "+String.valueOf(start));
Log.d("Demo","\tcount: "+String.valueOf(count));
Log.d("Demo","\tafter: "+String.valueOf(after));
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.d("Demo","in OTC: "+String.valueOf(on++));
Log.d("Demo","\ts: "+s.toString());
Log.d("Demo","\tstart: "+String.valueOf(start));
Log.d("Demo","\tcount: "+String.valueOf(count));
Log.d("Demo","\tbefore: "+String.valueOf(before));
}
@Override
public void afterTextChanged(Editable s) {
Log.d("Demo","in ATC: "+after++);
Log.d("Demo","\ts: "+s.toString());
String textToConvert = s.toString();
if(textToConvert.length() > 0 && Character.compare(textToConvert.charAt(textToConvert.length()-1),'\n') == 0){
onClick(convertButton);
}
}
}
如果有人对调试日志感到好奇,请告诉我,我会发布它。它帮助我了解了我是如何获得异常(exception)的。
那么最重要的是……我做了什么?
在我的应用程序中,我想将 onClick
函数“绑定(bind)”到软键盘上的“Enter”按钮以及布局中的转换 Button
对象。
我意识到我的 onClick
函数干扰了 TextWatcher
所在的 EditText
对象。所以我必须找出一种方法来判断 onClick
何时被 TextWatcher
或 OnClickListener
调用。
“Enter”按钮将在字符串末尾放置一个“\n”(换行符)。所以我会检查一下。如果它在那里,我会调用 onClick
。
然后 onClick
会将 EditText
中的文本设置为空字符串 ""。更改文本会导致 TextWatcher
再次通过它的三个方法。当它得到 afterTextChange
时,它会索引一个空的 String
和 KABOOM。 (因为我试图捕获长度为 - 1 的最后一个字符)
String empty = "";
int length = empty.length(); // 0
empty.charAt(length - 1); //if empty had three thing in it the length - 1 would be 2 (the index of the last character in the String)
//BUT it doesn't so empty[-1] is bad
^^^没有布埃诺^^^
所以我添加了一个字符串长度大于 0 的检查。现在我可以相信我不会索引到一个空字符串。
我已经对我的应用程序进行了一些测试,以任何顺序调用 onClick
。一切正常。
我在代码中谈到为什么我使用 AppCompactActivity 的链接是 here .它几乎使它成为 ActionBarActivity,即使该类现在已被弃用。
关于java - OnKeyListener.onKey 未被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32028908/
我收到一条错误消息“ View 类型中的方法 setOnKeyListener(View.OnKeyListener) 不适用于参数 (new OnKeyListener(){})” 我怎样才能克服这
为什么我不能用参数 View 实现 OnKeyListener,例如 on example其中参数是(View v, int keyCode, KeyEvent event) 我被迫使用参数(Dial
堆栈的人们大家好...... 我在让 onKeyListener 工作时遇到一些问题。基本上,正如您在下面看到的,我想启动按钮单击以及 EditText 框上的 KeyListener 的 Inten
请问为什么 OnKey() 方法中的代码没有执行?请注意,我正试图通过点击 android 键盘上的“搜索”按钮来触发此操作。 主要代码如下: package com.onkeyexample1; i
有导致警报对话框的 MainActivity,当打开的警报对话框不起作用时更改音量,放置 OnKeyListener,现在当您按下音量按钮时处理两次,MainActivity 中的监听器处理单击正确,
我正在做一件事情,我需要在按下 Fragment 时听取电源和音量按钮的声音。我使用音量按钮成功地做到了这一点,但是,当按下电源按钮时,屏幕关闭并且我的代码没有执行。 view.setOnKeyLis
我正在尝试在关键事件上实现动画。相同的代码在 OnClickListener 上运行良好,但在 OnKeyListener 上没有任何反应。甚至在 Logcat 上也没有错误消息。 请帮我解决这个问题
我目前正在为 Android 制作一款游戏,我希望能够在其中使用相机按钮进行拍摄(或者我不介意使用不同的硬件按钮,只是点击屏幕会很垃圾)。 在我看来我有: public class GameFrame
我已经创建了最简单的 Android 项目,以便使用 OnKeyListener 进行测试,以查看在 EditText 小部件中键入的内容。问题是 onKey 方法只触发返回键 - 没有其他。根据我下
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: public boolean onKey() called twice? Display.setOnKeyL
我想在编辑文本中输入文本后应用一些数字验证。我尝试使用 TextWatcher 来做,但它只适用于高版本,而不是低版本。 因此我想使用 OnKeyListener 事件。但这也不起作用。 start_
我错过了什么?我觉得不得不发布这个真的很愚蠢,但也许其他人会看到我正在犯的(可能很明显的)错误。 import android.app.Activity; import android.os.Bund
我不明白为什么这段代码不起作用。仅检测退格键和返回键。监听器不会为任何其他键触发。我的设备是 Nexus One。 我试图覆盖 Activity 的 OnKeyDown 方法,结果更糟。唯一检测到的按
package woot.wat.wen; import android.app.Activity; import android.os.Bundle; import android.text.Lay
当在 Button 上按下 Enter 键时,我想要某种功能。当我覆盖 onKey() 时,我编写了要为 KEY_ENTER 执行的代码。这很好用。 setupButton.setOnKeyListe
我正在学习一本书中的教程。我知道怎么猜对了吗?好吧,无论如何,我已经到了我们正在制作一个允许用户输入文本并按下按钮的简单应用程序的地步。按下按钮时,输入的文本将全部转换为大写。 我们在应用程序中添加了
我知道this/similar question之前有人问过,但给出的解决方案对我不起作用,所以我再次询问。我尝试了该答案中给出的解决方案,但我的 OnKeyListener 仍然从未在某些设备上被调
在 fragment 上,我有以下 OnKeyListener。如果当前显示,我用它来隐藏该 fragment 内部的 View 。如果未显示,我不会使用按键,而 Android 会。 get
我正在使用 onKeyListener 来获取 onKey 事件。它适用于普通键盘。但它不适用于软键盘。我只能获取数字而不是字母的 onKey 事件。有什么办法可以解决这个问题吗?任何形式的帮助将不胜
我定义了一个 EditText 字段,我希望在用户编辑该字段时收到通知。所以我想:简单 - 我添加了一个 OnKeyListener ,所以我做到了。但即使文本字段被编辑(甚至显示输入/修改的文本)我
我是一名优秀的程序员,十分优秀!