I have an array of EditText and I want to disable the standard keyboard Android that appears every time I click on them.
these are the parts code I am using:
InputMethodManager imm = (InputMethodManager)getSystemService(
Context.INPUT_METHOD_SERVICE);
for (i=0;i<dim*dim;i++){
imm.hideSoftInputFromWindow(value[i].getWindowToken(), 0);
value[i].setOnTouchListener(this);
value[i].setOnClickListener(this);
value[i].setOnFocusChangeListener(this);
}
EDIT:
I created a new class, with these lines of code:
import android.content.Context;
import android.util.AttributeSet;
import android.widget.EditText;
public class KeyboardControlEditText extends EditText {
private boolean mShowKeyboard = false;
public void setShowKeyboard(boolean value) {
mShowKeyboard = value;
}
// This constructor has to be overriden
public KeyboardControlEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
// Now tell the VM whether or not we are a text editor
#Override
public boolean onCheckIsTextEditor() {
return mShowKeyboard;
}
}
and in my main class in OnCreate:
for (i=0;i<dim*dim;i++){
((KeyboardControlEditText) value[i]).setShowKeyboard(false);
value[i].setOnTouchListener(this);
value[i].setOnClickListener(this);
}
You need to create your own EditText class for this. Then, override the default onCheckIsTextEditor and return false.
public class NoKeyboardEditText extends EditText {
// This constructor has to be overriden
public NoKeyboardEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
// Now tell the VM that we are not a text editor
#Override
public boolean onCheckIsTextEditor() {
return false;
}
}
Make sure you substitute in the correct name for the new EditText. For example, if your package is com.example.widget, you'd want to use <com.example.widget.NoKeyboardEditText ... />.
If you need this to be dynamic, you can get even fancier:
public class KeyboardControlEditText extends EditText {
private boolean mShowKeyboard = false;
public void setShowKeyboard(boolean value) {
mShowKeyboard = value;
}
// This constructor has to be overriden
public KeyboardControlEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
// Now tell the VM whether or not we are a text editor
#Override
public boolean onCheckIsTextEditor() {
return mShowKeyboard;
}
}
That way, you can call ((KeyboardControlEditText) myEditText).setShowKeyboard(false); to change it at runtime.
Related
I have an EditText what I populate via
editText.setText(content)
The reason this is an EditText and not a TextView is because I also want to paste stuff (later when user is operating the app) in it or manually type in it, if applicable.
But I have to
reset a flag if editText set via setText()
and nothing if pasted by user
How can I distinguish how a EditText was populated? addTextChangedListener()'s callbacks are triggered in each case.
You can set Listener Class:
public interface GoEditTextListener {
void onUpdate();
}
Custom Edittext
public class GoEditText extends EditText
{
ArrayList<GoEditTextListener> listeners;
public GoEditText(Context context)
{
super(context);
listeners = new ArrayList<>();
}
public GoEditText(Context context, AttributeSet attrs)
{
super(context, attrs);
listeners = new ArrayList<>();
}
public GoEditText(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
listeners = new ArrayList<>();
}
public void addListener(GoEditTextListener listener) {
try {
listeners.add(listener);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
/**
* Here you can catch paste, copy and cut events
*/
#Override
public boolean onTextContextMenuItem(int id) {
boolean consumed = super.onTextContextMenuItem(id);
switch (id){
case android.R.id.cut:
onTextCut();
break;
case android.R.id.paste:
onTextPaste();
break;
case android.R.id.copy:
onTextCopy();
}
return consumed;
}
public void onTextCut(){
}
public void onTextCopy(){
}
/**
* adding listener for Paste for example
*/
public void onTextPaste(){
for (GoEditTextListener listener : listeners) {
listener.onUpdate();
}
}
}
xml
<com.yourname.project.GoEditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/editText1"/>
Code
private GoEditText editText1;
editText1 = (GoEditText) findViewById(R.id.editText1);
editText1.addListener(new GoEditTextListener() {
#Override
public void onUpdate() {
//here do what you want when text Pasted
}
});
Simply extend EditText, include the flag, and override setText:
public class MyEditText extends EditText {
boolean fromSetText;
#Override
public void setText(String text) {
super.setText(text);
fromSetText = true;
}
}
You can define your own setters/getters and constructors based on your requirements.
I'm trying to create a custom EditText that provides an onLostFocus event. However, I can't get my head around how I tell the custom class what method to run when the focus is lost.
This is my extended EditText:
public class smtyEditText extends EditText {
public smtyEditText(Context context) {
super(context);
}
public smtyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public smtyEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setFocusChangeListener() {
this.setOnFocusChangeListener(new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
// notify the relevant activity, probably passing it some parameters like what instance of smtyEditText triggered the event.
}
}
});
}
}
The intention of the setFocusChangeListener function was that from any given activity I could do something like:
public class AddMeal extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_meal);
EditText etMealName = (EditText) findViewById(R.id.txtmealName);
etMealName.setFocusChangeListener(this.fieldLostFocus)
}
// then
public void fieldLostFocus(eventSource) {
// run some kind of validation on the field text.
}
}
Clearly I'm "code paraphrasing" here. I also get that Interfaces, and some other "EventNotifier" class might be needed. These are the resources I've tried to decipher so far:
http://www.javaworld.com/article/2077462/learn-java/java-tip-10--implement-callback-routines-in-java.html
How to Define Callbacks in Android?
http://www.justinmccandless.com/blog/Setting+Up+a+Callback+Function+in+Android
But for whatever reason I can't crystallize what is needed. Do you have any suggestions on how I can achieve this?
You don't need the inheritance... it only adds an unnecessary layer of indirection. Just add the focus change handler in your activity.
public class AddMeal extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_meal);
EditText etMealName = (EditText) findViewById(R.id.txtmealName);
etMealName.setFocusChangeListener(new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
// call method to handle loss of focus
}
}
});
}
// then
public void fieldLostFocus(eventSource) {
// run some kind of validation on the field text.
}
}
i would like to create a class, which extends Button and implement a method, which is alwasy called, when the Button is clicked. But i still want it's OnClickListener to be called.
My Idea is to save the OnClickListener into a private member when the constructor or setOnClickListener is called and then set the OnClickListener to my own OnClickListener. This one would then call my method and the saved OnClickListener.
But i don't see how i can get the OnClickListenr, i only see, how to set it.
Is there a way to acces it?
Or do you have a better idea? (it doesn't matter wheter my method is called before or after the OnClickListener)
I guess you could do this:
public class OnceClickedTwiceRunButton extends Button{
public OnceClickedTwiceRunButton(Context context) {
super(context);
}
public OnceClickedTwiceRunButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public OnceClickedTwiceRunButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private OnClickListener extraClickMethod;
#Override
public void setOnClickListener(OnClickListener newListener)
{
super.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
DefaultClickMethod(v);
if(extraClickMethod != null)
{
extraClickMethod.onClick(v);
}
}
});
extraClickMethod = newListener;
}
private void DefaultClickMethod(View v)
{
//TODO
}
}
I have read the many answers on this question but my question is asking where I place the code. I am looking to validate that a number is greater than 100 in the EditTextPreference. This is the code I use to populate the preferences:
public class SettingsFrag extends PreferenceFragment{
//Override onCreate so that the code will run when the activity is started.
#Override
public void onCreate(Bundle savedInstanceState){
//Call to the super class.
super.onCreate(savedInstanceState);
//add the preferences from the XML file.
addPreferencesFromResource(R.xml.preferences);
}
}
Is it in here I add the validation or would I have to create another class?
preferences.xml:
<EditTextPreference
android:key="geofence_range"
android:title="Geofence Size"
android:defaultValue="500"
android:inputType="number"
android:summary="Geofence Size Around User Location"
android:dialogTitle="Enter Size (meters):" />
Add setOnPreferenceChangeListener for EditTextPreference after addPreferencesFromResource to validate data input for User:
EditTextPreference edit_Pref = (EditTextPreference)
getPreferenceScreen().findPreference("geofence_range");
edit_Pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// put validation here..
if(<validation pass>){
return true;
}else{
return false;
}
}
});
Note: This answer is based on the deprecated android.preference.EditTextPreference.
Huh. Another one of those things that should be so darned easy in Android but isn't. Other answers just silently prevent writing back the result to preferences, which seems a bit shoddy. (Showing toast is less shoddy, but is still shoddy).
You'll need a custom preference to do this. Customize onValidate to suit your needs.
package com.two_play.extensions;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.util.AttributeSet;
import android.view.View;
import android.widget.EditText;
public class ValidatingEditTextPreference extends EditTextPreference {
public ValidatingEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public ValidatingEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public ValidatingEditTextPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ValidatingEditTextPreference(Context context) {
super(context);
}
#Override
protected void showDialog(Bundle state) {
super.showDialog(state);
AlertDialog dlg = (AlertDialog)getDialog();
View positiveButton = dlg.getButton(DialogInterface.BUTTON_POSITIVE);
getEditText().setError(null);
positiveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onPositiveButtonClicked(v);
}
});
}
private void onPositiveButtonClicked(View v) {
String errorMessage = onValidate(getEditText().getText().toString());
if (errorMessage == null)
{
getEditText().setError(null);
onClick(getDialog(),DialogInterface.BUTTON_POSITIVE);
getDialog().dismiss();
} else {
getEditText().setError(errorMessage);
return; // return WITHOUT dismissing the dialog.
}
}
/***
* Called to validate contents of the edit text.
*
* Return null to indicate success, or return a validation error message to display on the edit text.
*
* #param text The text to validate.
* #return An error message, or null if the value passes validation.
*/
public String onValidate(String text)
{
try {
Double.parseDouble(text);
return null;
} catch (Exception e)
{
return getContext().getString(R.string.error_invalid_number);
}
}
}
It seems more elegant to me to disable the "OK" button instead of allowing the user to press it but then discard their input and show the error. getDialog seems to be gone in androidx.preference, but this seems to work for me instead:
final EditTextPreference p = new EditTextPreference(context);
p.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
#Override
public void onBindEditText(#NonNull final EditText editText) {
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable editable) {
String validationError;
try {
// ... insert your validation logic here, throw on failure ...
validationError = null; // All OK!
} catch (Exception e) {
validationError = e.getMessage();
}
editText.setError(validationError);
editText.getRootView().findViewById(android.R.id.button1)
.setEnabled(validationError == null);
}
});
}
});
Here is my Kotlin implementation for androidx.preference.* based on Vladimir Panteleev's answer:
class CustomPreference : EditTextPreference {
// ...
private fun applyValidation() = setOnBindEditTextListener { editText ->
editText.doAfterTextChanged { editable ->
requireNotNull(editable)
// TODO Add validation magic here.
editText.error = if (criteria.isValid()) {
null // Everything is fine.
} else {
if (criteria.getErrorMessage() == null) "Unknown validation error"
else resources.getString(criteria.getErrorMessage())
}
}
}
}
The handy doAfterTextChanged extension is part of the androidx.core:core-ktx library.
i am new to android .
i was working with android canvas and i wonder how does SurfaceView class functions work when their function defination is empty in the android source code .Here is the android surface view class source code
package android.view;
import com.android.layoutlib.bridge.MockView;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
public class SurfaceView extends MockView {
public SurfaceView(Context context) {
this(context, null);
}
public SurfaceView(Context context, AttributeSet attrs) {
this(context, attrs , 0);
}
public SurfaceView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public SurfaceHolder getHolder() {
return mSurfaceHolder;
}
private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
#Override
public boolean isCreating() {
return false;
}
#Override
public void addCallback(Callback callback) {
}
#Override
public void removeCallback(Callback callback) {
}
#Override
public void setFixedSize(int width, int height) {
}
#Override
public void setSizeFromLayout() {
}
#Override
public void setFormat(int format) {
}
#Override
public void setType(int type) {
}
#Override
public void setKeepScreenOn(boolean screenOn) {
}
#Override
public Canvas lockCanvas() {
return null;
}
#Override
public Canvas lockCanvas(Rect dirty) {
return null;
}
#Override
public void unlockCanvasAndPost(Canvas canvas) {
}
#Override
public Surface getSurface() {
return null;
}
#Override
public Rect getSurfaceFrame() {
return null;
}
};
}
so how does this work when we write
canvas c = holder.lockCanvas(null);
or
holder.unlockCanvasAndPost(c);
when we have nothing in source code to process.. i mean where is the code to get the work done. if help me find it..
The full SurfaceView source code is in the AOSP code on Github:
https://github.com/android/platform_frameworks_base/blob/master/core/java/android/view/SurfaceView.java
It appears that you're looking at the source for the stub library.
For the SDK, a library is generated that has entries for all public classes, fields, and methods, but no implementation. You build your app against that, rather than the actual library, so that your build fails if you try to use classes, fields, or methods that aren't part of the official Android API.
If you look in the actual source for SurfaceView you will see methods like setWindowType() (line 415) that have #hide in the javadoc. Even though the method is "public" in the Java-language sense, it's not part of the published API, and is therefore excluded from the stub library.